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:
@@ -184,3 +184,29 @@ TEST_CASE("ReplayRecorder startNewRun rolls to a new file", "[replay]")
|
||||
REQUIRE(second.find("_2.replay") != std::string::npos);
|
||||
recorder.close();
|
||||
}
|
||||
|
||||
TEST_CASE("CommandManager rolls the replay file on a Reset command", "[replay]")
|
||||
{
|
||||
Simulation sim(ConfigLoader::loadFromDirectory(CONFIG_DIR), 1u);
|
||||
CommandManager manager(sim);
|
||||
|
||||
std::unique_ptr<ReplayRecorder> recorder =
|
||||
std::make_unique<ReplayRecorder>(CONFIG_DIR, tempOutputDir());
|
||||
ReplayRecorder* recorderPtr = recorder.get();
|
||||
manager.setRecorder(std::move(recorder));
|
||||
const std::string firstPath = recorderPtr->currentFilePath();
|
||||
|
||||
std::shared_ptr<ResetCommand> reset = std::make_shared<ResetCommand>();
|
||||
reset->config = std::make_shared<GameConfig>(ConfigLoader::loadFromDirectory(CONFIG_DIR));
|
||||
reset->seed = 999u;
|
||||
manager.enqueue(reset);
|
||||
manager.drain();
|
||||
|
||||
const std::string secondPath = recorderPtr->currentFilePath();
|
||||
REQUIRE(firstPath != secondPath);
|
||||
REQUIRE(secondPath.find("_999.replay") != std::string::npos);
|
||||
|
||||
manager.setRecorder(nullptr);
|
||||
QFile::remove(QString::fromStdString(firstPath));
|
||||
QFile::remove(QString::fromStdString(secondPath));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user