using System.Collections.Immutable; using SideScrollerGame.Sim.Definitions; using SideScrollerGame.Sim.Serialization; namespace SideScrollerGame.Sim.Replay; public static class ReplayPlayer { public static ImmutableArray Play(ReplayRecord replay, GameDefinition gameDefinition, SimulationConfig config) { if (replay.ContentHash != GameDefinitionHasher.Compute(gameDefinition)) throw new InvalidOperationException("Replay content hash does not match the supplied game definition."); if (replay.TicksPerSecond != config.TicksPerSecond) throw new InvalidOperationException("Replay tick rate does not match the supplied simulation config."); var hashes = ImmutableArray.CreateBuilder(replay.Ticks.Length); Simulation simulation = new(gameDefinition, config, replay.Seed); foreach (var recordedTick in replay.Ticks) { var result = simulation.Step(recordedTick.ActionBatch); if (result.StateHash != recordedTick.ExpectedStateHash) throw new InvalidOperationException($"Replay diverged at tick {recordedTick.ActionBatch.Tick}."); hashes.Add(result.StateHash); } return hashes.MoveToImmutable(); } }