mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Phase 2c (roster gate): dilute single-boss elite pools
Each zone's elite pool was a single SpawnWeight=1 over-tier boss, so InterruptElite bracket rolls auto-picked that boss 100% of the time. The post-2b tier-lethality trace named these one-shots (Warchief, Hag, Roper, Young Red Dragon) as the dominant remaining death source. Promotes one mid-tier alt per zone to IsElite (underforge gets two since fire_elemental was itself a non-elite killer). Boss SW=1 stays; alt SW 3-4 gives the boss ~17-25% elite-roll share. pickZoneEnemy also excludes IsElite from the standard pool, so promotion softens standard encounters by one mid-difficulty entry — each zone still has 3-4 standard entries left. Crypt-Valdris already dual-elite, untouched. Promotions: worg, owlbear, aboleth_thrall, vampire_spawn, salamander+fire_elemental, drow_elite_warrior, night_hag, dragonborn_cultist, hezrou. Phase 1 matrix delta (200 trials/cell, Fighter, centerline): goblin_warrens: 0% → 3.0% completion (first non-zero T1 reading) sunken_temple: 0% → 0.5% dragons_lair: death 100% → 60% (40% starve — different failure) underdark: death 100% → 90% (10% starve) feywild: death 100% → 92% (8% starve) T3 cells still 100% death — next pass is global supply/threat levers. Tier-lethality trace shows Drow Elite Warrior + Dragonborn Cultist spawning and being winnable, with arcs stretching to 7-10 encounters instead of fresh-entry one-shots. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -156,15 +156,47 @@ target the cascade path that's now mostly resolved; they have no
|
||||
remaining death-fraction to convert. Phase 2c (roster dilution) is
|
||||
justified rather than premature.
|
||||
|
||||
### Phase 2c — roster gate (next)
|
||||
### Phase 2c — roster gate (shipped)
|
||||
|
||||
Promote softer mid-tier monsters to `IsElite: true` in zones whose
|
||||
elite pool is a single tier-disproportionate boss (warchief / hag /
|
||||
roper / dragon are all SpawnWeight=1 alone in their elite pool, so
|
||||
an InterruptElite bracket roll = 100% pick of the over-tier boss).
|
||||
Diluting the elite pool with one or two softer alternates at higher
|
||||
SpawnWeight lets the fighter sometimes face a winnable elite,
|
||||
without removing the over-tier boss as a possible spawn.
|
||||
Promoted one mid-tier alt to `IsElite: true` in every zone whose elite
|
||||
pool was a single SpawnWeight=1 boss (`internal/plugin/dnd_zone.go`).
|
||||
The boss stays in the pool; weighted dilution means the InterruptElite
|
||||
bracket no longer auto-picks the over-tier boss. `pickZoneEnemy` also
|
||||
excludes the promoted entry from the standard pool, lowering standard
|
||||
encounter difficulty by removing one mid-difficulty option from
|
||||
non-elite brackets (acceptable: each zone still has 3-4 standard
|
||||
entries left). Crypt-Valdris was already dual-elite (wight + flameskull)
|
||||
and was left alone.
|
||||
|
||||
| zone | promoted alt | boss (untouched) |
|
||||
|--------------------|-----------------------|--------------------|
|
||||
| goblin_warrens | worg (SW=3) | hobgoblin_warchief |
|
||||
| forest_shadows | owlbear (SW=4) | green_hag |
|
||||
| sunken_temple | aboleth_thrall (SW=3) | water_elemental |
|
||||
| manor_blackspire | vampire_spawn (SW=3) | revenant |
|
||||
| underforge | salamander (SW=3) + fire_elemental (SW=3) | helmed_horror |
|
||||
| underdark | drow_elite_warrior (SW=4) | roper |
|
||||
| feywild_crossing | night_hag (SW=3) | fomorian |
|
||||
| dragons_lair | dragonborn_cultist (SW=3) | young_red_dragon |
|
||||
| abyss_portal | hezrou (SW=4) | marilith |
|
||||
|
||||
**Phase 1 matrix delta (200 trials/cell, Fighter, tier centerline):**
|
||||
goblin_warrens 0% → **3.0%** completion (first non-zero T1 reading
|
||||
since Phase 0); sunken_temple 0% → 0.5%; dragons_lair death% **100% →
|
||||
60%** with 40% now starve (fighter survives the elite-spawn path long
|
||||
enough to run out of supplies — different failure mode); underdark
|
||||
death% 100% → 90% (10% starve); feywild_crossing 100% → 92% death
|
||||
(8% starve). T3 manor_blackspire / underforge still 100% death — the
|
||||
remaining death pressure there is the post-2b chained-standard path,
|
||||
not the elite roll.
|
||||
|
||||
Tier-lethality trace cross-check (`Phase2_TierLethality`) shows the
|
||||
new alt-elites actually spawning and being winnable: underdark trial
|
||||
1 now opens with `Drow Elite Warrior` (won), reaches the Roper at
|
||||
turn 6, retreats, then dies on a Hook Horror nick — a substantively
|
||||
longer arc than the pre-2c fresh-entry Roper one-shot. Dragons_lair
|
||||
trials similarly show `Dragonborn Cultist` as a winnable elite stop
|
||||
before the dragon roll lands.
|
||||
|
||||
Stat-block tuning of the bosses themselves is off-limits per the
|
||||
Phase 3 constraint (bestiary is shared across systems).
|
||||
|
||||
@@ -220,7 +220,7 @@ func zoneGoblinWarrens() ZoneDefinition {
|
||||
{BestiaryID: "goblin_sneak", SpawnWeight: 7},
|
||||
{BestiaryID: "goblin_archer", SpawnWeight: 6},
|
||||
{BestiaryID: "hobgoblin_grunt", SpawnWeight: 5},
|
||||
{BestiaryID: "worg", SpawnWeight: 3},
|
||||
{BestiaryID: "worg", SpawnWeight: 3, IsElite: true},
|
||||
{BestiaryID: "goblin_shaman", SpawnWeight: 2},
|
||||
{BestiaryID: "hobgoblin_warchief", SpawnWeight: 1, IsElite: true},
|
||||
},
|
||||
@@ -310,7 +310,7 @@ func zoneForestShadows() ZoneDefinition {
|
||||
Enemies: []ZoneEnemy{
|
||||
{BestiaryID: "dire_wolf", SpawnWeight: 6},
|
||||
{BestiaryID: "bandit_captain", SpawnWeight: 4},
|
||||
{BestiaryID: "owlbear", SpawnWeight: 4},
|
||||
{BestiaryID: "owlbear", SpawnWeight: 4, IsElite: true},
|
||||
{BestiaryID: "dryad_corrupted", SpawnWeight: 3},
|
||||
{BestiaryID: "displacer_beast", SpawnWeight: 3},
|
||||
{BestiaryID: "green_hag", SpawnWeight: 1, IsElite: true},
|
||||
@@ -356,7 +356,7 @@ func zoneSunkenTemple() ZoneDefinition {
|
||||
{BestiaryID: "kuo_toa", SpawnWeight: 7},
|
||||
{BestiaryID: "kuo_toa_whip", SpawnWeight: 4},
|
||||
{BestiaryID: "merrow", SpawnWeight: 4},
|
||||
{BestiaryID: "aboleth_thrall", SpawnWeight: 3},
|
||||
{BestiaryID: "aboleth_thrall", SpawnWeight: 3, IsElite: true},
|
||||
{BestiaryID: "water_elemental", SpawnWeight: 1, IsElite: true},
|
||||
},
|
||||
Boss: ZoneBoss{
|
||||
@@ -403,7 +403,7 @@ func zoneManorBlackspire() ZoneDefinition {
|
||||
{BestiaryID: "poltergeist", SpawnWeight: 5},
|
||||
{BestiaryID: "banshee", SpawnWeight: 3},
|
||||
{BestiaryID: "wraith", SpawnWeight: 3},
|
||||
{BestiaryID: "vampire_spawn", SpawnWeight: 3},
|
||||
{BestiaryID: "vampire_spawn", SpawnWeight: 3, IsElite: true},
|
||||
{BestiaryID: "revenant", SpawnWeight: 1, IsElite: true},
|
||||
},
|
||||
Boss: ZoneBoss{
|
||||
@@ -449,8 +449,8 @@ func zoneUnderforge() ZoneDefinition {
|
||||
{BestiaryID: "magmin", SpawnWeight: 6},
|
||||
{BestiaryID: "azer", SpawnWeight: 5},
|
||||
{BestiaryID: "flameskull", SpawnWeight: 4},
|
||||
{BestiaryID: "salamander", SpawnWeight: 3},
|
||||
{BestiaryID: "fire_elemental", SpawnWeight: 3},
|
||||
{BestiaryID: "salamander", SpawnWeight: 3, IsElite: true},
|
||||
{BestiaryID: "fire_elemental", SpawnWeight: 3, IsElite: true},
|
||||
{BestiaryID: "helmed_horror", SpawnWeight: 1, IsElite: true},
|
||||
},
|
||||
Boss: ZoneBoss{
|
||||
@@ -495,7 +495,7 @@ func zoneUnderdark() ZoneDefinition {
|
||||
MaxRooms: 10,
|
||||
Enemies: []ZoneEnemy{
|
||||
{BestiaryID: "drow", SpawnWeight: 7},
|
||||
{BestiaryID: "drow_elite_warrior", SpawnWeight: 4},
|
||||
{BestiaryID: "drow_elite_warrior", SpawnWeight: 4, IsElite: true},
|
||||
{BestiaryID: "drow_mage", SpawnWeight: 3},
|
||||
{BestiaryID: "mind_flayer", SpawnWeight: 2},
|
||||
{BestiaryID: "hook_horror", SpawnWeight: 4},
|
||||
@@ -545,7 +545,7 @@ func zoneFeywildCrossing() ZoneDefinition {
|
||||
{BestiaryID: "will_o_wisp", SpawnWeight: 5},
|
||||
{BestiaryID: "quickling", SpawnWeight: 5},
|
||||
{BestiaryID: "green_hag", SpawnWeight: 4},
|
||||
{BestiaryID: "night_hag", SpawnWeight: 3},
|
||||
{BestiaryID: "night_hag", SpawnWeight: 3, IsElite: true},
|
||||
{BestiaryID: "fomorian", SpawnWeight: 1, IsElite: true},
|
||||
},
|
||||
Boss: ZoneBoss{
|
||||
@@ -590,7 +590,7 @@ func zoneDragonsLair() ZoneDefinition {
|
||||
{BestiaryID: "kobold", SpawnWeight: 7},
|
||||
{BestiaryID: "guard_drake", SpawnWeight: 5},
|
||||
{BestiaryID: "kobold_scale_sorcerer", SpawnWeight: 4},
|
||||
{BestiaryID: "dragonborn_cultist", SpawnWeight: 3},
|
||||
{BestiaryID: "dragonborn_cultist", SpawnWeight: 3, IsElite: true},
|
||||
{BestiaryID: "young_red_dragon", SpawnWeight: 1, IsElite: true},
|
||||
},
|
||||
Boss: ZoneBoss{
|
||||
@@ -637,7 +637,7 @@ func zoneAbyssPortal() ZoneDefinition {
|
||||
Enemies: []ZoneEnemy{
|
||||
{BestiaryID: "quasit", SpawnWeight: 6},
|
||||
{BestiaryID: "vrock", SpawnWeight: 5},
|
||||
{BestiaryID: "hezrou", SpawnWeight: 4},
|
||||
{BestiaryID: "hezrou", SpawnWeight: 4, IsElite: true},
|
||||
{BestiaryID: "nalfeshnee", SpawnWeight: 2},
|
||||
{BestiaryID: "marilith", SpawnWeight: 1, IsElite: true},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user