namespace ProjectM.Simulation
{
///
/// Server-only working state for the run FSM — lives on the CycleDirector beside but is
/// NOT replicated (adding fields here never re-bakes the ghost). Owned/written by RunDirectorSystem.
/// Determinism: = max(1, Hash(, )) — monotonic
/// int, never a tick, equality-compared. Tick sentinels (/)
/// route through and compare via NetworkTick.IsNewerThan (never raw uint).
///
public struct RunRuntime : Unity.Entities.IComponentData
{
// ---- run identity / seed ----
/// Working copy of the run seed (mirrored to the replicated ).
public uint RunSeed;
/// Monotonic run counter; bumped on the Staging→Launching edge so each run reseeds. Equality-compared.
public int RunEpoch;
/// Per-playthrough salt folded into for cross-session map variety (seeded at spawn, non-tick).
public uint HostSalt;
// ---- room traversal ----
/// Monotonic room-seed counter; bumped per room advance so the field/enemy directors reseed. Equality-compared.
public int RoomEpoch;
/// Which of the two ping-pong sub-arena slots the active room occupies (CurrentRoom & 1).
public byte ActiveSubSlot;
/// The active room's stable map node id (single plan authority — field/enemy directors read this, never re-derive).
public int CurrentNodeId;
/// The active room's column (mirrors ).
public byte CurrentCol;
/// The active room's (single plan authority).
public byte CurrentRoomType;
// ---- scarcity / banking latches ----
/// Run-wide remaining resource-node allotment (floors each room's scatter; decrements per node) → true scarcity.
public int NodeBudgetRemaining;
/// The the terminal bank last fired for — equality latch so a multi-tick Returning banks once.
public int LastBankedRunEpoch;
/// 1 iff the run ended by a genuine BOSS clear (gates the win-meter/RunsCompleted credit; 0 on abort/wipe).
public byte LastTerminalCleared;
/// Rooms actually CLEARED this run (bumped on each InRoom→RoomReward edge; reset at launch) — the
/// honest depth the terminal bank records into MaxDepthReached (never the planned RoomCount — D-F3).
public int RoomsClearedThisRun;
// ---- ready / grace ----
/// Previous-tick all-ready state (rising-edge latch for the Staging→Launching launch).
public byte WasAllReady;
/// Server tick the RoomReward boon-pick grace elapses (NonZero; IsNewerThan-compared).
public uint RewardGraceTick;
/// Server tick the RouteSelect grace elapses → auto-pick lowest-index reachable (NonZero; IsNewerThan-compared).
public uint RouteGraceTick;
/// DR-046: RoomExplore soft-timeout (NonZero; auto-advance if nobody interacts the portal), so the
/// loot window can never softlock. Set on entering RoomExplore, compared via NetworkTick.IsNewerThan.
public uint ExploreGraceTick;
// ---- boons ----
/// Monotonic per-run boon-pick counter → distinct SourceIds in the run-scoped boon band; reset each run.
public uint BoonPickCounter;
}
}