GGPO
"Good Game, Peace Out" — the rollback networking SDK, MIT-licensed, ~3.6k★ / 406 forks, last pushed June 2024, not archived. It is the reference implementation of rollback for fighting games and the clearest statement anywhere of what netcode costs an engine, which is why it lands here rather than in a networking wiki.
The pitch, and the mechanism
The README states the problem in one line: traditional techniques hide network transmission time by adding delay to a player's input, which produces a sluggish game feel. Rollback instead uses input prediction and speculative execution — the local input runs immediately, the remote input is guessed, and when the real input arrives the simulation is rewound and replayed. GGPO transmits only inputs, never state, because sending the whole game state every frame is too expensive.
The three requirements, which are the real content
The Developer Guide is blunt about what a game engine must already be for any of this to work:
- The simulation must be fully deterministic — the same state plus the same inputs must advance to a byte-identical state on every machine.
- The game state must be fully encapsulated and serializable.
- The engine must load, save, and execute a single frame without rendering it.
That third one is the rollback itself: replaying six frames after a late packet means running six headless simulation steps between two rendered frames. GGPO splits everything in a game into game state (positions, health, score) and inputs (buttons — and anything else that feeds the simulation, including the time of day if the game reads it), and explicitly excludes the renderer and non-gameplay effects from both.
The integration surface is small — ggpo_start_session, ggpo_add_player, ggpo_add_local_input,
ggpo_synchronize_inputs, and six mandatory callbacks including save_game_state,
load_game_state and advance_frame. When ggpo_synchronize_inputs returns anything but GGPO_OK
the game must not advance: GGPO has stopped hearing from the remote player and has hit its
internal prediction limit.
Windows-only builds at present, via Visual Studio 2019 and CMake, with porting work stated as in progress.
Why this matters to an engine
Determinism and serializable state are not features an engine adds later. A floating-point inconsistency, an unsynchronised random source, or gameplay logic that reads renderer state all break requirement 1, and none of them announce themselves until two machines diverge. This is the architectural commitment netcode describes, and it is the reason the choice is made at the start of a project rather than at the end.