Plaza is a set of foundational building blocks for correct, high performance, server authoritative applications. In Rust.
You implement one trait, StateLogic, and Plaza owns the rest: the controller loop that serializes every change, the transports, and the per-client snapshots. Build a multiplayer game server, or a collaborative document, or a shared to-do list. Anything where many clients change one piece of state and the server has the final word.
It ships as seven crates, and that split is the whole point. plaza, plaza_session and plaza_lobby are the server. plaza_client_utils, plaza_server_utils, plaza_ws and plaza_wire are runtime free and build for wasm, so a browser client can share the server's own rule code instead of reimplementing it and hoping the two agree. Use Plaza on the server, on the client, or both. That is the contract.
The library takes a lot of inspiration from Gabriel Gambetta's Fast Paced Multiplayer. The netcode example demonstrates what Gambetta did with his live demo, and I think it holds up next to the original. It also takes some parts from games I've made but never released, and a little from Coherence's Vampire Survivors multiplayer article.
Making multiplayer games shouldn't require a full rewrite every time you go from one game to the next. Game engines are starting to provide multiplayer infrastructure, but they tend to be inflexible. Plaza is flexible. That's the value proposition.
The Horde and Blackhole examples are where that gets demonstrated. Horde runs up to 8,000 enemies and 128 players; Blackhole runs 6,000 gravitationally simulated pellets across 64 black holes. Thousands of interactive entities, simulated on the server, streamed to every client as deltas against what that client has actually acknowledged. A single client's downlink stays in the hundreds of KiB/s even at those counts, because relevance culling, two tier player LOD and crowd summaries decide what each viewer actually needs. Both run in the browser.
I am amazed at how well movement holds together at low send rates. Drop the entity rate to 1 Hz and the horde still moves smoothly, because every client runs the same rule the server does rather than interpolating between stale samples.
Recovery is first class, and I think that's the part people will feel first. Hide a browser tab for a minute and come back: the world is there, in one frame. Three things make that work. The server stops streaming to a client that has provably stopped acknowledging, so the backlog never grows to megabytes. The client throws its backlog away without parsing it, because none of it describes a moment it can still play. And an acknowledgement carrying the digest of nothing obligates the server to send a full baseline, which is why there is no resync request message anywhere in the protocol. Dropping your state is the request.
I wanted the building blocks first class and swappable, because no real game ships by importing a library and hoping that everything works. Custom code gets written, experiments get run. So prediction, reconciliation, interpolation, lag compensation, rollback, relevance streaming and delta baselines are all separate pieces you can take, replace or ignore. The client crates also carry four principles that every netcode bug I hit while building the examples traces back to. Those are documented, with what each one cost to learn.
It's at 0.5.0 with 500+ tests and four playgrounds you can run right now. It is early, and I'd rather say that than pretend otherwise.
One caveat on the examples: at maximum settings they push a lot of data, so play them over LAN or offline rather than hosting them on the internet. They're built to show the ceiling, not to be deployed at it.
