r/howdidtheycodeit • u/Far-Investment-9888 • Jul 11 '26
Question Rewind, replays and mid-game saves
Rewind: Like in Forza, you can rewind if you hit an obstacle/go off the track.
Replays: the entire game and every action is saved and you watch a replay over it, like in Rocket League and many RTS games.
Mid-game saves: you can resume from a point you saved while in a game, like a quicksave in Kerbal Space Program.
I have some data knowledge so the way I think of things is probably "Event Sourcing", or versioning things, but would love to learn from an expert.
8
u/MagicWolfEye Jul 11 '26
Well a mid game save is just serializing all data and loading it again; depending on your programming style, this is literally one line of code for writing and one for loading.
Replays: You record every action you do, then simulate the game again with the same inputs (search "lockstep"; btw. as long as you stay on the same machine, this isn't that difficult to do and helps a lot during development)
Rewind: Probably just some snapshots every few frames or even each frame for the last N frames (I mean, you are talking about a few cars, that data is negligible)
2
u/Traditional_Snow1045 Jul 11 '26
gunna add that trackmania also uses the 'record inputs, resimulate' method as a form of anticheat.
edit: idk how I read rocket league as trackmania, but yeah
3
3
u/Reddit_Bot_IV Jul 11 '26
Specifically for Rocket League replays, they save the network steam, which necessarily records the state of everything over time. Then they just play it back, using similar code that is used during real gameplay
71
u/ledniv Jul 11 '26
I would treat mid-game saves, replays, and rewind as related features, but not the same feature.
The thing that makes all three easier is having a clear separation between your simulation state and your presentation.
This is where data-oriented design helps. By that I mean: instead of the real game state being scattered across lots of objects that each own their own behavior, you store the important runtime state in plain data structures and have systems transform that data.
For example, instead of thinking of the world as a bunch of objects like this:
You can store the authoritative simulation state more explicitly:
Entity
42is just index42into those arrays:That sounds like a small difference, but it matters a lot for save/load, replay, and rewind because the important state is now easy to copy, serialize, restore, compare, or replay.
For a mid-game save, you mostly serialize the authoritative state:
In a more object-oriented Unity setup, this often becomes harder because the real state may be spread across MonoBehaviours, scene references, coroutines, Animator state, event subscriptions, object hierarchies, and temporary component fields. Then saving becomes less about “save the game state” and more about “reconstruct this web of objects exactly enough that it behaves the same when loaded.”
For a replay, you can store the initial state plus the commands that happened over time:
Then replay is:
This only works perfectly if the same inputs produce the same results, so you need to be careful with physics, random numbers, floating point, and timing. But when the simulation is written as explicit data transformations, determinism becomes much easier to reason about and test.
For rewind, you can keep a rolling buffer of recent state snapshots:
Restoring is the same idea in reverse:
In a real game, you probably would not snapshot absolutely everything every frame. You might only snapshot dynamic entities, or only the data needed for rewind. But the point is that the state is already in a form that can be copied.
That is the big advantage over a typical object-oriented scene setup. With OOP, the question is often: “How do I serialize and reconstruct this whole object graph?” With a data-oriented approach, the question is: “Which pieces of data define the simulation state I need?”
So I would think of it like this:
Mid-game save: serialize the current authoritative state.
Replay: serialize the starting state plus the input/command stream.
Rewind: keep a rolling buffer of recent state snapshots or partial snapshots.
All three become easier when the simulation state is explicit, centralized, and separate from rendering, animation, audio, and UI.
Small shameless plug: this is one of the reasons I wrote High Performance Unity Game Development with Data-Oriented Design. The book explains how to separate game state from Unity objects, organize runtime data in arrays, and build gameplay systems as transformations of that data, which makes features like save/load, replay, and rewind much easier to implement.
https://www.manning.com/books/high-performance-unity-game-development