replay: closing tests and overlay polish (Phase 4)

- 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
This commit is contained in:
2026-06-30 21:20:22 +02:00
parent 26e108f3e1
commit bd9f550b67
4 changed files with 191 additions and 5 deletions

View File

@@ -433,12 +433,28 @@ Reshape mutations to flow through one path; behaviour unchanged.
the periodic-checksum-then-command ordering at a shared tick. (Live GUI playback is wired but
not auto-tested here.)
### Phase 4 — Closing tests & polish
### Phase 4 — Closing tests & polish — DONE
- **Round-trip test:** serialize → parse → assert command equality.
- **Replay-equivalence test (headless):** record a scripted run, play it back through the same
`lib` path, assert per-tick checksums match end-to-end — the real proof, no UI needed.
- Mismatch-warning UX, end-of-replay overlay polish.
- **Round-trip:** every command verb serializes → parsesre-serializes identically;
malformed input is rejected (`parseCommand` returns nullptr).
- **Replay-equivalence (headless):** a short scripted run and a **long ~2400-tick run through
waves/combat** each record → read → replay with **no desync** and a **byte-identical final
state checksum**.
- **Desync detection:** corrupting one recorded checksum makes the player 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 for
readability; config/version mismatch is warned to the log on launch (its visible consequence,
a desync, is already surfaced by the overlay).
### Status
Record + playback is functionally complete and covered by headless tests. Still deferred (per
this design): snapshots, save/load, backward-seek, cross-platform float hardening, expanding the
file checksum beyond RNG. Known minor rough edge: in replay mode the recipe/layout dialogs and
escape→restart can still open but do nothing (their commands hit the no-op enqueue); fully
disabling that input UI is polish, not correctness.
### Notes