# CHANGES

## 2026-11-02 (America/Chicago) — Naxx 20/25/30 + Hunter recal + boss cadence

### Multi-length Naxx sims
- Every build now evaluated at **1200 / 1500 / 1800 s** (20 / 25 / 30 min).
- Results include **mixed DPS**, **wave**, **boss**, and **total damage** (= mixed × T) per length.
- Site: CSS radio run-length selector (CSP `script-src 'none'` — no JS).
- Mix weights are **schedule-derived**: fight window = min(90s, boss_hp / boss_dps, gap to next); not fixed 70/30.

### Boss cadence
- **CONFIRMED** scheduled Naxx bosses every 4 min: Anub'Rekhan 4:00 (HP 4,600) · Noth 8:00 (11,500) · Patchwerk 12:00 (21,000) · Sapphiron 16:00 (26,000) · Kel'Thuzad 20:00 (58,500).
  Sources: azerothsurvivorsgame.com/zones/, azeroth-survivors.org/wiki/naxxramas/ (v0.139.2), AZS_GetUpcomingBosses / AZS_SCHEDULE.
- **ASSUMED** endless after 20:00 every 240s (Orion). Addon API has `AZS_RUN.nb` countdown but unpublished interval. Combat log + saved_runs neither confirmed nor contradicted.
- `boss_hp` default updated 8000 → **58500** (KT base).

### Hunter Kill Shot recalibration
- Source: `logs/saved_runs.json` unique Gates of Ahn'Qiraj L33 · 637.16s · **34,493 DPS** (NOT Naxx).
- Shares: Aimed 60.6% (3471 hits / 1768 crits) · Rapid Fire **23.8% proc** · Frost Trap 5.4% · Amulet Inferno Frost 1.4% · Multi 2.6% · Auto 2.5%.
- Old model folded RF into Aimed free-casts so RF own DPS ≈ 0. Now RF is an **explicit proc damage line** (RF/Aimed = 0.393 from meter).
- Kill Shot mixed @20 min: **9866.4 → 34562.3**.

### Files
- `lib/core.py` — Naxx schedule, mix_weights_for_length, run_average(run_length=…), set_run_length
- `lib/builds_whr.py` — hunter_kill_shot recalibrated
- `lib/builds_rest.py` — Mage Fire uses live `_core.RUN_LENGTH_SEC`
- `model.py` — multi-length output into `by_length`
- `render_site.py` — regenerates `site/index.html`

## 2026-11-02 (America/Chicago) — Combat-log calibration

### Parser
- Added `parse_log.py` over `logs/WoWCombatLog-snap` (1.5M lines, copy of Orion's WoW 1.12 log; PC file untouched).
- Splits runs on gaps >120s; infers class from spell damage; per-run duration, per-spell dmg/crit/avg/max, AoE targets via same-timestamp clusters, damage-over-time curve, pet damage.
- Outputs: `logs/parsed_runs.json`, `logs/parsed_summary.md`.

### Log coverage (kept runs ≥60s, ≥1k dmg)
- **69 runs** across Oct 21–30, 2026.
- Classes: Mage 29, Warlock 18, Warrior 12, Priest 4, Shaman 2, Druid 2, Hunter 1, Paladin 1.
- Flamestrike is the dominant `Your` damage line (~343k hits); then Hellfire, Rain of Fire, Shadow Bolt.

### Assumptions replaced
| Knob | Before (post-audit) | After (log-calibrated) | Source |
|---|---|---|---|
| Sim length | **1200s** (ASSUMED); originally **none**/steady-state | **1401s** | Median Mage run ≥10 min (23.35 min); mean 31.8 min |
| Wave density | **8** flat ASSUMED | **Ramp 12→80** (Mage Fire); flat **40** other classes | FS same-timestamp avg targets; FS-focused median ~103 (mega-packs capped) |
| Mage in-run crit | gear+talents only (~35%) | +`MAGE_EXTRA_CRIT_END=0.30` over run | Log FS crit median **63.2%** on FS-focused runs |

### Ranking impact (mixed DPS)
- Mage Inferno FS: **8375.6 → 56117.8** (AoE density + crit ramp; now #1 overall). Matches log late-run Mage player DPS often 20k–100k+.
- Other AoE (Bladestorm, Divine Storm, HotR, etc.) also rose with density=40; ST Kill Shot barely moved.
- ST/no-scaling bias check: classes that only had flat density=8 were undercounting multi-target; density=40 fixes the global bias. Full in-run card ramps still Mage-Fire-primary.

### Sim length reported
- **Before any audit:** none (steady-state).
- **After time-based audit, before log:** 1200s.
- **After log calibration:** 1401s.


# AZS DPS model audit changes (2026-11-02)

## Sim length
| | Before | After |
|---|---|---|
| Run / sim clock | **None** (steady-state Rank-1 Common; `in_run_cards: NOT modeled`) | **1200 s (20 min)** run-averaged progress `p=t/T` for Mage Fire focus builds; samples=21 |
| Other classes | Steady-state | Steady-state talents/sets, but channel/DoT base damage corrected; **spell-specific in-run cards still not fully modeled** (same late-run bias remains except Mage Fire) |

## Bugs fixed

### 1. Channel/DoT used per-tick `damage` instead of `damage_total`
- **Where:** `lib/core.py` `spell_dps` / `_base_damage`
- **Old:** Prefer `facts.damage` (e.g. Flamestrike 12.39 / tick)
- **New:** Prefer `facts.damage_total` when present (Flamestrike 49.56 full duration; metric notes `full_duration`)
- **Impact:** AoE channels (Flamestrike, Blizzard, Consecration, Rain of Fire, Volley, …) and DoTs with only `damage_total` were undercounted by ~duration/tick_interval (FS ≈ **4.0×**). Primary reason prior Mage undervalued Flamestrike (173 DPS vs thousands when set+Inferno modeled).

### 2. Mage Fire modeled Legendary Fireball set, omitted Inferno Flamestrike neck
- **Old winner:** Pyroclasm (Fire) mixed **3665.5** with Fireball 8x5* set; FS contribution **173.1**
- **New:** Enumerate both:
  - **Pyroclasm + Inferno Flamestrike** (Rare FS 8x5* second-hit 75% + Amulet of the Inferno: Flamestrike run upgrades) mixed **8375.6**
  - Pyroclasm + Fireball set (corrected) mixed **4824.4**
- **Also:** Blast Wave + Fire Blast now in rotation; Hot Streak counts all Fire casts; Ignite on FS; run-scaled legendary FS dmg/CDR path + second-hit card stacking.

### 3. Gear echo counted weapon as echo piece
- **Old:** `echo = 0.0336 * 8 = 0.2688`
- **New:** `echo = 0.0336 * 7 = 0.2352` (Sulfuras has no echo)
- **Impact:** ~2.7% less echo multiplier on all builds.

### 4. Execute set +30% crit damage applied cross-class
- **Old:** `GEAR.crit_dmg = 0.3091 + 0.30`
- **New:** `GEAR.crit_dmg = 0.3091`; Warrior Mortal Wounds adds `+0.30` for Execute set only
- **Impact:** Non-warrior crit multiplier down; Warrior Arms nearly unchanged.

### 5. Druid Force of Nature double-added free Starfire
- **Old:** two consecutive `sf += free * cast * …` lines
- **New:** single add
- **Impact:** Balance Druid mixed 5276.2 → 4577.5

### 6. dps0 path ignored `extra_targets`
- **Old:** extra_targets unused when falling back to dps0
- **New:** scale baseline by `min(density, tgt+extra)/tgt`
- **Impact:** Small buffs to remaining dps0-only edges.

## Before / after per-class best (mixed DPS)

| Class | Before best | Before mixed | After best | After mixed |
|---|---|---:|---|---:|
| Mage | Pyroclasm (Fire) | 3665.5 | Pyroclasm + Inferno Flamestrike | 8375.6 |
| Hunter | Kill Shot | 10796.6 | Kill Shot | 9840.1 |
| Warrior | Mortal Wounds | 6130.5 | Mortal Wounds | 5977.2 |
| Paladin | Hammer of the Righteous | 5511.6 | Divine Storm | 5176.8 |
| Druid | Force of Nature | 5276.2 | Force of Nature | 4577.5 |
| Rogue | Killing Spree | 4570.9 | Killing Spree | 4150.8 |
| Shaman | Elemental Mastery | 4068.1 | Elemental Mastery | 3935.3 |
| Warlock | Seed of Corruption | 2508.2 | Seed of Corruption | 4232.1 |
| Priest | Shadowform | 2354.2 | Shadowform | 3880.6 |

Paladin ranking flipped (HotR ↔ DS) from gear/channel corrections. Priest/Warlock rose from DoT `damage_total` path.

## Still assumed (not re-derived from combat log)
- Run length 1200s; Inferno card `{v}` schedule (legendary path count 0→5 + second-hit +1.25 by end)
- Cross-class Dreadnaught+Sulfuras gear template
- Kill rate 2/s wave; mob HP 400; boss HP 8000
- Pet/Water Elemental/Demon/Treant damage tables
- Non-Mage spell-specific in-run upgrade stacking
