LANTERN purge B3+B5: delete the cycle/core/win-lose spine + onboarding; save epoch v7

Deletes CyclePhaseSystem, GoalReachedSystem, CoreDamage/CoreRestore, ThreatDirector,
CoreIntegrity/GoalProgress/RunPhase/RunOutcome/ThreatState components,
CoreVisualFeedbackSystem, and the whole Client/Onboarding slice (+6 test files).

Keepers reworked: RunDirectorSystem (UpdateBefore attr + launch guard + goal/threat
bank removed; sole SaveRequest raiser now), CycleDirectorSpawnSystem (ledger/meta
host only), WaveSystem UNGATED (waves run wherever a WaveDirector is baked),
EnemyAISystem core-fallback stripped, AmbientAudioSystem reworked (bed + run cues;
no CycleState gate), MusicSystem RunInfo-only, HudSystem big trim (goal meter, core
bar, siege banner, terminal banner, outcome flash, onboarding hook all gone),
MetaShop/ClassPrep/AimReticle siege gates dropped, DebugOverlay/ops re-meant
(SpawnWave=force next wave, EndSiege=quiet arena; SetCalm/AdvanceGoal/SetHeat
retired, bytes reserved), TuningConfig Core knobs retired (ids 20-23 reserved),
StorageMath.DrainFraction deleted, HowToPlay copy rewritten.

Save epoch v7 (fresh epoch, operator-approved): SaveData drops goal/core/outcome +
conveyor/machine-IO fields; MinLoadableVersion=7; PendingSave/PendingStructure
trimmed; RollTerminalCampaignForward deleted; SaveStructureScan signature slimmed.

390 tests green; Play world-creation clean (player + waves live, no exceptions).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 15:27:12 -07:00
parent 835dace213
commit b34945c2d2
74 changed files with 233 additions and 3955 deletions
@@ -35,10 +35,6 @@ namespace ProjectM.Tests
// GruntWindup must stay the canonical Tuning const (TelegraphTests couples to it).
Assert.AreEqual((float)Tuning.AttackWindupTicks, d.GruntWindupTicks, 1e-6f, "GruntWindupTicks == Tuning.AttackWindupTicks");
Assert.AreEqual(0.7f, d.StructureAggroWeight, 1e-6f, "EB-1 StructureAggroWeight default (<1 prefers structures)");
Assert.AreEqual(10f, d.CoreDamagePerHusk, 1e-6f, "END-1 CoreDamagePerHusk default");
Assert.AreEqual(18f, d.CoreRegenIntervalTicks, 1e-6f, "END-1 CoreRegenIntervalTicks default");
Assert.AreEqual(0.5f, d.CoreOverrunDrainPct, 1e-6f, "END-1 CoreOverrunDrainPct default (half the ledger on a breach)");
Assert.AreEqual(2.5f, d.FinalSiegeMultiplier, 1e-6f, "END-2 FinalSiegeMultiplier default (~2.5x a normal siege)");
}
@@ -47,6 +43,7 @@ namespace ProjectM.Tests
{
for (byte knob = 0; knob < TuningKnob.Count; knob++)
{
if (knob >= 20 && knob <= 23) continue; // retired END-1/END-2 knob ids (LANTERN purge; reserved)
var c = TuningConfig.Defaults();
float baseline = TuningConfig.Get(c, knob);
float target = baseline + 7f; // survives both clamps (positive)
@@ -56,7 +53,7 @@ namespace ProjectM.Tests
// every OTHER knob is untouched
var d = TuningConfig.Defaults();
for (byte other = 0; other < TuningKnob.Count; other++)
if (other != knob)
if (other != knob && !(other >= 20 && other <= 23))
Assert.AreEqual(TuningConfig.Get(d, other), TuningConfig.Get(c, other), 1e-4f,
$"knob {other} unchanged while editing {knob}");
}
@@ -126,7 +123,10 @@ namespace ProjectM.Tests
TuningConfig.Apply(ref c, TuningKnob.ChargerWhiffStaggerTicks, 50f);
var c2 = TuningConfig.FromReport(TuningConfig.ToReport(c));
for (byte knob = 0; knob < TuningKnob.Count; knob++)
{
if (knob >= 20 && knob <= 23) continue; // retired knob ids (LANTERN purge)
Assert.AreEqual(TuningConfig.Get(c, knob), TuningConfig.Get(c2, knob), 1e-6f, $"knob {knob} survives ToReport/FromReport");
}
}
// ---- consumption (world) ----