#pragma once #include #include #include #include "ReplayReader.h" #include "Tick.h" class Simulation; // Drives playback of a parsed replay against a Simulation: applies each recorded // command at its recorded tick (through Simulation::apply) and verifies the RNG // checksums, reporting the first desync. Entries are consumed in file order, // which reproduces the exact command/tick interleaving of the original run. // // Cadence (mirrors how the run was recorded so checksums line up): // player.start(); // process tick-0 entries before the first tick // each frame, for each tick to run: // if (player.isFinished()) break; // sim.tick(); // player.advanceTo(sim.getCurrentTick()); class ReplayPlayer { public: ReplayPlayer(Simulation& simulation, std::vector entries); // Process all entries recorded at tick 0 (the initial checksum and any // commands issued before the first tick). Call once, before the first tick. void start(); // Process all entries recorded at `tick`. Call once after each sim.tick(). void advanceTo(Tick tick); // True once all entries are consumed or a desync was detected. bool isFinished() const; // The tick at which the recomputed checksum first diverged, if any. std::optional getDesyncTick() const; private: void processEntriesAt(Tick tick); Simulation& m_simulation; std::vector m_entries; std::size_t m_cursor = 0; std::optional m_desyncTick; };