Hooks a recorder into the command chokepoint so each run is written to disk as
it plays, ready for playback in Phase 3.
- ReplayRecorder (lib): line-oriented append-friendly file — keyed header
(version, build, seed, config_hash, timestamp), then '---', then tick-tagged
command lines interleaved with "# checksum <tick> <hex>" RNG fingerprints.
Each line is flushed so a crash leaves a valid partial file. Config hash is a
64-bit FNV over the config dir's *.toml files; build tag is __DATE__/__TIME__.
- CommandSerializer (lib): per-command text (length-prefixed variable parts;
ship layouts and splitter filters serialized inline). Reset is a file
boundary, never a stream entry.
- CommandManager owns an optional ReplayRecorder: drain() records each applied
command + a post-apply checksum; a drained Reset rolls to a new file;
recordTickCheckpoint() (called per tick from onFrame) writes a checksum every
30 ticks.
- Random seed generated in main and on restart (std::random_device); Simulation
retains it via getSeed() for the header.
- GameWorldView attaches the recorder at construction (first file + tick-0
checksum); replays land in <data>/replays named <timestamp>_<seed>.replay.
ReplayRecorderTest covers serialization, file well-formedness, file rolling,
and the CommandManager drain->record integration. Full suite green
(346 cases / 3377 assertions); app, tests, and balancing all build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DUsFgd2Ga6pmLz8giS8WUn
Reshapes every UI-driven sim mutation to flow through one path so it can be
recorded and replayed later, with behaviour unchanged.
- Command model (lib): Command base + derived types (PlaceBuilding, Demolish,
RotateInPlace, SetRecipe, SetShipLayout, Set[Site]SplitterFilters,
ClearBeltTiles, ApplySchematicChoice, Reset), each with a playerId for the
future-multiplayer shape. PlaceBuilding is atomic (carries optional
recipe/layout/filters) because deferred commands never return the new
BuildingId to the caller.
- CommandManager (lib): FIFO queue holding a Simulation&; enqueue + drain.
- Simulation::apply(const Command&): the single chokepoint, dispatching by
kind to the existing mutators. Mutators stay public (enforced by convention,
not compile-time, so the test suite keeps driving the sim directly).
- Timing: GameWorldView owns the CommandManager and drains it once per frame in
onFrame, before the tick batch (runs at 0x too, so build-while-paused is
preserved). A drained Reset triggers the view reset.
- UI fan-in: GameWorldView enqueues its own input directly; MainWindow and
SelectedBuildingPanel emit CommandRequestedEvent, which GameWorldView
subscribes to and enqueues. No UI site mutates the sim directly anymore.
- CommandTest: asserts apply(...) yields byte-identical state to the direct
mutator path, and that CommandManager drains FIFO through apply.
Full suite green (338 cases / 3353 assertions); determinism double-run still
passes. Design doc updated with the atomic-PlaceBuilding and convention-
enforcement decisions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DUsFgd2Ga6pmLz8giS8WUn
Introduces the state-checksum machinery the replay feature rests on, and a
test that proves the simulation is deterministic for a given seed/binary.
- StateChecksum: FNV-1a Hasher (bit-pattern float hashing, -0 normalization,
length-tagged strings) plus a portable mt19937 state fingerprint.
- BeltSystem/BuildingSystem: appendChecksum(Hasher&) folding transport and
building/site/occupancy state in deterministic (sorted/insertion) order.
- Simulation: rngFingerprint() (cheap, for the future file checksum) and
computeStateChecksum() (full state: RNG, scalars, wave/schematic/unlock
state, subsystems, and ECS position/health/facing/body/scrap/identity).
- DeterminismTest: Hasher unit tests, RNG-fingerprint tests, and a double-run
test asserting identical per-tick full-state checksums from one seed; plus a
different-seed divergence guard.
Exit criteria met: double-run determinism test passes; full suite green
(334 cases / 3346 assertions).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DUsFgd2Ga6pmLz8giS8WUn
Captures the deterministic command-replay design (seed + config hash +
tick-tagged command log, re-simulated on playback), the command-chokepoint
and timing model, determinism/checksum strategy, file format, and a
sequenced Phase 0-4 implementation plan.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DUsFgd2Ga6pmLz8giS8WUn
Fixes a bug where the selected construction site was not drawn with a border.
Reviewed-on: #2
Co-authored-by: Malte Langkabel <malte.langkabel@gmail.com>
Co-committed-by: Malte Langkabel <malte.langkabel@gmail.com>