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:
@@ -16,7 +16,7 @@ namespace ProjectM.Client
|
||||
/// </summary>
|
||||
public static class HowToPlayPanel
|
||||
{
|
||||
static readonly string[] Tabs = { "Controls", "The Loop", "Build & Economy", "Threats", "Win / Lose" };
|
||||
static readonly string[] Tabs = { "Controls", "The Loop", "Build & Economy", "Threats" };
|
||||
|
||||
public static VisualElement Build(Action onClose)
|
||||
{
|
||||
@@ -85,35 +85,24 @@ namespace ProjectM.Client
|
||||
Body(c, "Pause — Esc");
|
||||
break;
|
||||
case 1: // The Loop
|
||||
Head(c, "THE LOOP — expedition RUNS are how you win");
|
||||
Body(c, "1. BASE — pick your CLASS + buy PREP buffs (this run only); build Turrets + a Fabricator; spend Aether on PERMANENT class upgrades.");
|
||||
Head(c, "THE LOOP — descend, fight, bank");
|
||||
Body(c, "1. BASE — pick your suit-frame, buy PREP buffs (this run only), spend Aether on PERMANENT upgrades.");
|
||||
Body(c, "2. READY UP [T] — when everyone is ready, the party launches into a multi-room run together.");
|
||||
Body(c, "3. RUN — clear each room, pick 1 of 3 BOONS (this run only), choose your path on the map, mine the crystals.");
|
||||
Body(c, "4. BOSS — fell it and the party returns with the haul: +1 on the Engine meter. A wipe banks nothing.");
|
||||
Body(c, "5. SIEGE — a completed run provokes retaliation at base. Defend the Core!");
|
||||
Body(c, "6. WIN — fill the Engine meter, then hold the final siege.");
|
||||
Body(c, "3. RUN — clear each room, pick 1 of 3 BOONS (this run only), choose your path, mine the crystals.");
|
||||
Body(c, "4. BOSS — fell it and the party returns with the haul. A wipe banks nothing but the depth record.");
|
||||
break;
|
||||
case 2: // Build & Economy
|
||||
Head(c, "RESOURCES & BUILDING");
|
||||
Body(c, "Ore — main currency. Attack the glowing crystals INSIDE runs and haul them home (they're scarce — spend well).");
|
||||
Body(c, "Turret (40 Ore) — auto-fires at enemies. Needs Charge as ammo.");
|
||||
Body(c, "Fabricator (30 Ore) — converts Ore → Charge so turrets keep firing.");
|
||||
Body(c, "Wall (Biomass) — a cheap barrier that blocks enemies.");
|
||||
Body(c, "Aether — rare; fuels PERMANENT class upgrades at the base between runs.");
|
||||
Body(c, "Aether — rare; fuels PERMANENT upgrades at the base between runs.");
|
||||
Body(c, "Open Build with Tab (Y), pick a piece, click a green tile to place it.");
|
||||
break;
|
||||
case 3: // Threats
|
||||
default: // Threats
|
||||
Head(c, "THREATS");
|
||||
Body(c, "Husks assault the base during a Siege — keep them off the Engine Core.");
|
||||
Body(c, "A Husk that reaches the Core drains it. Lose the Core in the final siege and the run ends.");
|
||||
Body(c, "Runs escalate room by room — elites guard the deep paths, a boss guards the end.");
|
||||
Body(c, "Enemy variety scales the deeper you push.");
|
||||
break;
|
||||
default: // Win / Lose
|
||||
Head(c, "WIN / LOSE");
|
||||
Body(c, "WIN — clear expeditions to fill the Engine meter, then hold the final siege.");
|
||||
Body(c, "LOSE — the Engine Core falls during the final siege.");
|
||||
Body(c, "A Core breach mid-run is only a setback: resources lost, the Core recovers in Calm.");
|
||||
Body(c, "What the light doesn't hold, the dark takes back.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,17 +129,11 @@ namespace ProjectM.Client
|
||||
static void StagePendingSave(World server)
|
||||
{
|
||||
var data = SaveService.Load();
|
||||
// A terminal (won/lost) save Continues as a FRESH campaign — base+meta kept, outcome/meter/core reset
|
||||
// (else the dead outcome banner re-latches from the first snapshot).
|
||||
SaveService.RollTerminalCampaignForward(data);
|
||||
|
||||
if (data == null) return;
|
||||
var em = server.EntityManager;
|
||||
var e = em.CreateEntity();
|
||||
// v5->v6 migration (operator-approved): an old save's Charge counted boss-cleared runs (DR-042), so a
|
||||
// missing RunsCompleted floors to it — the HUD never shows "Charge 3/4" beside "Runs completed: 0".
|
||||
int runsCompleted = data.RunsCompleted > data.GoalCharge ? data.RunsCompleted : data.GoalCharge;
|
||||
em.AddComponentData(e, new PendingSave { GoalCharge = data.GoalCharge, GoalTarget = data.GoalTarget, CoreCurrent = data.CoreCurrent, RunOutcome = (byte)data.RunOutcome, RunsCompleted = runsCompleted, MaxDepthReached = data.MaxDepthReached, HasData = 1 });
|
||||
em.AddComponentData(e, new PendingSave { RunsCompleted = data.RunsCompleted, MaxDepthReached = data.MaxDepthReached, HasData = 1 });
|
||||
// v6: stage the meta tiers UNCONDITIONALLY (empty OK — the Bursted spawn system GetBuffers it in the
|
||||
// HasData block; a conditional buffer would throw on any v<=5 Continue). Rows verbatim, no clamping.
|
||||
var mbuf = em.AddBuffer<PendingMetaRow>(e);
|
||||
@@ -159,10 +153,6 @@ namespace ProjectM.Client
|
||||
var sbuf = em.AddBuffer<PendingStructure>(se);
|
||||
foreach (var s in data.Structures)
|
||||
sbuf.Add(SaveApply.ToPending(s)); // EB-1: pure mapping (unit-tested, incl. the wounded HP)
|
||||
var iobuf = em.AddBuffer<PendingStructureIo>(se);
|
||||
if (data.StructureIo != null)
|
||||
foreach (var io in data.StructureIo)
|
||||
iobuf.Add(new PendingStructureIo { StructureIndex = io.StructureIndex, Slot = io.Slot, ResourceId = io.ResourceId, Count = io.Count });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,9 +165,6 @@ namespace ProjectM.Client
|
||||
using var q = em.CreateEntityQuery(ComponentType.ReadOnly<ResourceLedger>());
|
||||
if (q.IsEmptyIgnoreFilter) return;
|
||||
var dir = q.GetSingletonEntity();
|
||||
var goal = em.HasComponent<GoalProgress>(dir) ? em.GetComponentData<GoalProgress>(dir) : default;
|
||||
var core = em.HasComponent<CoreIntegrity>(dir) ? em.GetComponentData<CoreIntegrity>(dir) : default; // END-1
|
||||
var outcome = em.HasComponent<RunOutcome>(dir) ? em.GetComponentData<RunOutcome>(dir) : default; // END-2
|
||||
|
||||
var buffer = em.GetBuffer<StorageEntry>(dir, true);
|
||||
var rows = new LedgerRow[buffer.Length];
|
||||
@@ -195,21 +182,16 @@ namespace ProjectM.Client
|
||||
// v6: the permanent-meta slice via the ONE shared collector — omitting it HERE (the most common
|
||||
// exit path) would silently WIPE all meta progression on quit (the meta review's top blocker).
|
||||
MetaSaveScan.Collect(em, dir, out var metaRows, out var runsCompleted, out var maxDepth);
|
||||
SaveStructureScan.Collect(em, nowTick, out var structures, out var structureIo);
|
||||
SaveStructureScan.Collect(em, nowTick, out var structures);
|
||||
|
||||
SaveService.Save(new SaveData
|
||||
{
|
||||
GoalCharge = goal.Charge,
|
||||
GoalTarget = goal.Target,
|
||||
CoreCurrent = core.Current,
|
||||
RunsCompleted = runsCompleted,
|
||||
MaxDepthReached = maxDepth,
|
||||
MetaUpgrades = metaRows,
|
||||
RunOutcome = outcome.Value,
|
||||
|
||||
Ledger = rows,
|
||||
Structures = structures,
|
||||
StructureIo = structureIo,
|
||||
SavedAtMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user