๐ค AI-Assisted Development Notice
This project was developed with substantial AI assistance. The vast majority of the code, documentation, tests, and formal specifications were written with the help of Claude Opus 4.5 and Codex 5.1. Human oversight was provided for code review, architectural decisions, and final approval, but the implementation work was heavily AI-driven. This transparency is provided so users can make informed decisions about using this crate.
โ ๏ธ โ ๏ธ โ ๏ธ WARNINGโ ๏ธ โ ๏ธ โ ๏ธ This crate is currently in alpha state as I start integrating it with some in-development game projects. I will utilize
semverto the best of my ability to help guard against breaking changes. The main goal of this is to provide a robust, easy-to-use, 100% reliable rollback engine for games. As such, there may be anywhere between "zero" API changes and "complete overhauls". This readme and the version will be updated appropriately as things stabilize.
Fortress Rollback is a correctness-first peer-to-peer rollback networking library for deterministic multiplayer games, written in 100% safe Rust ๐ฆ (#![forbid(unsafe_code)]). It is engineered for reliability: zero panics in production code, determinism by construction, extensive property and fuzz testing, and formal verification (TLA+, Kani, Z3) of its trickiest invariants. The callback-style API common to rollback libraries is replaced with a simple, request-driven control flow โ instead of registering callbacks, you advance the session and fulfill the list of requests it returns.
Fortress Rollback began as a fortified fork of the excellent ggrs crate โ itself inspired by the GGPO network SDK โ and has since grown its own capabilities, including graceful peer drop, runtime input delay, redundant-host spectators, and hot-join. Migrating from ggrs? See Migration from ggrs below.
Questions, bug reports, or feature ideas are welcome on GitHub Issues.
Fortress Rollback includes interactive game examples built with macroquad. Run them locally to see rollback networking in action:
# P2P session (run in two terminals with different ports)
cargo run --example ex_game_p2p --features graphical-examples -- --local-port 7000 --players localhost 127.0.0.1:7001
cargo run --example ex_game_p2p --features graphical-examples -- --local-port 7001 --players 127.0.0.1:7000 localhost
# Sync test (determinism verification)
cargo run --example ex_game_synctest --features graphical-examples -- --num-players 2 --check-distance 7See the examples README for system dependencies and more options.
To get started with Fortress Rollback, check out the following resources:
- ๐ User Guide โ Full documentation site with guides, architecture, and API reference
- ๐ GitHub Wiki โ Quick reference and community-editable docs
- ๐ป Examples โ Working code examples for common use cases
- ๐ฎ Request Handling Example โ How to handle game loop requests with manual matching or the
handle_requests!macro - ๐ API Documentation โ Auto-generated Rust docs on docs.rs
The interactive examples use macroquad, which requires system libraries:
Linux (Debian/Ubuntu):
sudo apt-get install libasound2-dev libx11-dev libxi-dev libgl1-mesa-devLinux (Fedora/RHEL):
sudo dnf install alsa-lib-devel libX11-devel libXi-devel mesa-libGL-develmacOS/Windows: No additional dependencies required.
Alpha / experimental only.
- 100% Deterministic: All collections use
BTreeMap/BTreeSetfor guaranteed iteration order; newhashmodule provides FNV-1a deterministic hashing - Panic-Free API: All public APIs return
Resulttypes instead of panicking โ no unexpected crashes - Correctness-First: Formally verified with TLA+ and Z3 proofs; ~1600 tests (~92% coverage) including multi-process network and resilience scenarios
- Enhanced Desync Detection: Built-in checksum validation with
P2PSession::confirmed_inputs_for_frame()for debugging state divergence handle_requests!Macro: Eliminates boilerplate in the game loop โ see User Guide- Config Presets:
SyncConfig::lan(),ProtocolConfig::mobile(), etc. for common network conditions - Player Handle Convenience Methods: Easy access to local/remote handles for 1v1 games, player type checking, and iteration โ see User Guide
- Unified Session Trait: Write generic game loops via
Session<T>โ works with P2P, spectator, and sync test sessions โ see User Guide - Runtime Input Delay: Adjust per-player input delay mid-session via
P2PSession::set_input_delayfor hybrid delay+rollback netcode โ see User Guide - Graceful Peer Drop: Configure
DisconnectBehavior::ContinueWithoutso the session keeps advancing for surviving peers, or remove a peer explicitly withP2PSession::remove_player(kick / surrender / leave-match) โ see User Guide
๐ Complete comparison with GGRS โ โ See all differences, bug fixes, and migration steps
| Condition | Supported | Optimal |
|---|---|---|
| RTT | <200ms | <100ms |
| Packet Loss | <15% | <5% |
| Jitter | <50ms | <20ms |
For detailed configuration guidance, see the User Guide.
| Feature | Description |
|---|---|
sync-send |
Adds Send + Sync bounds for multi-threaded game engines (e.g., Bevy) |
hot-join |
Allows a peer to join/rejoin a running session by filling a reserved or gracefully-dropped slot via a state snapshot (requires Config::State: Serialize + DeserializeOwned; player count stays fixed) |
tokio |
Enables TokioUdpSocket for async Tokio applications |
paranoid |
Runtime invariant checking in release builds |
graphical-examples |
Enables ex_game graphical examples (requires macroquad deps) |
loom |
Loom-compatible synchronization primitives for concurrency testing |
json |
JSON serialization for telemetry types (to_json() methods) |
z3-verification |
Enables Z3 SMT solver proofs (development/CI only โ requires Z3 installed) |
z3-verification-bundled |
Like z3-verification but builds Z3 from source (slow, no system Z3 needed) |
For detailed feature documentation, see the User Guide.
Moving from the original ggrs crate? See the step-by-step guide in migration.md. It covers the crate rename (fortress-rollback), the new Config::Address Ord bound, and import changes (fortress_rollback).
Fortress Rollback's core logic needs no WASM feature flag, but the two Web/WASM integration paths covered here have different requirements:
- Browser
wasm32-unknown-unknownusesweb_time's browser clock. Its dependency graph may legitimately includewasm-bindgen,js-sys, andweb-systhrough browser-only timing or transport crates. - Godot Web GDExtensions use
wasm32-unknown-emscripten. Their normal dependency graph must contain none of those JavaScript bridge crates because Godot's Web export loads the Rust output as an Emscripten side module, not through wasm-bindgen.
Native, browser, and Emscripten builds all measure protocol intervals and quality-report RTT with a local monotonic web_time::Instant; no shared epoch timestamp is required.
For browser networking, Matchbox 0.14 provides WebRTC data channels. Keep it behind the browser-only target gate so it cannot enter a Godot Web Emscripten build:
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]
matchbox_socket = "0.14"Matchbox's optional ggrs feature implements the upstream GGRS trait only, not Fortress Rollback's NonBlockingSocket. Leave that feature disabled and wrap a raw Matchbox channel in a local adapter that uses fortress_rollback::network::codec to encode and decode messages. Split the channel and poll a fixed maximum from its receiver per call; WebRtcChannel::receive() drains the entire queue. The custom socket example shows the generic codec and bounded-socket pattern such an adapter should follow.
Matchbox handles:
- WebRTC peer-to-peer connections โ direct data channels between browsers
- Signaling server โ connection establishment (only needed during setup)
- Low-latency unreliable channels โ unordered delivery with no retransmits, matching rollback traffic; reserve reliable channels for separate application data
See the custom socket example for implementing your own transport (WebSockets, custom protocols, etc.)
Fortress Rollback is dual-licensed under either
- MIT License: Also available online
- Apache License, Version 2.0: Also available online
at your option.