using Unity.Entities;
using Unity.NetCode;
namespace ProjectM.Simulation
{
///
/// One owned permanent meta-upgrade tier, keyed by (class, upgrade). The CycleDirector's DynamicBuffer of these is
/// the authoritative per-class meta-progression record. A GLOBAL [GhostField] buffer on the ownerless
/// interpolated director ghost (no OwnerSendType — the party invests together and every client reads it for the
/// shop), mirroring . Persisted to disk (SaveData v6) and re-applied born-correct at
/// player spawn as meta-band s. Bytes only (Burst/serialization safe). Sparse — an
/// absent (class, upgrade) row means tier 0.
///
[InternalBufferCapacity(24)]
public struct MetaTierState : IBufferElementData
{
/// Owning class id (Warrior/Ranger — the CharacterId anchor).
[GhostField] public byte ClassId;
/// Upgrade id (append-only key into the meta catalog).
[GhostField] public byte UpgradeId;
/// Owned tier (>=1; an absent row = 0).
[GhostField] public byte Tier;
}
///
/// Server-only singleton on the CycleDirector: the FIRST-COMMIT latch for the co-op route choice. Written IN-PLACE
/// (immediate SystemAPI.SetComponent, not a deferred ECB) inside RouteSelectSystem's drain loop so two
/// same-tick picks cannot both observe ==0 (the DR-014 atomicity idiom). NOT replicated.
///
public struct RouteCommand : IComponentData
{
/// 1 once a route has been committed for the current (RunEpoch, layer).
public byte HasPick;
/// The committed option index (into the replicated RouteOpt* set).
public byte OptionIndex;
/// Run epoch the pick is for (stale-reject guard).
public int ForRunEpoch;
/// Layer the pick is for (stale-reject guard).
public int ForLayer;
}
///
/// Server-only singleton on the CycleDirector: the room-exit PORTAL interact latch (DR-046). PortalInteractReceiveSystem
/// sets when a player interacts the portal during RoomExplore; RunDirectorSystem (the sole
/// RunInfo/RunRuntime writer) reads it to advance the run + tear the room down, then clears it. NOT replicated.
/// Added unconditionally at director spawn (like RouteCommand).
///
public struct PortalCommand : IComponentData
{
/// 1 once a participant has interacted the room-exit portal this RoomExplore.
public byte HasInteract;
}
///
/// Server-only persisted meta counters on the CycleDirector (mirrored to the replicated for
/// the HUD). Added UNCONDITIONALLY at director spawn (like CycleRuntime/ThreatState/RunPhase) so a New-Game boot
/// has the component the bank block reads; restored values are SetComponent'd only inside the save-present block.
/// NOT replicated.
///
public struct MetaCounters : IComponentData
{
public int RunsCompleted;
public int MaxDepthReached;
}
///
/// Server-only tag of a player's class id, added at spawn by GoInGameServerSystem. Lets the meta systems
/// resolve which per-class tier record to seed / spend against (class was previously only an AbilityRef /
/// wire concern). NOT replicated.
///
public struct PlayerClass : IComponentData
{
public byte ClassId;
}
}