The host crashes. The match doesn't.
Understudy is serverless host failover for Godot multiplayer. One player's machine hosts the match. A second one, the shadow, runs a warm copy of it, and if the host's game crashes, freezes or quits, the shadow takes over within about a quarter of a second: no reload, no reconnect, no "host left the game" screen. A third keeps a standby copy for when both fail at once.
Godot has no host migration of its own (the engine proposal godot-proposals#7912 has been open since 2023). Understudy hands the live match over.
Features
- Pure GDScript, Godot 4.5 and newer, no native code, no server, no service to pay for.
- Players send only inputs; the host runs the rules. Each player predicts its own moves.
- Strict mode: if your rules give bit-identical results on every machine, the shadow re-runs the host's ticks and reports any difference. That catches a cheating host and the bugs that make machines disagree. Included: deterministic math (
UnderstudyMath), a lint for risky calls, and a record-and-replay desync checker. - ENet (LAN, direct IP) and Steam (Steam's relays through GodotSteam: no port forwarding, no IP addresses shared) transports.
- Snapshots are compressed differences from what each player last confirmed.
- Dual licensed CC0-1.0 or MIT-0: use it for anything, no attribution needed.
Measured
On one Linux machine, copies of the demo playing as bots, every link with 40 ms one-way latency, 10 ms jitter and 1% loss:
| Test | Players | Result |
|---|---|---|
| 10 min, 29 host + 39 player crashes | 8 | 29 takeovers, gap median 228 ms, max 262 ms, no freeze of 300 ms or more |
| Host and shadow killed together, 9 times | 8 | standby took over every time, max 276 ms |
| Host quits gracefully, 8 times | 8 | max 69 ms |
| Host's link flickers, 8 times | 8 | max 242 ms |
| Over Steam's relays | 4 | max 235 ms, every link relayed and identity-checked by Steam |
| Two players | 2 | the survivor takes over |
| Cheating host | 5 | every edit made while a shadow ran was reported |
A recorded match replays bit-identically on Windows and on Godot 4.5. Status: 0.1.0, new; everything was measured on one machine, not yet between players in different homes.
How to use
- Extend
UnderstudyGamewith your rules:step(tick, inputs),save_state(),load_state(bytes),add_player(id),remove_player(id). - Add an
UnderstudySessionnode, setgame_factoryandinput_source, callhost(port)orjoin(address, port). - Draw
session.display_game().
Your rules must change only through step() and be saved and loaded as bytes. Godot's physics nodes can't hold the match itself (they can't be rewound or re-run); keep it in plain data.
What it doesn't do
Lag compensation, interest management, lobbies and NAT traversal off Steam are up to your game. The host's and shadow's machines see the whole match.
Changelog for version v0.1.0
2026-10-08 02:22:22
No changelog provided for this version.