- Round-trip: every command verb serialize->parse->re-serialize is identical;
malformed input is rejected.
- Equivalence: add a long ~2400-tick run through waves/combat that records,
reads back, and replays to a byte-identical final state with no desync
(alongside the existing short scenario).
- Desync detection: corrupting one recorded checksum makes ReplayPlayer report
the exact desync tick.
- Reset boundary: a Reset drained through CommandManager rolls the recorder to
a new file named by the new seed.
- Polish: the end-of-replay / desync overlay dims the world behind the message.
Record + playback is now functionally complete and covered by headless tests.
Full suite green (354 cases / 3418 assertions).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DUsFgd2Ga6pmLz8giS8WUn
Adds view-only playback: re-simulate from the recorded seed + commands and
verify the RNG checksums.
- ReplayReader (lib): parses a replay file into header + an ordered stream of
command/checksum entries. CommandSerializer gains the inverse parseCommand
(round-trips every verb; rejects malformed input).
- ReplayPlayer (lib): the playback driver. Applies each command at its exact
recorded tick and verifies checksums in file order (start() handles tick 0;
advanceTo(tick) handles each tick after sim.tick()). Independent of
replay-time speed/pause; reports the first desync tick.
- CommandManager replay mode: enqueue() becomes a no-op so live input is
ignored while the recorded stream drives application.
- main.cpp: --replay <file> reads + validates (warns on version/config-hash
mismatch), seeds the sim from the header, and threads the replay through
MainWindow to GameWorldView.
- GameWorldView: drives the player in onFrame (manual speed/pause kept,
forward-only), gates the schematic-choices and game-over polls, and draws a
"REPLAY" tag plus a passive "Replay ended" / "Desync at tick N" overlay.
- computeReplayConfigHash factored out of ReplayRecorder for reuse by main.
ReplayPlaybackTest records a scripted run, reads it back, replays it, and
asserts no desync + byte-identical final state -- including the
periodic-checksum-then-command ordering at a shared tick. Full suite green
(350 cases / 3396 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