namespace Theriapolis.Core.Tactical; /// /// Persists per-chunk player-caused modifications (chopped trees, dropped items, /// emptied bandit camps). Implementations: in-memory (Phase 4 tests + runtime /// cache), MessagePack-backed (Phase 4 save body — see ). /// public interface IChunkDeltaStore { /// Returns the delta for a chunk, or null if no modifications recorded. ChunkDelta? Get(ChunkCoord cc); /// Records a chunk's delta. Overwrites any existing entry. void Put(ChunkCoord cc, ChunkDelta delta); /// Erases a chunk's delta — the chunk reverts to its deterministic baseline. void Remove(ChunkCoord cc); /// Snapshot of every recorded delta, used by SaveCodec to flush the world. IReadOnlyDictionary All { get; } } /// /// Sparse delta for a single chunk: just the tactical-tile cells that diverge /// from 's output. Phase 4 stores both /// the surface and the deco; richer per-tile state arrives later. /// public sealed class ChunkDelta { public List TileMods { get; } = new(); /// True if the spawn list has been consumed (all spawns cleared). public bool SpawnsConsumed { get; set; } } public readonly struct TileMod { public readonly byte LocalX; public readonly byte LocalY; public readonly TacticalSurface Surface; public readonly TacticalDeco Deco; public readonly byte Flags; public TileMod(int lx, int ly, TacticalSurface s, TacticalDeco d, byte f) { LocalX = (byte)lx; LocalY = (byte)ly; Surface = s; Deco = d; Flags = f; } } /// Trivial in-memory implementation. Used by tests and at runtime before save. public sealed class InMemoryChunkDeltaStore : IChunkDeltaStore { private readonly Dictionary _store = new(); public ChunkDelta? Get(ChunkCoord cc) => _store.TryGetValue(cc, out var d) ? d : null; public void Put(ChunkCoord cc, ChunkDelta delta) => _store[cc] = delta; public void Remove(ChunkCoord cc) => _store.Remove(cc); public IReadOnlyDictionary All => _store; }