Replay: deterministic record & playback (#4)

Add deterministic record/playback for a run.

Recording captures `(seed, config hash, ordered tick-tagged commands)` and re-simulates on playback — no state snapshots. `DotaFactory.exe --replay <file>` re-plays a recorded run view-only with manual speed/pause.

Reviewed-on: #4
Co-authored-by: Malte Langkabel <malte.langkabel@gmail.com>
Co-committed-by: Malte Langkabel <malte.langkabel@gmail.com>
This commit was merged in pull request #4.
This commit is contained in:
2026-07-01 19:20:08 +00:00
committed by mlangkabel
parent cf68ac2862
commit d74ba5bfad
40 changed files with 3385 additions and 129 deletions

View File

@@ -10,6 +10,7 @@
#include "RecipesConfig.h"
#include "SchematicChoiceOption.h"
#include "Simulation.h"
#include "SimulationTestAccess.h"
#include "StationBodyComponent.h"
static GameConfig loadConfig()
@@ -38,7 +39,7 @@ static void killEnemyStationsAndApply(Simulation& sim)
killEnemyStations(sim);
if (sim.hasSchematicChoicesPending())
{
sim.applySchematicChoice(0);
SimulationTestAccess::applySchematicChoice(sim, 0);
}
}
@@ -246,7 +247,7 @@ TEST_CASE("RecipeSchematic: recipe schematic can appear in pending choices",
break;
}
}
sim.applySchematicChoice(0);
SimulationTestAccess::applySchematicChoice(sim, 0);
}
}
CHECK(foundRecipeChoice);
@@ -308,7 +309,7 @@ TEST_CASE("RecipeSchematic: newlyUnlockedItemNames is sorted, deduplicated, and
}
}
sim.applySchematicChoice(0);
SimulationTestAccess::applySchematicChoice(sim, 0);
}
}
@@ -340,7 +341,7 @@ TEST_CASE("RecipeSchematic: newlyUnlockedItemNames matches recipes that actually
const std::set<std::string> unlockedBefore = unlockedTrackedRecipeIds();
const SchematicChoiceOption choice = sim.getPendingSchematicChoices()[0];
sim.applySchematicChoice(0);
SimulationTestAccess::applySchematicChoice(sim, 0);
std::set<std::string> expectedNames;
for (const RecipeDef& def : cfg.recipes.recipes)