HASH bc67f8bcebb9
DATE 2025-07-22
SUBJECT nix: formatting with alejandra
FILES 22 CHANGED
HASH bc67f8bcebb9
DATE 2025-07-22
SUBJECT nix: formatting with alejandra
FILES 22 CHANGED
┌─ nix/apps/simulation/default.nix ──────────────────────────────────────────┐
│ diff --git a/nix/apps/simulation/default.nix b/nix/apps/simulation/default.nix │
│ index db7e3f3..87ba8d8 100644 │
│ --- a/nix/apps/simulation/default.nix │
│ +++ b/nix/apps/simulation/default.nix │
│ @@ -8,10 +8,10 @@ │
│ inputs, │
│ ... │
│ }: let │
│ - # Mass simulations using mkMassSim │
│ massSimFunctions = import ./mkMassSim.nix {inherit lib pkgs classes encounter b │
│ uffs debuffs inputs;}; │
│ inherit (massSimFunctions) mkMassSim mkRaceComparison; │
│ │
│ + # TODO: abstract this. │
│ massSimulations = { │
│ dps-p1-raid-single-long = mkMassSim { │
│ specs = "dps"; # shortcut to all DPS classes templates │
│ @@ -57,7 +57,7 @@ │
│ template = "multiTarget"; │
│ }; │
│ dps-p1-raid-single-short = mkMassSim { │
│ - specs = "dps"; # shortcut to all DPS classes templates │
│ + specs = "dps"; │
│ encounter = encounter.raid.short.singleTarget; │
│ iterations = 10000; │
│ phase = "p1"; │
│ @@ -100,7 +100,7 @@ │
│ template = "multiTarget"; │
│ }; │
│ dps-p1-raid-single-burst = mkMassSim { │
│ - specs = "dps"; # burstcut to all DPS classes templates │
│ + specs = "dps"; │
│ encounter = encounter.raid.burst.singleTarget; │
│ iterations = 10000; │
│ phase = "p1"; │
│ @@ -144,139 +144,199 @@ │
│ }; │
│ }; │
│ │
│ - # Race comparison simulations for all DPS specs │
│ + # for all race combinations │
│ + raceScenarios = [ │
│ + { │
│ + targetCount = "single"; │
│ + duration = "long"; │
│ + encounter = encounter.raid.long.singleTarget; │
│ + template = "singleTarget"; │
│ + } │
│ + { │
│ + targetCount = "single"; │
│ + duration = "short"; │
│ + encounter = encounter.raid.short.singleTarget; │
│ + template = "singleTarget"; │
│ + } │
│ + { │
│ + targetCount = "single"; │
│ + duration = "burst"; │
│ + encounter = encounter.raid.burst.singleTarget; │
│ + template = "singleTarget"; │
│ + } │
│ + │
│ + { │
│ + targetCount = "three"; │
│ + duration = "long"; │
│ + encounter = encounter.raid.long.threeTarget; │
│ + template = "multiTarget"; │
│ + } │
│ + { │
│ + targetCount = "three"; │
│ + duration = "short"; │
│ + encounter = encounter.raid.short.threeTarget; │
│ + template = "multiTarget"; │
│ + } │
│ + { │
│ + targetCount = "three"; │
│ + duration = "burst"; │
│ + encounter = encounter.raid.burst.threeTarget; │
│ + template = "multiTarget"; │
│ + } │
│ + │
│ + { │
│ + targetCount = "cleave"; │
│ + duration = "long"; │
│ + encounter = encounter.raid.long.cleave; │
│ + template = "cleave"; │
│ + } │
│ + { │
│ + targetCount = "cleave"; │
│ + duration = "short"; │
│ + encounter = encounter.raid.short.cleave; │
│ + template = "cleave"; │
│ + } │
│ + { │
│ + targetCount = "cleave"; │
│ + duration = "burst"; │
│ + encounter = encounter.raid.burst.cleave; │
│ + template = "cleave"; │
│ + } │
│ + │
│ + { │
│ + targetCount = "ten"; │
│ + duration = "long"; │
│ + encounter = encounter.raid.long.tenTarget; │
│ + template = "multiTarget"; │
│ + } │
│ + { │
│ + targetCount = "ten"; │
│ + duration = "short"; │
│ + encounter = encounter.raid.short.tenTarget; │
│ + template = "multiTarget"; │
│ + } │
│ + { │
│ + targetCount = "ten"; │
│ + duration = "burst"; │
│ + encounter = encounter.raid.burst.tenTarget; │
│ + template = "multiTarget"; │
│ + } │
│ + ]; │
│ + │
│ raceComparisonSpecs = [ │
│ { │
│ class = "death_knight"; │
│ spec = "frost"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "death_knight"; │
│ spec = "unholy"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "druid"; │
│ spec = "balance"; │
│ - template = "singleTarget"; │
│ } │
│ - # { class = "druid"; spec = "feral"; template = "singleTarget"; } │
│ + # { class = "druid"; spec = "feral"; } │
│ { │
│ class = "hunter"; │
│ spec = "beast_mastery"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "hunter"; │
│ spec = "marksmanship"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "hunter"; │
│ spec = "survival"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "mage"; │
│ spec = "arcane"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "mage"; │
│ spec = "fire"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "mage"; │
│ spec = "frost"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "monk"; │
│ spec = "windwalker"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "paladin"; │
│ spec = "retribution"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "priest"; │
│ spec = "shadow"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "rogue"; │
│ spec = "assassination"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "rogue"; │
│ spec = "combat"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "rogue"; │
│ spec = "subtlety"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "shaman"; │
│ spec = "elemental"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "shaman"; │
│ spec = "enhancement"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warlock"; │
│ spec = "affliction"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warlock"; │
│ spec = "demonology"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warlock"; │
│ spec = "destruction"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warrior"; │
│ spec = "arms"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warrior"; │
│ spec = "fury"; │
│ - template = "singleTarget"; │
│ } │
│ ]; │
│ │
│ - # Generate race comparison simulations for single target long encounters │
│ - raceComparisons = lib.listToAttrs (map (specConfig: { │
│ - name = "race-${specConfig.class}-${specConfig.spec}-p1-raid-single-long"; │
│ - value = mkRaceComparison { │
│ - class = specConfig.class; │
│ - spec = specConfig.spec; │
│ - encounter = encounter.raid.long.singleTarget; │
│ - iterations = 10000; │
│ - phase = "p1"; │
│ - encounterType = "raid"; │
│ - targetCount = "single"; │
│ - duration = "long"; │
│ - template = specConfig.template; │
│ - }; │
│ - }) │
│ - raceComparisonSpecs); │
│ + # generate all race comparison combinations (specs ? scenarios) │
│ + raceComparisons = lib.listToAttrs (lib.flatten (map ( │
│ + specConfig: │
│ + map (scenario: { │
│ + name = "race-${specConfig.class}-${specConfig.spec}-p1-raid-${scenario. │
│ targetCount}-${scenario.duration}"; │
│ + value = mkRaceComparison { │
│ + class = specConfig.class; │
│ + spec = specConfig.spec; │
│ + encounter = scenario.encounter; │
│ + iterations = 10000; │
│ + phase = "p1"; │
│ + encounterType = "raid"; │
│ + targetCount = scenario.targetCount; │
│ + duration = scenario.duration; │
│ + template = scenario.template; │
│ + }; │
│ + }) │
│ + raceScenarios │
│ + ) │
│ + raceComparisonSpecs)); │
│ │
│ - # Script that runs all simulations │
│ + # script that runs all simulations │
│ allSimulationsScript = pkgs.writeShellApplication { │
│ name = "all-simulations"; │
│ text = '' │
│ @@ -310,7 +370,7 @@ │
│ runtimeInputs = [pkgs.coreutils pkgs.findutils]; │
│ }; │
│ │
│ - # Convert mass simulations to apps and add the all-simulations app │
│ + # nix app │
│ simulationApps = │
│ lib.mapAttrs (name: massSim: { │
│ type = "app"; │
│ @@ -318,7 +378,6 @@ │
│ }) │
│ massSimulations; │
│ │
│ - # Convert race comparisons to apps │
│ raceComparisonApps = │
│ lib.mapAttrs (name: raceComp: { │
│ type = "app"; │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/apps/simulation/default.nix ────┐
│ diff --git a/nix/apps/simulation/default.nix │
│ b/nix/apps/simulation/default.nix │
│ index db7e3f3..87ba8d8 100644 │
│ --- a/nix/apps/simulation/default.nix │
│ +++ b/nix/apps/simulation/default.nix │
│ @@ -8,10 +8,10 @@ │
│ inputs, │
│ ... │
│ }: let │
│ - # Mass simulations using mkMassSim │
│ massSimFunctions = import ./mkMassSim.nix │
│ {inherit lib pkgs classes encounter buffs d │
│ ebuffs inputs;}; │
│ inherit (massSimFunctions) mkMassSim mkRa │
│ ceComparison; │
│ │
│ + # TODO: abstract this. │
│ massSimulations = { │
│ dps-p1-raid-single-long = mkMassSim { │
│ specs = "dps"; # shortcut to all DPS │
│ classes templates │
│ @@ -57,7 +57,7 @@ │
│ template = "multiTarget"; │
│ }; │
│ dps-p1-raid-single-short = mkMassSim { │
│ - specs = "dps"; # shortcut to all DPS │
│ classes templates │
│ + specs = "dps"; │
│ encounter = encounter.raid.short.sing │
│ leTarget; │
│ iterations = 10000; │
│ phase = "p1"; │
│ @@ -100,7 +100,7 @@ │
│ template = "multiTarget"; │
│ }; │
│ dps-p1-raid-single-burst = mkMassSim { │
│ - specs = "dps"; # burstcut to all DPS │
│ classes templates │
│ + specs = "dps"; │
│ encounter = encounter.raid.burst.sing │
│ leTarget; │
│ iterations = 10000; │
│ phase = "p1"; │
│ @@ -144,139 +144,199 @@ │
│ }; │
│ }; │
│ │
│ - # Race comparison simulations for all DPS │
│ specs │
│ + # for all race combinations │
│ + raceScenarios = [ │
│ + { │
│ + targetCount = "single"; │
│ + duration = "long"; │
│ + encounter = encounter.raid.long.singl │
│ eTarget; │
│ + template = "singleTarget"; │
│ + } │
│ + { │
│ + targetCount = "single"; │
│ + duration = "short"; │
│ + encounter = encounter.raid.short.sing │
│ leTarget; │
│ + template = "singleTarget"; │
│ + } │
│ + { │
│ + targetCount = "single"; │
│ + duration = "burst"; │
│ + encounter = encounter.raid.burst.sing │
│ leTarget; │
│ + template = "singleTarget"; │
│ + } │
│ + │
│ + { │
│ + targetCount = "three"; │
│ + duration = "long"; │
│ + encounter = encounter.raid.long.three │
│ Target; │
│ + template = "multiTarget"; │
│ + } │
│ + { │
│ + targetCount = "three"; │
│ + duration = "short"; │
│ + encounter = encounter.raid.short.thre │
│ eTarget; │
│ + template = "multiTarget"; │
│ + } │
│ + { │
│ + targetCount = "three"; │
│ + duration = "burst"; │
│ + encounter = encounter.raid.burst.thre │
│ eTarget; │
│ + template = "multiTarget"; │
│ + } │
│ + │
│ + { │
│ + targetCount = "cleave"; │
│ + duration = "long"; │
│ + encounter = encounter.raid.long.cleav │
│ e; │
│ + template = "cleave"; │
│ + } │
│ + { │
│ + targetCount = "cleave"; │
│ + duration = "short"; │
│ + encounter = encounter.raid.short.clea │
│ ve; │
│ + template = "cleave"; │
│ + } │
│ + { │
│ + targetCount = "cleave"; │
│ + duration = "burst"; │
│ + encounter = encounter.raid.burst.clea │
│ ve; │
│ + template = "cleave"; │
│ + } │
│ + │
│ + { │
│ + targetCount = "ten"; │
│ + duration = "long"; │
│ + encounter = encounter.raid.long.tenTa │
│ rget; │
│ + template = "multiTarget"; │
│ + } │
│ + { │
│ + targetCount = "ten"; │
│ + duration = "short"; │
│ + encounter = encounter.raid.short.tenT │
│ arget; │
│ + template = "multiTarget"; │
│ + } │
│ + { │
│ + targetCount = "ten"; │
│ + duration = "burst"; │
│ + encounter = encounter.raid.burst.tenT │
│ arget; │
│ + template = "multiTarget"; │
│ + } │
│ + ]; │
│ + │
│ raceComparisonSpecs = [ │
│ { │
│ class = "death_knight"; │
│ spec = "frost"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "death_knight"; │
│ spec = "unholy"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "druid"; │
│ spec = "balance"; │
│ - template = "singleTarget"; │
│ } │
│ - # { class = "druid"; spec = "feral"; te │
│ mplate = "singleTarget"; } │
│ + # { class = "druid"; spec = "feral"; } │
│ { │
│ class = "hunter"; │
│ spec = "beast_mastery"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "hunter"; │
│ spec = "marksmanship"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "hunter"; │
│ spec = "survival"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "mage"; │
│ spec = "arcane"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "mage"; │
│ spec = "fire"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "mage"; │
│ spec = "frost"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "monk"; │
│ spec = "windwalker"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "paladin"; │
│ spec = "retribution"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "priest"; │
│ spec = "shadow"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "rogue"; │
│ spec = "assassination"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "rogue"; │
│ spec = "combat"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "rogue"; │
│ spec = "subtlety"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "shaman"; │
│ spec = "elemental"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "shaman"; │
│ spec = "enhancement"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warlock"; │
│ spec = "affliction"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warlock"; │
│ spec = "demonology"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warlock"; │
│ spec = "destruction"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warrior"; │
│ spec = "arms"; │
│ - template = "singleTarget"; │
│ } │
│ { │
│ class = "warrior"; │
│ spec = "fury"; │
│ - template = "singleTarget"; │
│ } │
│ ]; │
│ │
│ - # Generate race comparison simulations fo │
│ r single target long encounters │
│ - raceComparisons = lib.listToAttrs (map (s │
│ pecConfig: { │
│ - name = "race-${specConfig.class}-${sp │
│ ecConfig.spec}-p1-raid-single-long"; │
│ - value = mkRaceComparison { │
│ - class = specConfig.class; │
│ - spec = specConfig.spec; │
│ - encounter = encounter.raid.long.sin │
│ gleTarget; │
│ - iterations = 10000; │
│ - phase = "p1"; │
│ - encounterType = "raid"; │
│ - targetCount = "single"; │
│ - duration = "long"; │
│ - template = specConfig.template; │
│ - }; │
│ - }) │
│ - raceComparisonSpecs); │
│ + # generate all race comparison combinatio │
│ ns (specs ? scenarios) │
│ + raceComparisons = lib.listToAttrs (lib.fl │
│ atten (map ( │
│ + specConfig: │
│ + map (scenario: { │
│ + name = "race-${specConfig.class}- │
│ ${specConfig.spec}-p1-raid-${scenario.target │
│ Count}-${scenario.duration}"; │
│ + value = mkRaceComparison { │
│ + class = specConfig.class; │
│ + spec = specConfig.spec; │
│ + encounter = scenario.encounter; │
│ + iterations = 10000; │
│ + phase = "p1"; │
│ + encounterType = "raid"; │
│ + targetCount = scenario.targetCo │
│ unt; │
│ + duration = scenario.duration; │
│ + template = scenario.template; │
│ + }; │
│ + }) │
│ + raceScenarios │
│ + ) │
│ + raceComparisonSpecs)); │
│ │
│ - # Script that runs all simulations │
│ + # script that runs all simulations │
│ allSimulationsScript = pkgs.writeShellApp │
│ lication { │
│ name = "all-simulations"; │
│ text = '' │
│ @@ -310,7 +370,7 @@ │
│ runtimeInputs = [pkgs.coreutils pkgs.fi │
│ ndutils]; │
│ }; │
│ │
│ - # Convert mass simulations to apps and ad │
│ d the all-simulations app │
│ + # nix app │
│ simulationApps = │
│ lib.mapAttrs (name: massSim: { │
│ type = "app"; │
│ @@ -318,7 +378,6 @@ │
│ }) │
│ massSimulations; │
│ │
│ - # Convert race comparisons to apps │
│ raceComparisonApps = │
│ lib.mapAttrs (name: raceComp: { │
│ type = "app"; │
└──────────────────────────────────────────────┘
┌─ nix/apps/simulation/mkMassSim.nix ────────────────────────────────────────┐
│ diff --git a/nix/apps/simulation/mkMassSim.nix b/nix/apps/simulation/mkMassSim.nix │
│ index 9adbf3b..9555de5 100644 │
│ --- a/nix/apps/simulation/mkMassSim.nix │
│ +++ b/nix/apps/simulation/mkMassSim.nix │
│ @@ -8,14 +8,17 @@ │
│ inputs, │
│ ... │
│ }: let │
│ + # TODO: this is cursed, consolidate the functions. │
│ inherit (lib.sim.simulation) mkSim; │
│ │
│ - # Extract playable races from class definitions │
│ - getPlayableRaces = className: │
│ + # extract playable races from class definitions │
│ + getPlayableRaces = className: │
│ if lib.hasAttr className classes && lib.hasAttr "playableRaces" classes.${cla │
│ ssName} │
│ then classes.${className}.playableRaces │
│ else throw "playableRaces not defined for class ${className}. Please add play │
│ ableRaces = [...] to nix/classes/${className}/default.nix"; │
│ │
│ + # categorize specs by role │
│ + # TODO: tanks │
│ getAllDPSSpecs = classes: template: let │
│ dpsSpecs = { │
│ death_knight = ["frost" "unholy"]; │
│ @@ -31,7 +34,7 @@ │
│ warrior = ["arms" "fury"]; │
│ }; │
│ │
│ - # Extract specs that exist in classes and have the template structure │
│ + # extract specs that exist in classes and have the template structure │
│ validSpecs = lib.flatten (lib.mapAttrsToList ( │
│ className: specNames: │
│ lib.filter (spec: spec != null) (map ( │
│ @@ -45,7 +48,8 @@ │
│ defaultRace = classes.${className}.${specName}.defaultRace; │
│ spec = classes.${className}.${specName}; │
│ in │
│ - if lib.hasAttr defaultRace spec.template │
│ + if │
│ + lib.hasAttr defaultRace spec.template │
│ && lib.hasAttr "p1" spec.template.${defaultRace} │
│ && lib.hasAttr "raid" spec.template.${defaultRace}.p1 │
│ && lib.hasAttr template spec.template.${defaultRace}.p1.raid │
│ @@ -62,40 +66,38 @@ │
│ in │
│ validSpecs; │
│ │
│ - # Get race configurations for a specific class/spec combination │
│ getRaceConfigs = classes: className: specName: template: phase: encounterType: │
│ let │
│ availableRaces = getPlayableRaces className; │
│ baseSpec = classes.${className}.${specName}; │
│ in │
│ map (raceName: { │
│ inherit className specName raceName; │
│ - # Access the race-specific config from the new template structure │
│ - config = │
│ - if lib.hasAttr "template" baseSpec │
│ + config = │
│ + if │
│ + lib.hasAttr "template" baseSpec │
│ && lib.hasAttr raceName baseSpec.template │
│ && lib.hasAttr phase baseSpec.template.${raceName} │
│ && lib.hasAttr encounterType baseSpec.template.${raceName}.${phase} │
│ && lib.hasAttr template baseSpec.template.${raceName}.${phase}.${encoun │
│ terType} │
│ then baseSpec.template.${raceName}.${phase}.${encounterType}.${template} │
│ else throw "Template ${template} not found for ${className}/${specName}/$ │
│ {raceName} at ${phase}.${encounterType}"; │
│ - }) availableRaces; │
│ + }) │
│ + availableRaces; │
│ │
│ - # Race comparison function │
│ mkRaceComparison = { │
│ class, │
│ spec, │
│ encounter, │
│ iterations ? 10000, │
│ - phase ? "p1", │
│ + phase ? "p1", │
│ encounterType ? "raid", │
│ targetCount ? "single", │
│ duration ? "long", │
│ template ? "singleTarget", │
│ }: let │
│ - # Get race configurations for this class/spec │
│ raceConfigs = getRaceConfigs classes class spec template phase encounterType; │
│ - │
│ - # Create individual simulation derivations for each race │
│ + │
│ + # create individual simulation derivations for each race │
│ simDerivations = lib.listToAttrs (map (raceConfig: { │
│ name = "${raceConfig.className}-${raceConfig.specName}-${raceConfig.raceN │
│ ame}"; │
│ value = let │
│ @@ -111,21 +113,19 @@ │
│ buildInputs = [pkgs.jq]; │
│ nativeBuildInputs = [inputs.wowsims.packages.${pkgs.system}.wowsimcli │
│ ]; │
│ } '' │
│ - # Generate input JSON file │
│ cat > input.json << 'EOF' │
│ ${simInput} │
│ EOF │
│ │
│ - # Run simulation │
│ echo "Running ${raceConfig.className}/${raceConfig.specName}/${raceCo │
│ nfig.raceName} simulation..." │
│ if wowsimcli sim --infile input.json --outfile output.json; then │
│ - # Extract DPS statistics │
│ + # extract dps statistics │
│ avgDps=$(jq -r '.raidMetrics.dps.avg // 0' output.json) │
│ maxDps=$(jq -r '.raidMetrics.dps.max // 0' output.json) │
│ minDps=$(jq -r '.raidMetrics.dps.min // 0' output.json) │
│ stdevDps=$(jq -r '.raidMetrics.dps.stdev // 0' output.json) │
│ │
│ - # Create loadout info │
│ + # construct loadout info │
│ loadout=$(echo '${builtins.toJSON raceConfig.config}' | jq '{ │
│ consumables, │
│ talentsString, │
│ @@ -137,7 +137,7 @@ │
│ profession2 │
│ }') │
│ │
│ - # Create final result │
│ + # create final result │
│ jq -n \ │
│ --arg raceName "${raceConfig.raceName}" \ │
│ --arg avgDps "$avgDps" \ │
│ @@ -161,10 +161,8 @@ │
│ }) │
│ raceConfigs); │
│ │
│ - # Generate output filename: <class>_<spec>_race_<phase>_<encounter-type>_<tar │
│ get-count>_<duration> │
│ structuredOutput = "${class}_${spec}_race_${phase}_${encounterType}_${targetC │
│ ount}_${duration}"; │
│ │
│ - # Aggregation script for race comparison │
│ aggregationScript = pkgs.writeShellApplication { │
│ name = "${structuredOutput}-aggregator"; │
│ text = '' │
│ @@ -173,11 +171,10 @@ │
│ echo "Aggregating race comparison results for: ${class}/${spec}" │
│ echo "Races simulated: ${toString (lib.length raceConfigs)}" │
│ │
│ - # Create base structure │
│ result=$(jq -n '{}') │
│ │
│ ${lib.concatMapStringsSep "\n" (raceConfig: '' │
│ - # Add ${raceConfig.raceName} results │
│ + # ${raceConfig.raceName} results │
│ raceData=$(cat ${simDerivations."${raceConfig.className}-${raceConfig │
│ .specName}-${raceConfig.raceName}"}) │
│ │
│ result=$(echo "$result" | jq \ │
│ @@ -193,7 +190,6 @@ │
│ '') │
│ raceConfigs} │
│ │
│ - # Create final output with metadata │
│ finalResult=$(echo "$result" | jq \ │
│ --arg class "${class}" \ │
│ --arg spec "${spec}" \ │
│ @@ -219,9 +215,8 @@ │
│ results: . │
│ }') │
│ │
│ - echo "$finalResult" | tee "${structuredOutput}.json" │
│ + echo "$finalResult" | jq -c '.' | tee "${structuredOutput}.json" │
│ │
│ - # Copy to web public directory with new structure │
│ repo_root="" │
│ current_dir="$PWD" │
│ while [[ "$current_dir" != "/" ]]; do │
│ @@ -237,11 +232,10 @@ │
│ repo_root="$PWD" │
│ fi │
│ │
│ - # Create directory structure: /comparison/<class>/<spec>/ │
│ comparison_dir="$repo_root/web/public/data/comparison/${class}/${spec}" │
│ mkdir -p "$comparison_dir" │
│ │
│ - # Copy race comparison file │
│ + # copy race comparison file │
│ cp "${structuredOutput}.json" "$comparison_dir/" │
│ echo "Copied to: $comparison_dir/${structuredOutput}.json" │
│ │
│ @@ -253,14 +247,14 @@ │
│ select(.value.dps != null and .value.dps > 0) | │
│ "\(.key): \(.value.dps | floor) DPS" │
│ ' | sort -k2 -nr │
│ - │
│ + │
│ # Show any failed races │
│ failed_races=$(echo "$finalResult" | jq -r ' │
│ .results | to_entries[] | │
│ select(.value.dps == null or .value.dps <= 0) | │
│ .key │
│ ') │
│ - │
│ + │
│ if [[ -n "$failed_races" ]]; then │
│ echo "" │
│ echo "Failed races (no valid DPS data):" │
│ @@ -273,10 +267,8 @@ │
│ runtimeInputs = [pkgs.jq pkgs.coreutils]; │
│ }; │
│ in { │
│ - # Individual race simulation derivations (for debugging) │
│ simulations = simDerivations; │
│ │
│ - # Main aggregation script │
│ script = aggregationScript; │
│ │
│ metadata = { │
│ @@ -287,7 +279,6 @@ │
│ }; │
│ }; │
│ │
│ - # Main mkMassSim function │
│ mkMassSim = { │
│ specs ? "dps", │
│ encounter, │
│ @@ -298,7 +289,7 @@ │
│ duration ? "long", │
│ template ? "singleTarget", │
│ }: let │
│ - # Get the list of specs based on the specs parameter │
│ + # get the list of specs based on the specs parameter │
│ specConfigs = │
│ if specs == "dps" │
│ then getAllDPSSpecs classes template │
│ @@ -306,7 +297,7 @@ │
│ then specs │
│ else throw "specs must be 'dps' or a list of spec configurations"; │
│ │
│ - # Create individual simulation derivations for each spec │
│ + # create individual simulation derivations for each spec │
│ simDerivations = lib.listToAttrs (map (spec: { │
│ name = "${spec.className}-${spec.specName}"; │
│ value = let │
│ @@ -327,16 +318,16 @@ │
│ ${simInput} │
│ EOF │
│ │
│ - # Run simulation │
│ echo "Running ${spec.className}/${spec.specName} simulation..." │
│ if wowsimcli sim --infile input.json --outfile output.json; then │
│ - # Extract DPS statistics │
│ + │
│ avgDps=$(jq -r '.raidMetrics.dps.avg // 0' output.json) │
│ maxDps=$(jq -r '.raidMetrics.dps.max // 0' output.json) │
│ minDps=$(jq -r '.raidMetrics.dps.min // 0' output.json) │
│ stdevDps=$(jq -r '.raidMetrics.dps.stdev // 0' output.json) │
│ │
│ - # Create loadout without rotation (only keep consumables, talents, │
│ glyphs, gear) │
│ + # create loadout without rotation (only keep consumables, talents, │
│ glyphs, gear) │
│ + # TODO: should we output the apl? │
│ loadout=$(echo '${builtins.toJSON spec.config}' | jq '{ │
│ consumables, │
│ talentsString, │
│ @@ -348,7 +339,7 @@ │
│ profession2 │
│ }') │
│ │
│ - # Create final result with all DPS statistics │
│ + # create final result with all DPS statistics │
│ jq -n \ │
│ --arg className "${spec.className}" \ │
│ --arg specName "${spec.specName}" \ │
│ @@ -431,10 +422,10 @@ │
│ results: . │
│ }') │
│ │
│ - echo "$finalResult" | tee "${structuredOutput}.json" │
│ + echo "$finalResult" | jq -c '.' | tee "${structuredOutput}.json" │
│ │
│ # copy to web public directory for web frontend │
│ - # Find the repo root by looking for flake.nix │
│ + # find the repo root by looking for flake.nix │
│ repo_root="" │
│ current_dir="$PWD" │
│ while [[ "$current_dir" != "/" ]]; do │
│ @@ -459,14 +450,12 @@ │
│ mkdir -p "$rankings_dir" │
│ mkdir -p "$archive_dir" │
│ │
│ - # Archive existing file if it exists │
│ if [[ -f "$existing_file" ]]; then │
│ timestamp=$(date +"%Y%m%d_%H%M%S") │
│ archived_name="${structuredOutput}_$timestamp.json" │
│ cp "$existing_file" "$archive_dir/$archived_name" │
│ echo "Archived existing file: $archived_name" │
│ │
│ - # Generate changelog by comparing with archived version │
│ echo "Generating changelog..." │
│ changes=$(echo "$finalResult" | jq --slurpfile archived "$existing_file │
│ " ' │
│ .results as $current | │
│ @@ -497,7 +486,6 @@ │
│ echo "Found $change_count DPS changes:" │
│ echo "$changes" | jq -r '.[] | " \(.class)/\(.spec): \(if .absolute_ │
│ change > 0 then "+" else "" end)\(.absolute_change) DPS (\(if .percent_change > 0 │
│ then "+" else "" end)\(.percent_change)%)"' │
│ │
│ - # Update or create changelog │
│ changelog_file="$web_data_dir/changelog.json" │
│ if [[ -f "$changelog_file" ]]; then │
│ current_changelog=$(cat "$changelog_file") │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ ...apps/simulation/mkMassSim.nix ───┐
│ diff --git a/nix/apps/simulation/mkMassSim.n │
│ ix b/nix/apps/simulation/mkMassSim.nix │
│ index 9adbf3b..9555de5 100644 │
│ --- a/nix/apps/simulation/mkMassSim.nix │
│ +++ b/nix/apps/simulation/mkMassSim.nix │
│ @@ -8,14 +8,17 @@ │
│ inputs, │
│ ... │
│ }: let │
│ + # TODO: this is cursed, consolidate the f │
│ unctions. │
│ inherit (lib.sim.simulation) mkSim; │
│ │
│ - # Extract playable races from class defin │
│ itions │
│ - getPlayableRaces = className: │
│ + # extract playable races from class defin │
│ itions │
│ + getPlayableRaces = className: │
│ if lib.hasAttr className classes && lib │
│ .hasAttr "playableRaces" classes.${className │
│ } │
│ then classes.${className}.playableRaces │
│ else throw "playableRaces not defined f │
│ or class ${className}. Please add playableRa │
│ ces = [...] to nix/classes/${className}/defa │
│ ult.nix"; │
│ │
│ + # categorize specs by role │
│ + # TODO: tanks │
│ getAllDPSSpecs = classes: template: let │
│ dpsSpecs = { │
│ death_knight = ["frost" "unholy"]; │
│ @@ -31,7 +34,7 @@ │
│ warrior = ["arms" "fury"]; │
│ }; │
│ │
│ - # Extract specs that exist in classes a │
│ nd have the template structure │
│ + # extract specs that exist in classes a │
│ nd have the template structure │
│ validSpecs = lib.flatten (lib.mapAttrsT │
│ oList ( │
│ className: specNames: │
│ lib.filter (spec: spec != null) ( │
│ map ( │
│ @@ -45,7 +48,8 @@ │
│ defaultRace = classes.${c │
│ lassName}.${specName}.defaultRace; │
│ spec = classes.${classNam │
│ e}.${specName}; │
│ in │
│ - if lib.hasAttr defaultRac │
│ e spec.template │
│ + if │
│ + lib.hasAttr defaultRace │
│ spec.template │
│ && lib.hasAttr "p1" spe │
│ c.template.${defaultRace} │
│ && lib.hasAttr "raid" s │
│ pec.template.${defaultRace}.p1 │
│ && lib.hasAttr template │
│ spec.template.${defaultRace}.p1.raid │
│ @@ -62,40 +66,38 @@ │
│ in │
│ validSpecs; │
│ │
│ - # Get race configurations for a specific │
│ class/spec combination │
│ getRaceConfigs = classes: className: spec │
│ Name: template: phase: encounterType: let │
│ availableRaces = getPlayableRaces class │
│ Name; │
│ baseSpec = classes.${className}.${specN │
│ ame}; │
│ in │
│ map (raceName: { │
│ inherit className specName raceName; │
│ - # Access the race-specific config fro │
│ m the new template structure │
│ - config = │
│ - if lib.hasAttr "template" baseSpec │
│ + config = │
│ + if │
│ + lib.hasAttr "template" baseSpec │
│ && lib.hasAttr raceName baseSpec. │
│ template │
│ && lib.hasAttr phase baseSpec.tem │
│ plate.${raceName} │
│ && lib.hasAttr encounterType base │
│ Spec.template.${raceName}.${phase} │
│ && lib.hasAttr template baseSpec. │
│ template.${raceName}.${phase}.${encounterTyp │
│ e} │
│ then baseSpec.template.${raceName}. │
│ ${phase}.${encounterType}.${template} │
│ else throw "Template ${template} no │
│ t found for ${className}/${specName}/${raceN │
│ ame} at ${phase}.${encounterType}"; │
│ - }) availableRaces; │
│ + }) │
│ + availableRaces; │
│ │
│ - # Race comparison function │
│ mkRaceComparison = { │
│ class, │
│ spec, │
│ encounter, │
│ iterations ? 10000, │
│ - phase ? "p1", │
│ + phase ? "p1", │
│ encounterType ? "raid", │
│ targetCount ? "single", │
│ duration ? "long", │
│ template ? "singleTarget", │
│ }: let │
│ - # Get race configurations for this clas │
│ s/spec │
│ raceConfigs = getRaceConfigs classes cl │
│ ass spec template phase encounterType; │
│ - │
│ - # Create individual simulation derivati │
│ ons for each race │
│ + │
│ + # create individual simulation derivati │
│ ons for each race │
│ simDerivations = lib.listToAttrs (map ( │
│ raceConfig: { │
│ name = "${raceConfig.className}-${r │
│ aceConfig.specName}-${raceConfig.raceName}"; │
│ value = let │
│ @@ -111,21 +113,19 @@ │
│ buildInputs = [pkgs.jq]; │
│ nativeBuildInputs = [inputs.wow │
│ sims.packages.${pkgs.system}.wowsimcli]; │
│ } '' │
│ - # Generate input JSON file │
│ cat > input.json << 'EOF' │
│ ${simInput} │
│ EOF │
│ │
│ - # Run simulation │
│ echo "Running ${raceConfig.clas │
│ sName}/${raceConfig.specName}/${raceConfig.r │
│ aceName} simulation..." │
│ if wowsimcli sim --infile input │
│ .json --outfile output.json; then │
│ - # Extract DPS statistics │
│ + # extract dps statistics │
│ avgDps=$(jq -r '.raidMetrics. │
│ dps.avg // 0' output.json) │
│ maxDps=$(jq -r '.raidMetrics. │
│ dps.max // 0' output.json) │
│ minDps=$(jq -r '.raidMetrics. │
│ dps.min // 0' output.json) │
│ stdevDps=$(jq -r '.raidMetric │
│ s.dps.stdev // 0' output.json) │
│ │
│ - # Create loadout info │
│ + # construct loadout info │
│ loadout=$(echo '${builtins.to │
│ JSON raceConfig.config}' | jq '{ │
│ consumables, │
│ talentsString, │
│ @@ -137,7 +137,7 @@ │
│ profession2 │
│ }') │
│ │
│ - # Create final result │
│ + # create final result │
│ jq -n \ │
│ --arg raceName "${raceConfi │
│ g.raceName}" \ │
│ --arg avgDps "$avgDps" \ │
│ @@ -161,10 +161,8 @@ │
│ }) │
│ raceConfigs); │
│ │
│ - # Generate output filename: <class>_<sp │
│ ec>_race_<phase>_<encounter-type>_<target-co │
│ unt>_<duration> │
│ structuredOutput = "${class}_${spec}_ra │
│ ce_${phase}_${encounterType}_${targetCount}_ │
│ ${duration}"; │
│ │
│ - # Aggregation script for race compariso │
│ n │
│ aggregationScript = pkgs.writeShellAppl │
│ ication { │
│ name = "${structuredOutput}-aggregato │
│ r"; │
│ text = '' │
│ @@ -173,11 +171,10 @@ │
│ echo "Aggregating race comparison r │
│ esults for: ${class}/${spec}" │
│ echo "Races simulated: ${toString ( │
│ lib.length raceConfigs)}" │
│ │
│ - # Create base structure │
│ result=$(jq -n '{}') │
│ │
│ ${lib.concatMapStringsSep "\n" (rac │
│ eConfig: '' │
│ - # Add ${raceConfig.raceName} re │
│ sults │
│ + # ${raceConfig.raceName} result │
│ s │
│ raceData=$(cat ${simDerivations │
│ ."${raceConfig.className}-${raceConfig.specN │
│ ame}-${raceConfig.raceName}"}) │
│ │
│ result=$(echo "$result" | jq \ │
│ @@ -193,7 +190,6 @@ │
│ '') │
│ raceConfigs} │
│ │
│ - # Create final output with metadata │
│ finalResult=$(echo "$result" | jq \ │
│ --arg class "${class}" \ │
│ --arg spec "${spec}" \ │
│ @@ -219,9 +215,8 @@ │
│ results: . │
│ }') │
│ │
│ - echo "$finalResult" | tee "${struct │
│ uredOutput}.json" │
│ + echo "$finalResult" | jq -c '.' | t │
│ ee "${structuredOutput}.json" │
│ │
│ - # Copy to web public directory with │
│ new structure │
│ repo_root="" │
│ current_dir="$PWD" │
│ while [[ "$current_dir" != "/" ]]; │
│ do │
│ @@ -237,11 +232,10 @@ │
│ repo_root="$PWD" │
│ fi │
│ │
│ - # Create directory structure: /comp │
│ arison/<class>/<spec>/ │
│ comparison_dir="$repo_root/web/publ │
│ ic/data/comparison/${class}/${spec}" │
│ mkdir -p "$comparison_dir" │
│ │
│ - # Copy race comparison file │
│ + # copy race comparison file │
│ cp "${structuredOutput}.json" "$com │
│ parison_dir/" │
│ echo "Copied to: $comparison_dir/${ │
│ structuredOutput}.json" │
│ │
│ @@ -253,14 +247,14 @@ │
│ select(.value.dps != null and .va │
│ lue.dps > 0) | │
│ "\(.key): \(.value.dps | floor) D │
│ PS" │
│ ' | sort -k2 -nr │
│ - │
│ + │
│ # Show any failed races │
│ failed_races=$(echo "$finalResult" │
│ | jq -r ' │
│ .results | to_entries[] | │
│ select(.value.dps == null or .val │
│ ue.dps <= 0) | │
│ .key │
│ ') │
│ - │
│ + │
│ if [[ -n "$failed_races" ]]; then │
│ echo "" │
│ echo "Failed races (no valid DPS │
│ data):" │
│ @@ -273,10 +267,8 @@ │
│ runtimeInputs = [pkgs.jq pkgs.coreuti │
│ ls]; │
│ }; │
│ in { │
│ - # Individual race simulation derivation │
│ s (for debugging) │
│ simulations = simDerivations; │
│ │
│ - # Main aggregation script │
│ script = aggregationScript; │
│ │
│ metadata = { │
│ @@ -287,7 +279,6 @@ │
│ }; │
│ }; │
│ │
│ - # Main mkMassSim function │
│ mkMassSim = { │
│ specs ? "dps", │
│ encounter, │
│ @@ -298,7 +289,7 @@ │
│ duration ? "long", │
│ template ? "singleTarget", │
│ }: let │
│ - # Get the list of specs based on the sp │
│ ecs parameter │
│ + # get the list of specs based on the sp │
│ ecs parameter │
│ specConfigs = │
│ if specs == "dps" │
│ then getAllDPSSpecs classes template │
│ @@ -306,7 +297,7 @@ │
│ then specs │
│ else throw "specs must be 'dps' or a │
│ list of spec configurations"; │
│ │
│ - # Create individual simulation derivati │
│ ons for each spec │
│ + # create individual simulation derivati │
│ ons for each spec │
│ simDerivations = lib.listToAttrs (map ( │
│ spec: { │
│ name = "${spec.className}-${spec.sp │
│ ecName}"; │
│ value = let │
│ @@ -327,16 +318,16 @@ │
│ ${simInput} │
│ EOF │
│ │
│ - # Run simulation │
│ echo "Running ${spec.className} │
│ /${spec.specName} simulation..." │
│ if wowsimcli sim --infile input │
│ .json --outfile output.json; then │
│ - # Extract DPS statistics │
│ + │
│ avgDps=$(jq -r '.raidMetrics. │
│ dps.avg // 0' output.json) │
│ maxDps=$(jq -r '.raidMetrics. │
│ dps.max // 0' output.json) │
│ minDps=$(jq -r '.raidMetrics. │
│ dps.min // 0' output.json) │
│ stdevDps=$(jq -r '.raidMetric │
│ s.dps.stdev // 0' output.json) │
│ │
│ - # Create loadout without rota │
│ tion (only keep consumables, talents, glyphs │
│ , gear) │
│ + # create loadout without rota │
│ tion (only keep consumables, talents, glyphs │
│ , gear) │
│ + # TODO: should we output the │
│ apl? │
│ loadout=$(echo '${builtins.to │
│ JSON spec.config}' | jq '{ │
│ consumables, │
│ talentsString, │
│ @@ -348,7 +339,7 @@ │
│ profession2 │
│ }') │
│ │
│ - # Create final result with al │
│ l DPS statistics │
│ + # create final result with al │
│ l DPS statistics │
│ jq -n \ │
│ --arg className "${spec.cla │
│ ssName}" \ │
│ --arg specName "${spec.spec │
│ Name}" \ │
│ @@ -431,10 +422,10 @@ │
│ results: . │
│ }') │
│ │
│ - echo "$finalResult" | tee "${struct │
│ uredOutput}.json" │
│ + echo "$finalResult" | jq -c '.' | t │
│ ee "${structuredOutput}.json" │
│ │
│ # copy to web public directory for │
│ web frontend │
│ - # Find the repo root by looking for │
│ flake.nix │
│ + # find the repo root by looking for │
│ flake.nix │
│ repo_root="" │
│ current_dir="$PWD" │
│ while [[ "$current_dir" != "/" ]]; │
│ do │
│ @@ -459,14 +450,12 @@ │
│ mkdir -p "$rankings_dir" │
│ mkdir -p "$archive_dir" │
│ │
│ - # Archive existing file if it exist │
│ s │
│ if [[ -f "$existing_file" ]]; then │
│ timestamp=$(date +"%Y%m%d_%H%M%S" │
│ ) │
│ archived_name="${structuredOutput │
│ }_$timestamp.json" │
│ cp "$existing_file" "$archive_dir │
│ /$archived_name" │
│ echo "Archived existing file: $ar │
│ chived_name" │
│ │
│ - # Generate changelog by comparing │
│ with archived version │
│ echo "Generating changelog..." │
│ changes=$(echo "$finalResult" | j │
│ q --slurpfile archived "$existing_file" ' │
│ .results as $current | │
│ @@ -497,7 +486,6 @@ │
│ echo "Found $change_count DPS c │
│ hanges:" │
│ echo "$changes" | jq -r '.[] | │
│ " \(.class)/\(.spec): \(if .absolute_change │
│ > 0 then "+" else "" end)\(.absolute_change │
│ ) DPS (\(if .percent_change > 0 then "+" els │
│ e "" end)\(.percent_change)%)"' │
│ │
│ - # Update or create changelog │
│ changelog_file="$web_data_dir/c │
│ hangelog.json" │
│ if [[ -f "$changelog_file" ]]; │
│ then │
│ current_changelog=$(cat "$cha │
│ ngelog_file") │
└──────────────────────────────────────────────┘
┌─ nix/checks.nix ───────────────────────────────────────────────────────────┐
│ diff --git a/nix/checks.nix b/nix/checks.nix │
│ deleted file mode 100644 │
│ index f6a1e14..0000000 │
│ --- a/nix/checks.nix │
│ +++ /dev/null │
│ @@ -1,155 +0,0 @@ │
│ -{ │
│ - lib, │
│ - classes, │
│ - encounter, │
│ - buffs, │
│ - debuffs, │
│ - inputs, │
│ - ... │
│ -}: { │
│ - perSystem = {pkgs, ...}: let │
│ - inherit (lib.sim.simulation) mkSim; │
│ - │
│ - # Helper function to get all available class/spec combinations │
│ - getAllClassSpecs = classes: │
│ - lib.flatten (lib.mapAttrsToList (className: classSpecs: │
│ - lib.mapAttrsToList (specName: specConfigs: │
│ - if lib.hasAttr "template" specConfigs │
│ - && lib.hasAttr "p1" specConfigs.template │
│ - && lib.hasAttr "raid" specConfigs.template.p1 │
│ - && lib.hasAttr "singleTarget" specConfigs.template.p1.raid │
│ - then { inherit className specName; config = specConfigs.template.p1.rai │
│ d.singleTarget; } │
│ - else null │
│ - ) classSpecs │
│ - ) classes); │
│ - │
│ - # Filter out null values │
│ - availableSpecs = lib.filter (x: x != null) (getAllClassSpecs classes); │
│ - │
│ - # Create test simulation for a given spec │
│ - createSpecTest = {className, specName, config}: let │
│ - testSim = mkSim { │
│ - requestId = "test-${className}-${specName}"; │
│ - iterations = 100; # Smaller iteration count for faster testing │
│ - player = config; │
│ - buffs = buffs.full; │
│ - debuffs = debuffs.full; │
│ - encounter = encounter.raid.long.singleTarget; │
│ - }; │
│ - │
│ - testScript = pkgs.writeShellScript "test-${className}-${specName}" '' │
│ - set -euo pipefail │
│ - │
│ - echo "Testing ${className}/${specName}..." │
│ - │
│ - # Generate input file │
│ - cat > input.json << 'EOF' │
│ - ${testSim} │
│ - EOF │
│ - │
│ - # Run simulation │
│ - if ! wowsimcli sim --infile input.json --outfile output.json; then │
│ - echo "ERROR: wowsimcli failed for ${className}/${specName}" │
│ - exit 1 │
│ - fi │
│ - │
│ - # Validate output │
│ - if [ ! -f output.json ]; then │
│ - echo "ERROR: No output file generated for ${className}/${specName}" │
│ - exit 1 │
│ - fi │
│ - │
│ - # Check DPS value exists and is reasonable │
│ - avgDps=$(jq -r '.raidMetrics.dps.avg // "null"' output.json) │
│ - if [ "$avgDps" = "null" ]; then │
│ - echo "ERROR: No DPS value found for ${className}/${specName}" │
│ - exit 1 │
│ - fi │
│ - │
│ - # Basic sanity check - DPS should be positive and reasonable (>1000) │
│ - # But let's debug what we're getting first │
│ - echo "DEBUG: Raw DPS value: '$avgDps'" │
│ - │
│ - if [ "$(echo "$avgDps <= 0" | bc -l)" = "1" ]; then │
│ - echo "ERROR: DPS too low or zero ($avgDps) for ${className}/${specName} │
│ " │
│ - echo "DEBUG: Full output:" │
│ - jq '.' output.json | head -20 │
│ - exit 1 │
│ - fi │
│ - │
│ - echo "SUCCESS: ${className}/${specName} - DPS: $avgDps" │
│ - rm -f input.json output.json │
│ - ''; │
│ - in testScript; │
│ - │
│ - # Create individual tests for each spec │
│ - specTests = lib.listToAttrs (map (spec: { │
│ - name = "${spec.className}-${spec.specName}"; │
│ - value = createSpecTest spec; │
│ - }) availableSpecs); │
│ - │
│ - # Create combined test that runs all specs │
│ - allSpecsTest = pkgs.writeShellScript "test-all-specs" '' │
│ - set -euo pipefail │
│ - │
│ - echo "Running WoW simulation tests for all available specs..." │
│ - echo "Found ${toString (lib.length availableSpecs)} specs to test" │
│ - echo "" │
│ - │
│ - failed_tests=() │
│ - │
│ - ${lib.concatMapStringsSep "\n" (spec: '' │
│ - if ! ${createSpecTest spec}; then │
│ - failed_tests+=("${spec.className}/${spec.specName}") │
│ - fi │
│ - '') availableSpecs} │
│ - │
│ - echo "" │
│ - if [ ''${#failed_tests[@]} -eq 0 ]; then │
│ - echo "? All ${toString (lib.length availableSpecs)} specs passed!" │
│ - exit 0 │
│ - else │
│ - echo "? ''${#failed_tests[@]} specs failed:" │
│ - printf '%s\n' "''${failed_tests[@]}" │
│ - exit 1 │
│ - fi │
│ - ''; │
│ - │
│ - in { │
│ - checks = { │
│ - # Individual spec tests │
│ - } // specTests // { │
│ - # Combined test │
│ - all-specs = pkgs.runCommand "test-all-specs" { │
│ - buildInputs = [ │
│ - pkgs.jq │
│ - pkgs.bc │
│ - inputs.wowsims.packages.${pkgs.system}.wowsimcli │
│ - ]; │
│ - } '' │
│ - cd $TMPDIR │
│ - ${allSpecsTest} │
│ - touch $out │
│ - ''; │
│ - │
│ - # Quick test with just a few representative specs │
│ - smoke-test = pkgs.runCommand "smoke-test" { │
│ - buildInputs = [ │
│ - pkgs.jq │
│ - pkgs.bc │
│ - inputs.wowsims.packages.${pkgs.system}.wowsimcli │
│ - ]; │
│ - } '' │
│ - cd $TMPDIR │
│ - echo "Running smoke test with a few representative specs..." │
│ - │
│ - ${lib.concatMapStringsSep "\n" (spec: │
│ - "${createSpecTest spec}" │
│ - ) (lib.take 3 availableSpecs)} │
│ - │
│ - echo "? Smoke test passed!" │
│ - touch $out │
│ - ''; │
│ - }; │
│ - }; │
│ -} │
│ \ No newline at end of file │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/checks.nix ─────────────────────┐
│ diff --git a/nix/checks.nix b/nix/checks.nix │
│ deleted file mode 100644 │
│ index f6a1e14..0000000 │
│ --- a/nix/checks.nix │
│ +++ /dev/null │
│ @@ -1,155 +0,0 @@ │
│ -{ │
│ - lib, │
│ - classes, │
│ - encounter, │
│ - buffs, │
│ - debuffs, │
│ - inputs, │
│ - ... │
│ -}: { │
│ - perSystem = {pkgs, ...}: let │
│ - inherit (lib.sim.simulation) mkSim; │
│ - │
│ - # Helper function to get all available │
│ class/spec combinations │
│ - getAllClassSpecs = classes: │
│ - lib.flatten (lib.mapAttrsToList (clas │
│ sName: classSpecs: │
│ - lib.mapAttrsToList (specName: specC │
│ onfigs: │
│ - if lib.hasAttr "template" specCon │
│ figs │
│ - && lib.hasAttr "p1" specConfig │
│ s.template │
│ - && lib.hasAttr "raid" specConf │
│ igs.template.p1 │
│ - && lib.hasAttr "singleTarget" │
│ specConfigs.template.p1.raid │
│ - then { inherit className specName │
│ ; config = specConfigs.template.p1.raid.sing │
│ leTarget; } │
│ - else null │
│ - ) classSpecs │
│ - ) classes); │
│ - │
│ - # Filter out null values │
│ - availableSpecs = lib.filter (x: x != nu │
│ ll) (getAllClassSpecs classes); │
│ - │
│ - # Create test simulation for a given sp │
│ ec │
│ - createSpecTest = {className, specName, │
│ config}: let │
│ - testSim = mkSim { │
│ - requestId = "test-${className}-${sp │
│ ecName}"; │
│ - iterations = 100; # Smaller iterati │
│ on count for faster testing │
│ - player = config; │
│ - buffs = buffs.full; │
│ - debuffs = debuffs.full; │
│ - encounter = encounter.raid.long.sin │
│ gleTarget; │
│ - }; │
│ - │
│ - testScript = pkgs.writeShellScript "t │
│ est-${className}-${specName}" '' │
│ - set -euo pipefail │
│ - │
│ - echo "Testing ${className}/${specNa │
│ me}..." │
│ - │
│ - # Generate input file │
│ - cat > input.json << 'EOF' │
│ - ${testSim} │
│ - EOF │
│ - │
│ - # Run simulation │
│ - if ! wowsimcli sim --infile input.j │
│ son --outfile output.json; then │
│ - echo "ERROR: wowsimcli failed for │
│ ${className}/${specName}" │
│ - exit 1 │
│ - fi │
│ - │
│ - # Validate output │
│ - if [ ! -f output.json ]; then │
│ - echo "ERROR: No output file gener │
│ ated for ${className}/${specName}" │
│ - exit 1 │
│ - fi │
│ - │
│ - # Check DPS value exists and is rea │
│ sonable │
│ - avgDps=$(jq -r '.raidMetrics.dps.av │
│ g // "null"' output.json) │
│ - if [ "$avgDps" = "null" ]; then │
│ - echo "ERROR: No DPS value found f │
│ or ${className}/${specName}" │
│ - exit 1 │
│ - fi │
│ - │
│ - # Basic sanity check - DPS should b │
│ e positive and reasonable (>1000) │
│ - # But let's debug what we're gettin │
│ g first │
│ - echo "DEBUG: Raw DPS value: '$avgDp │
│ s'" │
│ - │
│ - if [ "$(echo "$avgDps <= 0" | bc -l │
│ )" = "1" ]; then │
│ - echo "ERROR: DPS too low or zero │
│ ($avgDps) for ${className}/${specName}" │
│ - echo "DEBUG: Full output:" │
│ - jq '.' output.json | head -20 │
│ - exit 1 │
│ - fi │
│ - │
│ - echo "SUCCESS: ${className}/${specN │
│ ame} - DPS: $avgDps" │
│ - rm -f input.json output.json │
│ - ''; │
│ - in testScript; │
│ - │
│ - # Create individual tests for each spec │
│ - specTests = lib.listToAttrs (map (spec: │
│ { │
│ - name = "${spec.className}-${spec.spec │
│ Name}"; │
│ - value = createSpecTest spec; │
│ - }) availableSpecs); │
│ - │
│ - # Create combined test that runs all sp │
│ ecs │
│ - allSpecsTest = pkgs.writeShellScript "t │
│ est-all-specs" '' │
│ - set -euo pipefail │
│ - │
│ - echo "Running WoW simulation tests fo │
│ r all available specs..." │
│ - echo "Found ${toString (lib.length av │
│ ailableSpecs)} specs to test" │
│ - echo "" │
│ - │
│ - failed_tests=() │
│ - │
│ - ${lib.concatMapStringsSep "\n" (spec: │
│ '' │
│ - if ! ${createSpecTest spec}; then │
│ - failed_tests+=("${spec.className} │
│ /${spec.specName}") │
│ - fi │
│ - '') availableSpecs} │
│ - │
│ - echo "" │
│ - if [ ''${#failed_tests[@]} -eq 0 ]; t │
│ hen │
│ - echo "? All ${toString (lib.length │
│ availableSpecs)} specs passed!" │
│ - exit 0 │
│ - else │
│ - echo "? ''${#failed_tests[@]} specs │
│ failed:" │
│ - printf '%s\n' "''${failed_tests[@]} │
│ " │
│ - exit 1 │
│ - fi │
│ - ''; │
│ - │
│ - in { │
│ - checks = { │
│ - # Individual spec tests │
│ - } // specTests // { │
│ - # Combined test │
│ - all-specs = pkgs.runCommand "test-all │
│ -specs" { │
│ - buildInputs = [ │
│ - pkgs.jq │
│ - pkgs.bc │
│ - inputs.wowsims.packages.${pkgs.sy │
│ stem}.wowsimcli │
│ - ]; │
│ - } '' │
│ - cd $TMPDIR │
│ - ${allSpecsTest} │
│ - touch $out │
│ - ''; │
│ - │
│ - # Quick test with just a few represen │
│ tative specs │
│ - smoke-test = pkgs.runCommand "smoke-t │
│ est" { │
│ - buildInputs = [ │
│ - pkgs.jq │
│ - pkgs.bc │
│ - inputs.wowsims.packages.${pkgs.sy │
│ stem}.wowsimcli │
│ - ]; │
│ - } '' │
│ - cd $TMPDIR │
│ - echo "Running smoke test with a few │
│ representative specs..." │
│ - │
│ - ${lib.concatMapStringsSep "\n" (spe │
│ c: │
│ - "${createSpecTest spec}" │
│ - ) (lib.take 3 availableSpecs)} │
│ - │
│ - echo "? Smoke test passed!" │
│ - touch $out │
│ - ''; │
│ - }; │
│ - }; │
│ -} │
│ \ No newline at end of file │
└──────────────────────────────────────────────┘
┌─ nix/classes/death_knight/blood.nix ───────────────────────────────────────┐
│ diff --git a/nix/classes/death_knight/blood.nix b/nix/classes/death_knight/blood.n │
│ ix │
│ index b05ea50..e1c68c6 100644 │
│ --- a/nix/classes/death_knight/blood.nix │
│ +++ b/nix/classes/death_knight/blood.nix │
│ @@ -53,4 +53,4 @@ │
│ }; │
│ }; │
│ in │
│ - blood │
│ \ No newline at end of file │
│ + blood │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ ...lasses/death_knight/blood.nix ───┐
│ diff --git a/nix/classes/death_knight/blood. │
│ nix b/nix/classes/death_knight/blood.nix │
│ index b05ea50..e1c68c6 100644 │
│ --- a/nix/classes/death_knight/blood.nix │
│ +++ b/nix/classes/death_knight/blood.nix │
│ @@ -53,4 +53,4 @@ │
│ }; │
│ }; │
│ in │
│ - blood │
│ \ No newline at end of file │
│ + blood │
└──────────────────────────────────────────────┘
┌─ nix/classes/death_knight/default.nix ─────────────────────────────────────┐
│ diff --git a/nix/classes/death_knight/default.nix b/nix/classes/death_knight/defau │
│ lt.nix │
│ index efb9a20..9892eba 100644 │
│ --- a/nix/classes/death_knight/default.nix │
│ +++ b/nix/classes/death_knight/default.nix │
│ @@ -21,4 +21,3 @@ │
│ unholy = import ./unholy.nix {inherit lib consumables;}; │
│ # blood = import ./blood.nix {inherit lib consumables;}; │
│ } │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ ...sses/death_knight/default.nix ───┐
│ diff --git a/nix/classes/death_knight/defaul │
│ t.nix b/nix/classes/death_knight/default.nix │
│ index efb9a20..9892eba 100644 │
│ --- a/nix/classes/death_knight/default.nix │
│ +++ b/nix/classes/death_knight/default.nix │
│ @@ -21,4 +21,3 @@ │
│ unholy = import ./unholy.nix {inherit lib │
│ consumables;}; │
│ # blood = import ./blood.nix {inherit lib │
│ consumables;}; │
│ } │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/classes/druid/feral.nix ──────────────────────────────────────────────┐
│ diff --git a/nix/classes/druid/feral.nix b/nix/classes/druid/feral.nix │
│ index 055e05e..2b40aef 100644 │
│ --- a/nix/classes/druid/feral.nix │
│ +++ b/nix/classes/druid/feral.nix │
│ @@ -22,12 +22,11 @@ │
│ options = {}; │
│ inherit race gearset talents apl consumables profession1 profession2 distan │
│ ceFromTarget; │
│ glyphs = { │
│ - major1 = 54812; # Rip │
│ + major1 = 54812; │
│ }; │
│ }; │
│ │
│ feral = { │
│ - # Talent configurations │
│ talents = { │
│ primal = "321232"; │
│ }; │
│ @@ -67,4 +66,3 @@ │
│ }; │
│ in │
│ feral │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/druid/feral.nix ────────┐
│ diff --git a/nix/classes/druid/feral.nix b/n │
│ ix/classes/druid/feral.nix │
│ index 055e05e..2b40aef 100644 │
│ --- a/nix/classes/druid/feral.nix │
│ +++ b/nix/classes/druid/feral.nix │
│ @@ -22,12 +22,11 @@ │
│ options = {}; │
│ inherit race gearset talents apl cons │
│ umables profession1 profession2 distanceFrom │
│ Target; │
│ glyphs = { │
│ - major1 = 54812; # Rip │
│ + major1 = 54812; │
│ }; │
│ }; │
│ │
│ feral = { │
│ - # Talent configurations │
│ talents = { │
│ primal = "321232"; │
│ }; │
│ @@ -67,4 +66,3 @@ │
│ }; │
│ in │
│ feral │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/classes/druid/guardian.nix ───────────────────────────────────────────┐
│ diff --git a/nix/classes/druid/guardian.nix b/nix/classes/druid/guardian.nix │
│ index 9e3f98e..a42e2f9 100644 │
│ --- a/nix/classes/druid/guardian.nix │
│ +++ b/nix/classes/druid/guardian.nix │
│ @@ -26,17 +26,15 @@ │
│ }; │
│ inherit race gearset talents apl consumables profession1 profession2 distan │
│ ceFromTarget; │
│ glyphs = { │
│ - major1 = 94390; # frenzied regeneration │
│ - major2 = 40897; # maul │
│ - major3 = 54818; # survival instincts │
│ + major1 = 94390; │
│ + major2 = 40897; │
│ + major3 = 54818; │
│ }; │
│ }; │
│ │
│ guardian = { │
│ - # Talent configurations │
│ + # talent configurations │
│ talents = { │
│ - incarnation = "312122"; │
│ - heartOfTheWild = "312112"; │
│ }; │
│ │
│ p1 = { │
│ @@ -51,4 +49,4 @@ │
│ }; │
│ }; │
│ in │
│ - guardian │
│ \ No newline at end of file │
│ + guardian │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/druid/guardian.nix ─────┐
│ diff --git a/nix/classes/druid/guardian.nix │
│ b/nix/classes/druid/guardian.nix │
│ index 9e3f98e..a42e2f9 100644 │
│ --- a/nix/classes/druid/guardian.nix │
│ +++ b/nix/classes/druid/guardian.nix │
│ @@ -26,17 +26,15 @@ │
│ }; │
│ inherit race gearset talents apl cons │
│ umables profession1 profession2 distanceFrom │
│ Target; │
│ glyphs = { │
│ - major1 = 94390; # frenzied regenera │
│ tion │
│ - major2 = 40897; # maul │
│ - major3 = 54818; # survival instinct │
│ s │
│ + major1 = 94390; │
│ + major2 = 40897; │
│ + major3 = 54818; │
│ }; │
│ }; │
│ │
│ guardian = { │
│ - # Talent configurations │
│ + # talent configurations │
│ talents = { │
│ - incarnation = "312122"; │
│ - heartOfTheWild = "312112"; │
│ }; │
│ │
│ p1 = { │
│ @@ -51,4 +49,4 @@ │
│ }; │
│ }; │
│ in │
│ - guardian │
│ \ No newline at end of file │
│ + guardian │
└──────────────────────────────────────────────┘
┌─ nix/classes/mage/default.nix ─────────────────────────────────────────────┐
│ diff --git a/nix/classes/mage/default.nix b/nix/classes/mage/default.nix │
│ index 5e5280d..e54a263 100644 │
│ --- a/nix/classes/mage/default.nix │
│ +++ b/nix/classes/mage/default.nix │
│ @@ -21,4 +21,3 @@ │
│ fire = import ./fire.nix {inherit lib consumables;}; │
│ frost = import ./frost.nix {inherit lib consumables;}; │
│ } │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/mage/default.nix ───────┐
│ diff --git a/nix/classes/mage/default.nix b/ │
│ nix/classes/mage/default.nix │
│ index 5e5280d..e54a263 100644 │
│ --- a/nix/classes/mage/default.nix │
│ +++ b/nix/classes/mage/default.nix │
│ @@ -21,4 +21,3 @@ │
│ fire = import ./fire.nix {inherit lib con │
│ sumables;}; │
│ frost = import ./frost.nix {inherit lib c │
│ onsumables;}; │
│ } │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/classes/monk/brewmaster.nix ──────────────────────────────────────────┐
│ diff --git a/nix/classes/monk/brewmaster.nix b/nix/classes/monk/brewmaster.nix │
│ index 9f08134..f07b22b 100644 │
│ --- a/nix/classes/monk/brewmaster.nix │
│ +++ b/nix/classes/monk/brewmaster.nix │
│ @@ -34,8 +34,8 @@ │
│ brewmaster = { │
│ # Talent configurations │
│ talents = { │
│ - xuen = "213322"; # Single target build with Xuen │
│ - rjw = "233321"; # AoE build with RJW │
│ + xuen = "213322"; │
│ + rjw = "233321"; │
│ }; │
│ │
│ glyphs = { │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/monk/brewmaster.nix ────┐
│ diff --git a/nix/classes/monk/brewmaster.nix │
│ b/nix/classes/monk/brewmaster.nix │
│ index 9f08134..f07b22b 100644 │
│ --- a/nix/classes/monk/brewmaster.nix │
│ +++ b/nix/classes/monk/brewmaster.nix │
│ @@ -34,8 +34,8 @@ │
│ brewmaster = { │
│ # Talent configurations │
│ talents = { │
│ - xuen = "213322"; # Single target buil │
│ d with Xuen │
│ - rjw = "233321"; # AoE build with RJW │
│ + xuen = "213322"; │
│ + rjw = "233321"; │
│ }; │
│ │
│ glyphs = { │
└──────────────────────────────────────────────┘
┌─ nix/classes/monk/windwalker.nix ──────────────────────────────────────────┐
│ diff --git a/nix/classes/monk/windwalker.nix b/nix/classes/monk/windwalker.nix │
│ index eac0d91..ecd4884 100644 │
│ --- a/nix/classes/monk/windwalker.nix │
│ +++ b/nix/classes/monk/windwalker.nix │
│ @@ -10,8 +10,8 @@ │
│ defaultRace = "orc"; │
│ │
│ talents = { │
│ - xuen = "213322"; # Single target build with Xuen │
│ - rjw = "233321"; # AoE build with RJW │
│ + xuen = "213322"; │
│ + rjw = "233321"; │
│ }; │
│ │
│ glyphs = { │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/monk/windwalker.nix ────┐
│ diff --git a/nix/classes/monk/windwalker.nix │
│ b/nix/classes/monk/windwalker.nix │
│ index eac0d91..ecd4884 100644 │
│ --- a/nix/classes/monk/windwalker.nix │
│ +++ b/nix/classes/monk/windwalker.nix │
│ @@ -10,8 +10,8 @@ │
│ defaultRace = "orc"; │
│ │
│ talents = { │
│ - xuen = "213322"; # Single target buil │
│ d with Xuen │
│ - rjw = "233321"; # AoE build with RJW │
│ + xuen = "213322"; │
│ + rjw = "233321"; │
│ }; │
│ │
│ glyphs = { │
└──────────────────────────────────────────────┘
┌─ nix/classes/paladin/default.nix ──────────────────────────────────────────┐
│ diff --git a/nix/classes/paladin/default.nix b/nix/classes/paladin/default.nix │
│ index e64ce9b..1685639 100644 │
│ --- a/nix/classes/paladin/default.nix │
│ +++ b/nix/classes/paladin/default.nix │
│ @@ -14,4 +14,3 @@ │
│ retribution = import ./retribution.nix {inherit lib consumables;}; │
│ # protection = import ./protection.nix {inherit lib consumables;}; │
│ } │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/paladin/default.nix ────┐
│ diff --git a/nix/classes/paladin/default.nix │
│ b/nix/classes/paladin/default.nix │
│ index e64ce9b..1685639 100644 │
│ --- a/nix/classes/paladin/default.nix │
│ +++ b/nix/classes/paladin/default.nix │
│ @@ -14,4 +14,3 @@ │
│ retribution = import ./retribution.nix {i │
│ nherit lib consumables;}; │
│ # protection = import ./protection.nix {i │
│ nherit lib consumables;}; │
│ } │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/classes/paladin/protection.nix ───────────────────────────────────────┐
│ diff --git a/nix/classes/paladin/protection.nix b/nix/classes/paladin/protection.n │
│ ix │
│ index 11f5071..792ff3a 100644 │
│ --- a/nix/classes/paladin/protection.nix │
│ +++ b/nix/classes/paladin/protection.nix │
│ @@ -27,13 +27,12 @@ │
│ inherit race gearset talents apl consumables profession1 profession2 distan │
│ ceFromTarget; │
│ glyphs = { │
│ major1 = 41101; # consecration │
│ - major2 = 54928; # hammer of the righteous │
│ + major2 = 54928; # hammer of the righteous │
│ major3 = 54927; # focused shield │
│ }; │
│ }; │
│ │
│ protection = { │
│ - # Talent configurations │
│ talents = { │
│ hammer = "311111"; │
│ zealotry = "311121"; │
│ @@ -51,4 +50,4 @@ │
│ }; │
│ }; │
│ in │
│ - protection │
│ \ No newline at end of file │
│ + protection │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ ...lasses/paladin/protection.nix ───┐
│ diff --git a/nix/classes/paladin/protection. │
│ nix b/nix/classes/paladin/protection.nix │
│ index 11f5071..792ff3a 100644 │
│ --- a/nix/classes/paladin/protection.nix │
│ +++ b/nix/classes/paladin/protection.nix │
│ @@ -27,13 +27,12 @@ │
│ inherit race gearset talents apl cons │
│ umables profession1 profession2 distanceFrom │
│ Target; │
│ glyphs = { │
│ major1 = 41101; # consecration │
│ - major2 = 54928; # hammer of the rig │
│ hteous │
│ + major2 = 54928; # hammer of the rig │
│ hteous │
│ major3 = 54927; # focused shield │
│ }; │
│ }; │
│ │
│ protection = { │
│ - # Talent configurations │
│ talents = { │
│ hammer = "311111"; │
│ zealotry = "311121"; │
│ @@ -51,4 +50,4 @@ │
│ }; │
│ }; │
│ in │
│ - protection │
│ \ No newline at end of file │
│ + protection │
└──────────────────────────────────────────────┘
┌─ nix/classes/priest/default.nix ───────────────────────────────────────────┐
│ diff --git a/nix/classes/priest/default.nix b/nix/classes/priest/default.nix │
│ index 77ea529..dfa3bf7 100644 │
│ --- a/nix/classes/priest/default.nix │
│ +++ b/nix/classes/priest/default.nix │
│ @@ -19,4 +19,3 @@ │
│ ]; │
│ shadow = import ./shadow.nix {inherit lib consumables;}; │
│ } │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/priest/default.nix ─────┐
│ diff --git a/nix/classes/priest/default.nix │
│ b/nix/classes/priest/default.nix │
│ index 77ea529..dfa3bf7 100644 │
│ --- a/nix/classes/priest/default.nix │
│ +++ b/nix/classes/priest/default.nix │
│ @@ -19,4 +19,3 @@ │
│ ]; │
│ shadow = import ./shadow.nix {inherit lib │
│ consumables;}; │
│ } │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/classes/rogue/default.nix ────────────────────────────────────────────┐
│ diff --git a/nix/classes/rogue/default.nix b/nix/classes/rogue/default.nix │
│ index 6c24604..8bba83e 100644 │
│ --- a/nix/classes/rogue/default.nix │
│ +++ b/nix/classes/rogue/default.nix │
│ @@ -20,4 +20,3 @@ │
│ combat = import ./combat.nix {inherit lib consumables;}; │
│ subtlety = import ./subtlety.nix {inherit lib consumables;}; │
│ } │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/rogue/default.nix ──────┐
│ diff --git a/nix/classes/rogue/default.nix b │
│ /nix/classes/rogue/default.nix │
│ index 6c24604..8bba83e 100644 │
│ --- a/nix/classes/rogue/default.nix │
│ +++ b/nix/classes/rogue/default.nix │
│ @@ -20,4 +20,3 @@ │
│ combat = import ./combat.nix {inherit lib │
│ consumables;}; │
│ subtlety = import ./subtlety.nix {inherit │
│ lib consumables;}; │
│ } │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/classes/shaman/default.nix ───────────────────────────────────────────┐
│ diff --git a/nix/classes/shaman/default.nix b/nix/classes/shaman/default.nix │
│ index fbb3798..4448c61 100644 │
│ --- a/nix/classes/shaman/default.nix │
│ +++ b/nix/classes/shaman/default.nix │
│ @@ -15,4 +15,3 @@ │
│ elemental = import ./elemental.nix {inherit lib consumables;}; │
│ enhancement = import ./enhancement.nix {inherit lib consumables;}; │
│ } │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/shaman/default.nix ─────┐
│ diff --git a/nix/classes/shaman/default.nix │
│ b/nix/classes/shaman/default.nix │
│ index fbb3798..4448c61 100644 │
│ --- a/nix/classes/shaman/default.nix │
│ +++ b/nix/classes/shaman/default.nix │
│ @@ -15,4 +15,3 @@ │
│ elemental = import ./elemental.nix {inher │
│ it lib consumables;}; │
│ enhancement = import ./enhancement.nix {i │
│ nherit lib consumables;}; │
│ } │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/classes/warlock/default.nix ──────────────────────────────────────────┐
│ diff --git a/nix/classes/warlock/default.nix b/nix/classes/warlock/default.nix │
│ index 6eae7f1..3c86bbf 100644 │
│ --- a/nix/classes/warlock/default.nix │
│ +++ b/nix/classes/warlock/default.nix │
│ @@ -18,4 +18,3 @@ │
│ demonology = import ./demonology.nix {inherit lib consumables;}; │
│ destruction = import ./destruction.nix {inherit lib consumables;}; │
│ } │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/warlock/default.nix ────┐
│ diff --git a/nix/classes/warlock/default.nix │
│ b/nix/classes/warlock/default.nix │
│ index 6eae7f1..3c86bbf 100644 │
│ --- a/nix/classes/warlock/default.nix │
│ +++ b/nix/classes/warlock/default.nix │
│ @@ -18,4 +18,3 @@ │
│ demonology = import ./demonology.nix {inh │
│ erit lib consumables;}; │
│ destruction = import ./destruction.nix {i │
│ nherit lib consumables;}; │
│ } │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/classes/warrior/default.nix ──────────────────────────────────────────┐
│ diff --git a/nix/classes/warrior/default.nix b/nix/classes/warrior/default.nix │
│ index 0ea0740..c4aef9f 100644 │
│ --- a/nix/classes/warrior/default.nix │
│ +++ b/nix/classes/warrior/default.nix │
│ @@ -23,4 +23,3 @@ │
│ fury = import ./fury.nix {inherit lib consumables;}; │
│ # protection = import ./protection.nix {inherit lib consumables;}; │
│ } │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/classes/warrior/default.nix ────┐
│ diff --git a/nix/classes/warrior/default.nix │
│ b/nix/classes/warrior/default.nix │
│ index 0ea0740..c4aef9f 100644 │
│ --- a/nix/classes/warrior/default.nix │
│ +++ b/nix/classes/warrior/default.nix │
│ @@ -23,4 +23,3 @@ │
│ fury = import ./fury.nix {inherit lib con │
│ sumables;}; │
│ # protection = import ./protection.nix {i │
│ nherit lib consumables;}; │
│ } │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/classes/warrior/protection.nix ───────────────────────────────────────┐
│ diff --git a/nix/classes/warrior/protection.nix b/nix/classes/warrior/protection.n │
│ ix │
│ index f932927..7392ddc 100644 │
│ --- a/nix/classes/warrior/protection.nix │
│ +++ b/nix/classes/warrior/protection.nix │
│ @@ -26,17 +26,11 @@ │
│ }; │
│ inherit race gearset talents apl consumables profession1 profession2 distan │
│ ceFromTarget; │
│ glyphs = { │
│ - major1 = 58375; # shield slam │
│ - major2 = 58388; # revenge │
│ - major3 = 58387; # devastate │
│ }; │
│ }; │
│ │
│ protection = { │
│ - # Talent configurations │
│ talents = { │
│ - shockwave = "132112"; │
│ - dragonRoar = "132122"; │
│ }; │
│ │
│ p1 = { │
│ @@ -52,4 +46,3 @@ │
│ }; │
│ in │
│ protection │
│ - │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ ...lasses/warrior/protection.nix ───┐
│ diff --git a/nix/classes/warrior/protection. │
│ nix b/nix/classes/warrior/protection.nix │
│ index f932927..7392ddc 100644 │
│ --- a/nix/classes/warrior/protection.nix │
│ +++ b/nix/classes/warrior/protection.nix │
│ @@ -26,17 +26,11 @@ │
│ }; │
│ inherit race gearset talents apl cons │
│ umables profession1 profession2 distanceFrom │
│ Target; │
│ glyphs = { │
│ - major1 = 58375; # shield slam │
│ - major2 = 58388; # revenge │
│ - major3 = 58387; # devastate │
│ }; │
│ }; │
│ │
│ protection = { │
│ - # Talent configurations │
│ talents = { │
│ - shockwave = "132112"; │
│ - dragonRoar = "132122"; │
│ }; │
│ │
│ p1 = { │
│ @@ -52,4 +46,3 @@ │
│ }; │
│ in │
│ protection │
│ - │
└──────────────────────────────────────────────┘
┌─ nix/encounter/default.nix ────────────────────────────────────────────────┐
│ diff --git a/nix/encounter/default.nix b/nix/encounter/default.nix │
│ index 9922523..dfd8ccb 100644 │
│ --- a/nix/encounter/default.nix │
│ +++ b/nix/encounter/default.nix │
│ @@ -6,7 +6,6 @@ │
│ inherit (lib.sim.encounter) mkEncounter; │
│ inherit (lib) mapAttrs genList; │
│ │
│ - # Target count configurations │
│ targetConfigs = { │
│ singleTarget = [target.defaultRaidBoss]; │
│ cleave = [target.defaultRaidBoss target.defaultRaidBoss]; │
│ @@ -16,7 +15,6 @@ │
│ twentyTarget = genList (_: target.defaultRaidBoss) 20; │
│ }; │
│ │
│ - # Duration configurations │
│ durations = { │
│ long = { │
│ duration = 300; │
│ @@ -32,7 +30,6 @@ │
│ }; │
│ }; │
│ │
│ - # Generate encounters for a duration type │
│ mkDurationEncounters = durationConfig: │
│ mapAttrs ( │
│ name: targets: │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/encounter/default.nix ──────────┐
│ diff --git a/nix/encounter/default.nix b/nix │
│ /encounter/default.nix │
│ index 9922523..dfd8ccb 100644 │
│ --- a/nix/encounter/default.nix │
│ +++ b/nix/encounter/default.nix │
│ @@ -6,7 +6,6 @@ │
│ inherit (lib.sim.encounter) mkEncounter; │
│ inherit (lib) mapAttrs genList; │
│ │
│ - # Target count configurations │
│ targetConfigs = { │
│ singleTarget = [target.defaultRaidBoss] │
│ ; │
│ cleave = [target.defaultRaidBoss target │
│ .defaultRaidBoss]; │
│ @@ -16,7 +15,6 @@ │
│ twentyTarget = genList (_: target.defau │
│ ltRaidBoss) 20; │
│ }; │
│ │
│ - # Duration configurations │
│ durations = { │
│ long = { │
│ duration = 300; │
│ @@ -32,7 +30,6 @@ │
│ }; │
│ }; │
│ │
│ - # Generate encounters for a duration type │
│ mkDurationEncounters = durationConfig: │
│ mapAttrs ( │
│ name: targets: │
└──────────────────────────────────────────────┘
┌─ nix/lib/encounter.nix ────────────────────────────────────────────────────┐
│ diff --git a/nix/lib/encounter.nix b/nix/lib/encounter.nix │
│ index f1aba53..f66d916 100644 │
│ --- a/nix/lib/encounter.nix │
│ +++ b/nix/lib/encounter.nix │
│ @@ -1,5 +1,4 @@ │
│ let │
│ - # Base encounter template │
│ mkEncounter = { │
│ duration ? 300, │
│ durationVariation ? 60, │
│ @@ -15,5 +14,4 @@ let │
│ executeProportion45 = 0.45; │
│ executeProportion90 = 0.9; │
│ }; │
│ - # Duration-based encounter templates │
│ in {inherit mkEncounter;} │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/lib/encounter.nix ──────────────┐
│ diff --git a/nix/lib/encounter.nix b/nix/lib │
│ /encounter.nix │
│ index f1aba53..f66d916 100644 │
│ --- a/nix/lib/encounter.nix │
│ +++ b/nix/lib/encounter.nix │
│ @@ -1,5 +1,4 @@ │
│ let │
│ - # Base encounter template │
│ mkEncounter = { │
│ duration ? 300, │
│ durationVariation ? 60, │
│ @@ -15,5 +14,4 @@ let │
│ executeProportion45 = 0.45; │
│ executeProportion90 = 0.9; │
│ }; │
│ - # Duration-based encounter templates │
│ in {inherit mkEncounter;} │
└──────────────────────────────────────────────┘
┌─ nix/pkgs/testRaid.nix ────────────────────────────────────────────────────┐
│ diff --git a/nix/pkgs/testRaid.nix b/nix/pkgs/testRaid.nix │
│ index 3413a4c..a5d30e3 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 = "monk"; │
│ - spec = "windwalker"; │
│ + class = "warlock"; │
│ + spec = "demonology"; │
│ encounterType = "raid"; │
│ │
│ raid = mkSim { │
│ requestId = "raidSimAsync-f2cf5e22118a43c7"; │
│ iterations = 10000; │
│ - player = classes.${class}.${spec}.template.p1.${encounterType}.singleTarget; │
│ + player = classes.${class}.${spec}.template.troll.p1.${encounterType}.multiTar │
│ get; │
│ buffs = buffs.full; │
│ debuffs = debuffs.full; │
│ - encounter = encounter.${encounterType}.long.singleTarget; │
│ + encounter = encounter.${encounterType}.long.threeTarget; │
│ }; │
│ testRaid = writeShellApplication { │
│ name = "testRaid"; │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/pkgs/testRaid.nix ──────────────┐
│ diff --git a/nix/pkgs/testRaid.nix b/nix/pkg │
│ s/testRaid.nix │
│ index 3413a4c..a5d30e3 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 = "monk"; │
│ - spec = "windwalker"; │
│ + class = "warlock"; │
│ + spec = "demonology"; │
│ encounterType = "raid"; │
│ │
│ raid = mkSim { │
│ requestId = "raidSimAsync-f2cf5e22118a4 │
│ 3c7"; │
│ iterations = 10000; │
│ - player = classes.${class}.${spec}.templ │
│ ate.p1.${encounterType}.singleTarget; │
│ + player = classes.${class}.${spec}.templ │
│ ate.troll.p1.${encounterType}.multiTarget; │
│ buffs = buffs.full; │
│ debuffs = debuffs.full; │
│ - encounter = encounter.${encounterType}. │
│ long.singleTarget; │
│ + encounter = encounter.${encounterType}. │
│ long.threeTarget; │
│ }; │
│ testRaid = writeShellApplication { │
│ name = "testRaid"; │
└──────────────────────────────────────────────┘
┌─ nix/target/default.nix ───────────────────────────────────────────────────┐
│ diff --git a/nix/target/default.nix b/nix/target/default.nix │
│ index 4de419a..b8d1d35 100644 │
│ --- a/nix/target/default.nix │
│ +++ b/nix/target/default.nix │
│ @@ -1,7 +1,16 @@ │
│ {lib, ...}: let │
│ inherit (lib.sim.target) mkTarget; │
│ target = { │
│ + # default raid boss from wowsims │
│ + # id 31146 │
│ + # level 93 │
│ + # mechanical │
│ + # 550000 base damage │
│ + # 0.4 damage spread │
│ + # 2 swing timer │
│ defaultRaidBoss = mkTarget {}; │
│ + │
│ + # modeled after the party monkeys in stormstout │
│ smallTrash = mkTarget { │
│ level = 90; │
│ minBaseDamage = 15000; │
└────────────────────────────────────────────────────────────────────────────────────┘
┌─ nix/target/default.nix ─────────────┐
│ diff --git a/nix/target/default.nix b/nix/ta │
│ rget/default.nix │
│ index 4de419a..b8d1d35 100644 │
│ --- a/nix/target/default.nix │
│ +++ b/nix/target/default.nix │
│ @@ -1,7 +1,16 @@ │
│ {lib, ...}: let │
│ inherit (lib.sim.target) mkTarget; │
│ target = { │
│ + # default raid boss from wowsims │
│ + # id 31146 │
│ + # level 93 │
│ + # mechanical │
│ + # 550000 base damage │
│ + # 0.4 damage spread │
│ + # 2 swing timer │
│ defaultRaidBoss = mkTarget {}; │
│ + │
│ + # modeled after the party monkeys in st │
│ ormstout │
│ smallTrash = mkTarget { │
│ level = 90; │
│ minBaseDamage = 15000; │
└──────────────────────────────────────────────┘
[ BACK TO LOG ]
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET