mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Phase 3b (sweep): nick-floor + supply-burn sweep, T5 supply unlock
Wired SurpriseNickFloorOverride and SupplyBurnRatePctOverride into the
harness day-loop via two new parameterized helpers (surpriseRoundNickF,
applyDailyBurnP). Live callers go through the existing constants;
sweep test sits on top of the Phase 3-A best cell (e=23, d=1).
TestExpeditionBalance_Phase3B_NickSupplySweep walks 3×3 (floor ∈ {0, 1,
tier=live}) × (burn% ∈ {50, 75, 100=live}) × 10 zones × 200 trials.
Strong partial T5 positive; nick-floor lever inert.
- Supply burn is the T5 unlock: dragons_lair 0% → ~55% at burn=50.
Fighter survives elites; burn=75 isn't enough margin.
- T4 peaks at burn=75 (~12% underdark/feywild); burn=50 dips T4
slightly (more elites survived into).
- Nick-floor inert across tiers (≤3pp swing); wounded-clamp already
eats the chip-damage budget. Recommend dropping from live-tuning
candidates.
- T2-T3 wall persists: forest_shadows, manor_blackspire,
abyss_portal stuck at ~0% across every combo — outliers, not
addressable by global levers.
Global levers wrung out. Plan-doc Phase 3-B section + memory pointers
updated; next is Phase 4 (per-zone outlier pass). -short shows the
same two pre-existing failures (TestAdv2Scenario_ZoneRunGoblinWarrens,
TestMageSpellbookLineInRender).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -121,6 +121,26 @@ type expeditionBalanceProfile struct {
|
||||
// TestExpeditionBalance_Phase3_GlobalLeverSweep.
|
||||
EliteInterruptThresholdOverride int
|
||||
ThreatDriftBaseOverride int
|
||||
|
||||
// Phase 3-B global-lever overrides. Zero means "use live":
|
||||
//
|
||||
// SurpriseNickFloorOverride — absolute floor for the raw
|
||||
// surprise-round nick. Live floor is the zone tier (1..5).
|
||||
// Convention: 0 (the zero value) = "use live tier floor"; a
|
||||
// positive value sets the floor directly; -1 disables the floor
|
||||
// entirely (floor = 0). Lower floor = less per-fight chip damage
|
||||
// on fresh entries.
|
||||
//
|
||||
// SupplyBurnRatePctOverride — percent multiplier on the per-day
|
||||
// supply burn. Zero means "use live" (100%); 50 = half burn.
|
||||
// Lower = more supply margin for T4/T5 where starvation is the
|
||||
// dominant failure mode post-Phase-3-A.
|
||||
//
|
||||
// Both wired into the harness day loop only; live callers go
|
||||
// through the shipped helpers. See
|
||||
// TestExpeditionBalance_Phase3B_NickSupplySweep.
|
||||
SurpriseNickFloorOverride int
|
||||
SupplyBurnRatePctOverride int
|
||||
}
|
||||
|
||||
// expeditionTrialResult is the outcome of one simulated expedition.
|
||||
@@ -248,9 +268,11 @@ func (h *expeditionHarness) advanceExpeditionOneDay() expeditionTrialResult {
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Morning rollover — supply burn + day++.
|
||||
// 1. Morning rollover — supply burn + day++. Phase 3-B sweep can
|
||||
// scale the per-day burn via the harness profile; live callers go
|
||||
// through applyDailyBurn at 100%.
|
||||
harsh := h.exp.ThreatLevel > 60
|
||||
newSupplies, _ := applyDailyBurn(h.exp.Supplies, harsh, h.exp.SiegeMode)
|
||||
newSupplies, _ := applyDailyBurnP(h.exp.Supplies, harsh, h.exp.SiegeMode, h.supplyBurnRatePctOverride)
|
||||
h.exp.Supplies = newSupplies
|
||||
h.exp.CurrentDay++
|
||||
|
||||
@@ -394,6 +416,22 @@ func (h *expeditionHarness) resolvedNickDivisor() int {
|
||||
return liveSurpriseNickDivisor
|
||||
}
|
||||
|
||||
// resolvedNickFloor translates the harness profile's surprise-nick
|
||||
// floor override into the int contract surpriseRoundNickF expects
|
||||
// (<0 = use live tier-floor, >=0 = absolute floor value). The profile
|
||||
// uses 0 for "use live" so the struct's zero-value is the safe
|
||||
// default; -1 in the profile means "disable floor" (floor = 0).
|
||||
func (h *expeditionHarness) resolvedNickFloor() int {
|
||||
switch {
|
||||
case h.surpriseNickFloorOverride == 0:
|
||||
return -1
|
||||
case h.surpriseNickFloorOverride < 0:
|
||||
return 0
|
||||
default:
|
||||
return h.surpriseNickFloorOverride
|
||||
}
|
||||
}
|
||||
|
||||
// terminate stamps the final trial result with shared bookkeeping
|
||||
// (days elapsed, threat at end, encounter count, HP%).
|
||||
func (h *expeditionHarness) terminate(reason string, completed, died, starved bool) expeditionTrialResult {
|
||||
@@ -438,7 +476,7 @@ func (h *expeditionHarness) runHarnessFight(zone ZoneDefinition, elite bool) Com
|
||||
// spiral. Mirror live exactly so the harness measures the same
|
||||
// lever the live caller applies.
|
||||
nick := clampSurpriseNickD(
|
||||
surpriseRoundNick(monster, int(zone.Tier)),
|
||||
surpriseRoundNickF(monster, int(zone.Tier), h.resolvedNickFloor()),
|
||||
h.char.HPCurrent, h.char.HPMax,
|
||||
h.resolvedNickDivisor(),
|
||||
)
|
||||
@@ -560,6 +598,10 @@ type expeditionHarness struct {
|
||||
// (eliteInterruptThreshold=19, threatDriftBase=3).
|
||||
eliteInterruptThresholdOverride int
|
||||
threatDriftBaseOverride int
|
||||
// Phase 3-B levers. See expeditionBalanceProfile field doc; both
|
||||
// zero-sentinel for "use live".
|
||||
surpriseNickFloorOverride int
|
||||
supplyBurnRatePctOverride int
|
||||
// traceFight, if non-nil, is invoked once per fight inside
|
||||
// runHarnessFight with a human-readable summary. Used by the
|
||||
// Phase 2 lethality probe to spot whether the nick, the picked
|
||||
@@ -612,6 +654,8 @@ func runExpeditionBalanceTrial(p expeditionBalanceProfile, seed uint64) expediti
|
||||
surpriseNickDivisorOverride: p.SurpriseNickDivisorOverride,
|
||||
eliteInterruptThresholdOverride: p.EliteInterruptThresholdOverride,
|
||||
threatDriftBaseOverride: p.ThreatDriftBaseOverride,
|
||||
surpriseNickFloorOverride: p.SurpriseNickFloorOverride,
|
||||
supplyBurnRatePctOverride: p.SupplyBurnRatePctOverride,
|
||||
}
|
||||
for {
|
||||
res := h.advanceExpeditionOneDay()
|
||||
|
||||
Reference in New Issue
Block a user