HASH 1679885aaf93
DATE 2025-07-28
SUBJECT nix: add simulation hash to output metadata
FILES 7 CHANGED HASH 1679885aaf93
DATE 2025-07-28
SUBJECT nix: add simulation hash to output
metadata
FILES 7 CHANGED ┌─ .gitignore ────────────────────────────────────────────────────────────── [ COPY ] ─┐
│ diff --git a/.gitignore b/.gitignore │
│ new file mode 100644 │
│ index 0000000..6bbbb49 │
│ --- /dev/null │
│ +++ b/.gitignore │
│ @@ -0,0 +1 @@ │
│ +.ook/* │
└────────────────────────────────────────────────────────────────────────────────────┘ ┌─ .gitignore ──────────────────────── [ COPY ] ─┐
│ diff --git a/.gitignore b/.gitignore │
│ new file mode 100644 │
│ index 0000000..6bbbb49 │
│ --- /dev/null │
│ +++ b/.gitignore │
│ @@ -0,0 +1 @@ │
│ +.ook/* │
└──────────────────────────────────────────────┘ ┌─ README.md ─────────────────────────────────────────────────────────────── [ COPY ] ─┐
│ diff --git a/README.md b/README.md │
│ index 9f02355..94ed90d 100644 │
│ --- a/README.md │
│ +++ b/README.md │
│ @@ -3,10 +3,10 @@ │
│ Powered by [wowsims](https://github.com/wowsims/mop) and │
│ [nix](https://nixos.org/guides/how-nix-works/). │
│ │
│ -## The how and why │
│ +## About │
│ │
│ -The wowsimcli tool consumes simulation inputs as RaidSimRequest in the protojson │
│ -format. These input files can be exported from the │
│ +The wowsimcli tool consumes simulation inputs as RaidSimRequests in the │
│ +protojson format. These input files can be exported from the │
│ [WowSims Web UI](https://wowsims.com). The core of this project is a workflow │
│ that automates simulation at scale. We use nix to programmatically compose the │
│ required protojson input files. A script then orchestrates the entire process: │
│ @@ -16,8 +16,8 @@ required protojson input files. A script then orchestrates the e │
│ ntire process: │
│ files for every specialisation. │
│ 2. **Execute Simulations**: The script invokes wowsimcli for each generated │
│ file, running the simulation and producing a raw JSON output. │
│ -3. **Aggregate Data**: The script collects the output from all the individual │
│ - runs and aggregates the data into a single, clean JSON file. │
│ +3. **Aggregate Data**: A script collects the output from all the individual runs │
│ + and aggregates the data into a single, clean JSON file. │
│ │
│ This approach allows us to easily generate thousands of simulation combinations │
│ while also leveraging the powerful caching and parallelization features of the │
└────────────────────────────────────────────────────────────────────────────────────┘ ┌─ README.md ───────────────────────── [ COPY ] ─┐
│ diff --git a/README.md b/README.md │
│ index 9f02355..94ed90d 100644 │
│ --- a/README.md │
│ +++ b/README.md │
│ @@ -3,10 +3,10 @@ │
│ Powered by [wowsims](https://github.com/wow │
│ sims/mop) and │
│ [nix](https://nixos.org/guides/how-nix-work │
│ s/). │
│ │
│ -## The how and why │
│ +## About │
│ │
│ -The wowsimcli tool consumes simulation inpu │
│ ts as RaidSimRequest in the protojson │
│ -format. These input files can be exported f │
│ rom the │
│ +The wowsimcli tool consumes simulation inpu │
│ ts as RaidSimRequests in the │
│ +protojson format. These input files can be │
│ exported from the │
│ [WowSims Web UI](https://wowsims.com). The │
│ core of this project is a workflow │
│ that automates simulation at scale. We use │
│ nix to programmatically compose the │
│ required protojson input files. A script th │
│ en orchestrates the entire process: │
│ @@ -16,8 +16,8 @@ required protojson input f │
│ iles. A script then orchestrates the entire │
│ process: │
│ files for every specialisation. │
│ 2. **Execute Simulations**: The script invo │
│ kes wowsimcli for each generated │
│ file, running the simulation and produci │
│ ng a raw JSON output. │
│ -3. **Aggregate Data**: The script collects │
│ the output from all the individual │
│ - runs and aggregates the data into a sing │
│ le, clean JSON file. │
│ +3. **Aggregate Data**: A script collects th │
│ e output from all the individual runs │
│ + and aggregates the data into a single, c │
│ lean JSON file. │
│ │
│ This approach allows us to easily generate │
│ thousands of simulation combinations │
│ while also leveraging the powerful caching │
│ and parallelization features of the │
└──────────────────────────────────────────────┘ ┌─ flake.lock ────────────────────────────────────────────────────────────── [ COPY ] ─┐
│ diff --git a/flake.lock b/flake.lock │
│ index 6f26eeb..d15d620 100644 │
│ --- a/flake.lock │
│ +++ b/flake.lock │
│ @@ -54,7 +54,8 @@ │
│ "flake-parts": "flake-parts", │
│ "nixpkgs": "nixpkgs", │
│ "systems": "systems", │
│ - "wowsims": "wowsims" │
│ + "wowsims": "wowsims", │
│ + "wowsims-upstream": "wowsims-upstream" │
│ } │
│ }, │
│ "systems": { │
│ @@ -85,11 +86,11 @@ │
│ ] │
│ }, │
│ "locked": { │
│ - "lastModified": 1753671630, │
│ - "narHash": "sha256-9OpwCEsKtpxJRh4yHzAWhn5VT/V4SrG5msd3Bpy3laU=", │
│ + "lastModified": 1753685245, │
│ + "narHash": "sha256-nFSuXwbWYevQlZc/P9qRGWT1JfiYbbuOIxx08PtS1Ug=", │
│ "owner": "ooks-io", │
│ "repo": "mop", │
│ - "rev": "8daa9465df31c88738cc677cb5147eeb4f85e217", │
│ + "rev": "6156bf245b8a1663badb5c1663372ada3f8757c2", │
│ "type": "github" │
│ }, │
│ "original": { │
│ @@ -98,6 +99,22 @@ │
│ "repo": "mop", │
│ "type": "github" │
│ } │
│ + }, │
│ + "wowsims-upstream": { │
│ + "flake": false, │
│ + "locked": { │
│ + "lastModified": 1753683048, │
│ + "narHash": "sha256-nIeQRXq++k0nvTo11s948s5C5Ur/Hrh7aR8ENK+P6d8=", │
│ + "owner": "wowsims", │
│ + "repo": "mop", │
│ + "rev": "06153aa432c961a62ca8255eed5eb1ee1e7114ca", │
│ + "type": "github" │
│ + }, │
│ + "original": { │
│ + "owner": "wowsims", │
│ + "repo": "mop", │
│ + "type": "github" │
│ + } │
│ } │
│ }, │
│ "root": "root", │
└────────────────────────────────────────────────────────────────────────────────────┘ ┌─ flake.lock ──────────────────────── [ COPY ] ─┐
│ diff --git a/flake.lock b/flake.lock │
│ index 6f26eeb..d15d620 100644 │
│ --- a/flake.lock │
│ +++ b/flake.lock │
│ @@ -54,7 +54,8 @@ │
│ "flake-parts": "flake-parts", │
│ "nixpkgs": "nixpkgs", │
│ "systems": "systems", │
│ - "wowsims": "wowsims" │
│ + "wowsims": "wowsims", │
│ + "wowsims-upstream": "wowsims-upstre │
│ am" │
│ } │
│ }, │
│ "systems": { │
│ @@ -85,11 +86,11 @@ │
│ ] │
│ }, │
│ "locked": { │
│ - "lastModified": 1753671630, │
│ - "narHash": "sha256-9OpwCEsKtpxJRh4y │
│ HzAWhn5VT/V4SrG5msd3Bpy3laU=", │
│ + "lastModified": 1753685245, │
│ + "narHash": "sha256-nFSuXwbWYevQlZc/ │
│ P9qRGWT1JfiYbbuOIxx08PtS1Ug=", │
│ "owner": "ooks-io", │
│ "repo": "mop", │
│ - "rev": "8daa9465df31c88738cc677cb51 │
│ 47eeb4f85e217", │
│ + "rev": "6156bf245b8a1663badb5c16633 │
│ 72ada3f8757c2", │
│ "type": "github" │
│ }, │
│ "original": { │
│ @@ -98,6 +99,22 @@ │
│ "repo": "mop", │
│ "type": "github" │
│ } │
│ + }, │
│ + "wowsims-upstream": { │
│ + "flake": false, │
│ + "locked": { │
│ + "lastModified": 1753683048, │
│ + "narHash": "sha256-nIeQRXq++k0nvTo1 │
│ 1s948s5C5Ur/Hrh7aR8ENK+P6d8=", │
│ + "owner": "wowsims", │
│ + "repo": "mop", │
│ + "rev": "06153aa432c961a62ca8255eed5 │
│ eb1ee1e7114ca", │
│ + "type": "github" │
│ + }, │
│ + "original": { │
│ + "owner": "wowsims", │
│ + "repo": "mop", │
│ + "type": "github" │
│ + } │
│ } │
│ }, │
│ "root": "root", │
└──────────────────────────────────────────────┘ ┌─ flake.nix ─────────────────────────────────────────────────────────────── [ COPY ] ─┐
│ diff --git a/flake.nix b/flake.nix │
│ index fe61d9e..28cdaec 100644 │
│ --- a/flake.nix │
│ +++ b/flake.nix │
│ @@ -13,6 +13,10 @@ │
│ systems.follows = "systems"; │
│ }; │
│ }; │
│ + wowsims-upstream = { │
│ + url = "github:wowsims/mop"; │
│ + flake = false; │
│ + }; │
│ }; │
│ │
│ outputs = inputs @ { │
└────────────────────────────────────────────────────────────────────────────────────┘ ┌─ flake.nix ───────────────────────── [ COPY ] ─┐
│ diff --git a/flake.nix b/flake.nix │
│ index fe61d9e..28cdaec 100644 │
│ --- a/flake.nix │
│ +++ b/flake.nix │
│ @@ -13,6 +13,10 @@ │
│ systems.follows = "systems"; │
│ }; │
│ }; │
│ + wowsims-upstream = { │
│ + url = "github:wowsims/mop"; │
│ + flake = false; │
│ + }; │
│ }; │
│ │
│ outputs = inputs @ { │
└──────────────────────────────────────────────┘ ┌─ nix/apps/simulation/mkMassSim.nix ─────────────────────────────────────── [ COPY ] ─┐
│ diff --git a/nix/apps/simulation/mkMassSim.nix b/nix/apps/simulation/mkMassSim.nix │
│ index 50448c3..57ed483 100644 │
│ --- a/nix/apps/simulation/mkMassSim.nix │
│ +++ b/nix/apps/simulation/mkMassSim.nix │
│ @@ -95,6 +95,7 @@ │
│ targetCount ? "single", │
│ duration ? "long", │
│ template ? "singleTarget", │
│ + wowsimsCommit ? inputs.wowsims-upstream.shortRev, │
│ }: let │
│ raceConfigs = getRaceConfigs classes class spec template phase encounterType; │
│ │
│ @@ -243,6 +244,7 @@ │
│ --arg encounterDuration "${toString encounter.duration}" \ │
│ --arg encounterVariation "${toString encounter.durationVariation}" \ │
│ --arg targetCount "${toString (lib.length encounter.targets)}" \ │
│ + --arg wowsimsCommit "${wowsimsCommit}" \ │
│ --argjson raidBuffs '${builtins.toJSON buffs.full}' \ │
│ '{ │
│ metadata: { │
│ @@ -254,6 +256,7 @@ │
│ encounterDuration: ($encounterDuration | tonumber), │
│ encounterVariation: ($encounterVariation | tonumber), │
│ targetCount: ($targetCount | tonumber), │
│ + wowsimsCommit: $wowsimsCommit, │
│ raidBuffs: $raidBuffs │
│ }, │
│ results: . │
│ @@ -332,6 +335,7 @@ │
│ targetCount ? "single", │
│ duration ? "long", │
│ template ? "singleTarget", │
│ + wowsimsCommit ? inputs.wowsims-upstream.shortRev, │
│ }: let │
│ # get the list of specs based on the specs parameter │
│ specConfigs = │
│ @@ -492,6 +496,7 @@ │
│ --arg encounterDuration "${toString encounter.duration}" \ │
│ --arg encounterVariation "${toString encounter.durationVariation}" \ │
│ --arg targetCount "${toString (lib.length encounter.targets)}" \ │
│ + --arg wowsimsCommit "${wowsimsCommit}" \ │
│ --argjson raidBuffs '${builtins.toJSON buffs.full}' \ │
│ '{ │
│ metadata: { │
│ @@ -502,6 +507,7 @@ │
│ encounterDuration: ($encounterDuration | tonumber), │
│ encounterVariation: ($encounterVariation | tonumber), │
│ targetCount: ($targetCount | tonumber), │
│ + wowsimsCommit: $wowsimsCommit, │
│ raidBuffs: $raidBuffs │
│ }, │
│ results: . │
└────────────────────────────────────────────────────────────────────────────────────┘ ┌─ ...apps/simulation/mkMassSim.nix ── [ COPY ] ─┐
│ diff --git a/nix/apps/simulation/mkMassSim.n │
│ ix b/nix/apps/simulation/mkMassSim.nix │
│ index 50448c3..57ed483 100644 │
│ --- a/nix/apps/simulation/mkMassSim.nix │
│ +++ b/nix/apps/simulation/mkMassSim.nix │
│ @@ -95,6 +95,7 @@ │
│ targetCount ? "single", │
│ duration ? "long", │
│ template ? "singleTarget", │
│ + wowsimsCommit ? inputs.wowsims-upstream │
│ .shortRev, │
│ }: let │
│ raceConfigs = getRaceConfigs classes cl │
│ ass spec template phase encounterType; │
│ │
│ @@ -243,6 +244,7 @@ │
│ --arg encounterDuration "${toStri │
│ ng encounter.duration}" \ │
│ --arg encounterVariation "${toStr │
│ ing encounter.durationVariation}" \ │
│ --arg targetCount "${toString (li │
│ b.length encounter.targets)}" \ │
│ + --arg wowsimsCommit "${wowsimsCom │
│ mit}" \ │
│ --argjson raidBuffs '${builtins.t │
│ oJSON buffs.full}' \ │
│ '{ │
│ metadata: { │
│ @@ -254,6 +256,7 @@ │
│ encounterDuration: ($encounte │
│ rDuration | tonumber), │
│ encounterVariation: ($encount │
│ erVariation | tonumber), │
│ targetCount: ($targetCount | │
│ tonumber), │
│ + wowsimsCommit: $wowsimsCommit │
│ , │
│ raidBuffs: $raidBuffs │
│ }, │
│ results: . │
│ @@ -332,6 +335,7 @@ │
│ targetCount ? "single", │
│ duration ? "long", │
│ template ? "singleTarget", │
│ + wowsimsCommit ? inputs.wowsims-upstream │
│ .shortRev, │
│ }: let │
│ # get the list of specs based on the sp │
│ ecs parameter │
│ specConfigs = │
│ @@ -492,6 +496,7 @@ │
│ --arg encounterDuration "${toStri │
│ ng encounter.duration}" \ │
│ --arg encounterVariation "${toStr │
│ ing encounter.durationVariation}" \ │
│ --arg targetCount "${toString (li │
│ b.length encounter.targets)}" \ │
│ + --arg wowsimsCommit "${wowsimsCom │
│ mit}" \ │
│ --argjson raidBuffs '${builtins.t │
│ oJSON buffs.full}' \ │
│ '{ │
│ metadata: { │
│ @@ -502,6 +507,7 @@ │
│ encounterDuration: ($encounte │
│ rDuration | tonumber), │
│ encounterVariation: ($encount │
│ erVariation | tonumber), │
│ targetCount: ($targetCount | │
│ tonumber), │
│ + wowsimsCommit: $wowsimsCommit │
│ , │
│ raidBuffs: $raidBuffs │
│ }, │
│ results: . │
└──────────────────────────────────────────────┘ ┌─ nix/pkgs/testRaid.nix ─────────────────────────────────────────────────── [ COPY ] ─┐
│ diff --git a/nix/pkgs/testRaid.nix b/nix/pkgs/testRaid.nix │
│ index a5d30e3..000de8b 100644 │
│ --- a/nix/pkgs/testRaid.nix │
│ +++ b/nix/pkgs/testRaid.nix │
│ @@ -12,17 +12,17 @@ │
│ # quickly sim a single spec for testing purposes │
│ inherit (lib.sim.simulation) mkSim; │
│ │
│ - class = "warlock"; │
│ - spec = "demonology"; │
│ + class = "rogue"; │
│ + spec = "subtlety"; │
│ encounterType = "raid"; │
│ │
│ raid = mkSim { │
│ - requestId = "raidSimAsync-f2cf5e22118a43c7"; │
│ - iterations = 10000; │
│ - player = classes.${class}.${spec}.template.troll.p1.${encounterType}.multiTar │
│ get; │
│ + requestId = "raidSimAsync-c8e6f5783f4f390b"; │
│ + iterations = 1000; │
│ + player = classes.${class}.${spec}.template.troll.p1.${encounterType}.singleTa │
│ rget; │
│ buffs = buffs.full; │
│ debuffs = debuffs.full; │
│ - encounter = encounter.${encounterType}.long.threeTarget; │
│ + encounter = encounter.${encounterType}.long.singleTarget; │
│ }; │
│ testRaid = writeShellApplication { │
│ name = "testRaid"; │
└────────────────────────────────────────────────────────────────────────────────────┘ ┌─ nix/pkgs/testRaid.nix ───────────── [ COPY ] ─┐
│ diff --git a/nix/pkgs/testRaid.nix b/nix/pkg │
│ s/testRaid.nix │
│ index a5d30e3..000de8b 100644 │
│ --- a/nix/pkgs/testRaid.nix │
│ +++ b/nix/pkgs/testRaid.nix │
│ @@ -12,17 +12,17 @@ │
│ # quickly sim a single spec for testing p │
│ urposes │
│ inherit (lib.sim.simulation) mkSim; │
│ │
│ - class = "warlock"; │
│ - spec = "demonology"; │
│ + class = "rogue"; │
│ + spec = "subtlety"; │
│ encounterType = "raid"; │
│ │
│ raid = mkSim { │
│ - requestId = "raidSimAsync-f2cf5e22118a4 │
│ 3c7"; │
│ - iterations = 10000; │
│ - player = classes.${class}.${spec}.templ │
│ ate.troll.p1.${encounterType}.multiTarget; │
│ + requestId = "raidSimAsync-c8e6f5783f4f3 │
│ 90b"; │
│ + iterations = 1000; │
│ + player = classes.${class}.${spec}.templ │
│ ate.troll.p1.${encounterType}.singleTarget; │
│ buffs = buffs.full; │
│ debuffs = debuffs.full; │
│ - encounter = encounter.${encounterType}. │
│ long.threeTarget; │
│ + encounter = encounter.${encounterType}. │
│ long.singleTarget; │
│ }; │
│ testRaid = writeShellApplication { │
│ name = "testRaid"; │
└──────────────────────────────────────────────┘ ┌─ web/src/layouts/ChartLayout.astro ─────────────────────────────────────── [ COPY ] ─┐
│ diff --git a/web/src/layouts/ChartLayout.astro b/web/src/layouts/ChartLayout.astro │
│ index 66c0acb..9ab5f3f 100644 │
│ --- a/web/src/layouts/ChartLayout.astro │
│ +++ b/web/src/layouts/ChartLayout.astro │
│ @@ -1624,6 +1624,12 @@ class UnifiedChart { │
│ <span class="metadata-label">Date Simulated</span> │
│ <span class="metadata-value">${simulationDate}</span> │
│ </div> │
│ + <div class="metadata-item"> │
│ + <span class="metadata-label">Simulation Hash</span> │
│ + <span class="metadata-value"> │
│ + <a href="https://github.com/wowsims/mop/commit/${metadata.wowsimsCo │
│ mmit}" target="_blank" rel="noopener noreferrer">${metadata.wowsimsCommit}</a> │
│ + </span> │
│ + </div> │
│ <div class="metadata-item metadata-item-wide"> │
│ <span class="metadata-label">Active Raid Buffs</span> │
│ <div class="callout-note"> │
│ @@ -1684,6 +1690,12 @@ class UnifiedChart { │
│ <span class="metadata-label">Date Simulated</span> │
│ <span class="metadata-value">${simulationDate}</span> │
│ </div> │
│ + <div class="metadata-item"> │
│ + <span class="metadata-label">Simulation Hash</span> │
│ + <span class="metadata-value"> │
│ + <a href="https://github.com/wowsims/mop/commit/${metadata.wowsimsCo │
│ mmit}" target="_blank" rel="noopener noreferrer">${metadata.wowsimsCommit}</a> │
│ + </span> │
│ + </div> │
│ <div class="metadata-item metadata-item-wide"> │
│ <span class="metadata-label">Active Raid Buffs</span> │
│ <span class="metadata-value metadata-value-wrap">${formatRaidBuffs(me │
│ tadata.raidBuffs)}</span> │
└────────────────────────────────────────────────────────────────────────────────────┘ ┌─ ...src/layouts/ChartLayout.astro ── [ COPY ] ─┐
│ diff --git a/web/src/layouts/ChartLayout.ast │
│ ro b/web/src/layouts/ChartLayout.astro │
│ index 66c0acb..9ab5f3f 100644 │
│ --- a/web/src/layouts/ChartLayout.astro │
│ +++ b/web/src/layouts/ChartLayout.astro │
│ @@ -1624,6 +1624,12 @@ class UnifiedChart { │
│ <span class="metadata-label">Da │
│ te Simulated</span> │
│ <span class="metadata-value">${ │
│ simulationDate}</span> │
│ </div> │
│ + <div class="metadata-item"> │
│ + <span class="metadata-label">Si │
│ mulation Hash</span> │
│ + <span class="metadata-value"> │
│ + <a href="https://github.com/w │
│ owsims/mop/commit/${metadata.wowsimsCommit}" │
│ target="_blank" rel="noopener noreferrer">$ │
│ {metadata.wowsimsCommit}</a> │
│ + </span> │
│ + </div> │
│ <div class="metadata-item metadat │
│ a-item-wide"> │
│ <span class="metadata-label">Ac │
│ tive Raid Buffs</span> │
│ <div class="callout-note"> │
│ @@ -1684,6 +1690,12 @@ class UnifiedChart { │
│ <span class="metadata-label">Da │
│ te Simulated</span> │
│ <span class="metadata-value">${ │
│ simulationDate}</span> │
│ </div> │
│ + <div class="metadata-item"> │
│ + <span class="metadata-label">Si │
│ mulation Hash</span> │
│ + <span class="metadata-value"> │
│ + <a href="https://github.com/w │
│ owsims/mop/commit/${metadata.wowsimsCommit}" │
│ target="_blank" rel="noopener noreferrer">$ │
│ {metadata.wowsimsCommit}</a> │
│ + </span> │
│ + </div> │
│ <div class="metadata-item metadat │
│ a-item-wide"> │
│ <span class="metadata-label">Ac │
│ tive Raid Buffs</span> │
│ <span class="metadata-value met │
│ adata-value-wrap">${formatRaidBuffs(metadata │
│ .raidBuffs)}</span> │
└──────────────────────────────────────────────┘ [ BACK TO LOG ] ──────────────────────────────────────────────────────────────────────────────────────
OOKNET ────────────────────────────────────────────────
OOKNET