using System; namespace ProjectM.Simulation { /// One serialized ledger row (item id + count). An array FIELD of . [Serializable] public struct LedgerRow { public int ItemId; public int Count; } /// /// One serialized player-built structure (M7). Flat scalars (JsonUtility has no int2). The production /// cooldown is stored as REMAINING ticks (epoch-independent) so it survives the server-tick origin reset on a /// fresh session; the in-flight conveyor item (if any) rides here, while variable-length machine I/O buffers /// live in the flat table keyed by index. /// [Serializable] public struct StructureSave { public byte Type; public int CellX; public int CellZ; public byte Direction; // conveyor facing (0 for non-conveyors) public uint RemainingTicks; // production/cooldown ticks left at save time public byte ConveyorResId; // in-flight conveyor item resource (0 = none) public int ConveyorCount; public float HP; // EB-1: hit points at save time (0 from a pre-v3 save -> restored to baked Max) } /// /// One serialized machine I/O buffer row, joined to by /// . A flat top-level array (JsonUtility can't nest arrays-of-arrays); Slot 0 = /// MachineInput, Slot 1 = MachineOutput. /// [Serializable] public struct StructureIoRow { public int StructureIndex; public byte Slot; public byte ResourceId; public int Count; } /// /// Versioned, host-authoritative save slice (the FOUNDATION): the long-arc goal charge/target + the shared /// resource ledger. JsonUtility-friendly — a class with flat fields and an array FIELD (never a root array). /// The schema is intentionally ADDITIVE: future fields (placed structures, threat, storage) append without /// breaking old saves, gated by migration. /// [Serializable] public class SaveData { public const int CurrentVersion = 4; // END-1: v4 adds CoreCurrent (a wounded base persists) /// Oldest save schema the loader accepts (additive); a v2 save loads with structures at full HP. public const int MinLoadableVersion = 2; public int Version = CurrentVersion; public int GoalCharge; public int GoalTarget; public int CoreCurrent; // END-1: Engine Core integrity at save time (0 from a pre-v4 save -> restored to baked Max) public LedgerRow[] Ledger = Array.Empty(); public StructureSave[] Structures = Array.Empty(); public StructureIoRow[] StructureIo = Array.Empty(); public long SavedAtMs; } }