From 765c738c99e8eac2db78c934647cde1a2e448af0 Mon Sep 17 00:00:00 2001 From: prosolis <5590409+prosolis@users.noreply.github.com> Date: Fri, 15 May 2026 11:23:07 -0700 Subject: [PATCH] Phase 4b (rosters): per-zone outlier re-classification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 4-A's per-monster trace named one or two miscategorised entries on each of the four outlier zones — Phase 2c's single-boss-elite dilution pattern hadn't been applied uniformly, and several over-tier creatures were sitting on standard slots they couldn't carry. Roster changes (no monster stat-block touches — bestiary is shared): crypt_valdris (T1, 8.5% → 46.0%): Dropped flameskull (CR3, 68 kills — still in underforge T3 where its CR fits). Promoted specter to IsElite at SW=3 as the soft dilutor, mirroring Phase 2c's worg/owlbear shape so the elite bracket no longer auto-picks a one-shot. forest_shadows (T2, 0.0% → 7.5%): Standard pool was carrying two real killers — Displacer Beast (38% win) and Bandit Captain (57% win, 14hp loss/win). Both re-flagged IsElite; Owlbear SW cut 4→2 to keep the now-4-elite pool diluted instead of front-loading Owlbear (9% win) at 50% of elite rolls. Standards collapse to Dire Wolf + Dryad, matching sunken_temple's "all standards ≥90% win" floor. manor_blackspire (T3, 0.5% → 14.5%): Wraith was the dominant standard killer (85 attributed kills, 45hp loss per win) — too punishing for the standard slot. Promoted to IsElite; standard floor becomes Shadow+Poltergeist+Banshee (all ≥92% win in trace). abyss_portal (T5, 0.0% → 25.0%): Nalfeshnee was a CR-13 demon on a T5 standard slot (2.8% win, 86 kills); promoted to IsElite. Second pass: Vrock at 86% win as standard still bled 65 kills via 43hp/win attrition — promoted to elite too. Standard collapses to Quasit alone (99.9% win, 1.3hp loss), matching dragons_lair's near-zero standard-pool kill rate. Tier-level effect on the Phase 3-B (b=50, f=tier) sweep: T1: 26.8% → 44.0% (+17 pp) T2: 6.2% → 10.0% (+4) T3: 2.5% → 8.5% (+6) T4: 7.8% → 7.8% (no T4 outlier identified) T5: 27.5% → 41.0% (+14) Outliers are no longer outliers (forest_shadows 7.5% vs sibling 13% gap; abyss_portal 25% vs sibling 57.5%); the remaining T2/T3/T5 shortfall vs the target band (62-82%/54-74%/36-56%) is tier-wide — both zones at each problem tier sit below band, so a per-zone tool won't close it. Phase 4's exit condition ("all per-zone cells within band") is therefore conditioned on a follow-up tier-wide pass, but the per-zone bug-fix it was scoped to address is done. -short suite: same two pre-existing failures (TestAdv2Scenario_ZoneRunGoblinWarrens, TestMageSpellbookLineInRender). Co-Authored-By: Claude Opus 4.7 (1M context) --- internal/plugin/dnd_zone.go | 70 ++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/internal/plugin/dnd_zone.go b/internal/plugin/dnd_zone.go index 0902ed4..7d5a0c3 100644 --- a/internal/plugin/dnd_zone.go +++ b/internal/plugin/dnd_zone.go @@ -261,12 +261,21 @@ func zoneCryptValdris() ZoneDefinition { MinRooms: 6, MaxRooms: 7, Enemies: []ZoneEnemy{ + // Phase 4-B (outlier fix): the live roster was the only + // dual-killer-elite zone (wight + flameskull, both CR3+ on + // the T1 standards floor), so the InterruptElite bracket + // was effectively "pick your one-shot." Phase 2c skipped + // this zone because it was already dual-elite; Phase 4-A's + // per-monster trace caught the consequence (167/183 + // deaths attributed to those two). Flameskull dropped here + // (still in underforge T3 where its CR fits); specter + // promoted from standard to the soft-elite dilutor slot + // at SW=3, matching Phase 2c's worg/owlbear shape. {BestiaryID: "skeleton", SpawnWeight: 7}, {BestiaryID: "zombie", SpawnWeight: 6}, {BestiaryID: "shadow", SpawnWeight: 4}, - {BestiaryID: "specter", SpawnWeight: 3}, + {BestiaryID: "specter", SpawnWeight: 3, IsElite: true}, {BestiaryID: "wight", SpawnWeight: 1, IsElite: true}, - {BestiaryID: "flameskull", SpawnWeight: 1, IsElite: true}, }, Boss: ZoneBoss{ BestiaryID: "boss_valdris_unburied", @@ -308,11 +317,29 @@ func zoneForestShadows() ZoneDefinition { MinRooms: 6, MaxRooms: 8, Enemies: []ZoneEnemy{ + // Phase 4-B (outlier fix): standard pool was carrying two + // real killers — Displacer Beast (38% win as a standard + // pick) and Bandit Captain (57% win). Re-flag Displacer + // Beast as elite so it leaves the standard slot, joining + // Owlbear/Hag as a third elite for pool dilution; trim + // Bandit Captain SW so the soft Dire Wolf carries more of + // the standard roll mass. Boss + standards now match the + // sibling sunken_temple's lethality shape. + // + // Second pass: a first attempt (Displacer→elite alone) + // only moved comp 0% → 0.5%. Phase 4-A re-trace showed + // Bandit Captain still bleeding the standard pool (321 + // appearances, 54.8% win, 53 kills) and Owlbear monopolising + // the elite roll at SW=4. Promoted Captain to elite as + // well; cut Owlbear SW 4→2 so the 4-elite pool dilutes + // instead of front-loading Owlbear (9% win). Standard + // becomes Dire Wolf + Dryad, matching sunken_temple's + // "all standards ≥90% win" floor. {BestiaryID: "dire_wolf", SpawnWeight: 6}, - {BestiaryID: "bandit_captain", SpawnWeight: 4}, - {BestiaryID: "owlbear", SpawnWeight: 4, IsElite: true}, {BestiaryID: "dryad_corrupted", SpawnWeight: 3}, - {BestiaryID: "displacer_beast", SpawnWeight: 3}, + {BestiaryID: "owlbear", SpawnWeight: 2, IsElite: true}, + {BestiaryID: "bandit_captain", SpawnWeight: 3, IsElite: true}, + {BestiaryID: "displacer_beast", SpawnWeight: 3, IsElite: true}, {BestiaryID: "green_hag", SpawnWeight: 1, IsElite: true}, }, Boss: ZoneBoss{ @@ -399,10 +426,17 @@ func zoneManorBlackspire() ZoneDefinition { MinRooms: 7, MaxRooms: 9, Enemies: []ZoneEnemy{ + // Phase 4-B (outlier fix): Wraith was the dominant + // standard-pool killer (45 hp loss/win, 85 attributed + // kills in Phase 4-A) — too punishing for the standard + // slot at T3. Promoted to elite; Spawn+Wraith+Revenant + // becomes a 3-elite pool with balanced dilution, leaving + // Shadow/Poltergeist/Banshee as a clean standard floor + // (all ≥92% win in the trace). {BestiaryID: "shadow", SpawnWeight: 6}, {BestiaryID: "poltergeist", SpawnWeight: 5}, {BestiaryID: "banshee", SpawnWeight: 3}, - {BestiaryID: "wraith", SpawnWeight: 3}, + {BestiaryID: "wraith", SpawnWeight: 3, IsElite: true}, {BestiaryID: "vampire_spawn", SpawnWeight: 3, IsElite: true}, {BestiaryID: "revenant", SpawnWeight: 1, IsElite: true}, }, @@ -635,10 +669,30 @@ func zoneAbyssPortal() ZoneDefinition { MinRooms: 9, MaxRooms: 10, Enemies: []ZoneEnemy{ + // Phase 4-B (outlier fix): Nalfeshnee was mis-classified + // as a standard at T5 — Phase 4-A measured 2.8% win rate + // across 180 standard-pool picks, attributing 86 kills + // (43% of all deaths in the trace). Re-flagged as elite + // where its CR-13 stat block belongs; the new elite pool + // Hezrou+Nalfeshnee+Marilith mirrors the sibling + // dragons_lair's three-elite shape. Vrock SW shaved 5→4 + // so the soft Quasit (≥99% win) takes a larger share of + // the standard mass, since Vrock was the secondary + // standard killer (53 kills, 44hp loss/win). + // + // Second pass: a first attempt (Nalf→elite, Vrock SW 5→4) + // only moved comp 0% → 9%. Re-trace showed Vrock still + // dominant in the standard pool (1013 appearances, 86.3% + // win, but 43.6 hp loss per win → 65 kills via attrition). + // The sibling dragons_lair posts zero standard-pool kills; + // promoting Vrock to elite brings abyss in line. Standard + // floor collapses to Quasit alone, which is fine — Quasit + // posts ≥99.9% win in trace and the elite bracket + // triggers ~7% of rolls anyway. {BestiaryID: "quasit", SpawnWeight: 6}, - {BestiaryID: "vrock", SpawnWeight: 5}, + {BestiaryID: "vrock", SpawnWeight: 4, IsElite: true}, {BestiaryID: "hezrou", SpawnWeight: 4, IsElite: true}, - {BestiaryID: "nalfeshnee", SpawnWeight: 2}, + {BestiaryID: "nalfeshnee", SpawnWeight: 3, IsElite: true}, {BestiaryID: "marilith", SpawnWeight: 1, IsElite: true}, }, Boss: ZoneBoss{