Build a small realtime multiplayer game (2–16 players per room) with authoritative server state and lag that players don't notice under 150ms RTT.
Recommended stack
- PartyKit - room server. One file per room, websockets and state colocated at the edge, deploys in seconds.
- Phaser 3 or PixiJS - client rendering. Phaser if you need physics/scenes; Pixi if you only need fast sprites.
- TypeScript + zod - protocol. One shared schema file validates every message both directions.
- Vercel - client hosting. Static client next to the edge rooms keeps latency budgets honest.
Build steps
- Define the wire protocol first: a zod-validated union of client→server intents and server→client snapshots.
- Make the server authoritative: clients send intents, server simulates at a fixed tick (e.g. 20Hz), broadcasts snapshots.
- Interpolate remote players between snapshots; predict only the local player, reconcile on snapshot.
- Add rooms: create/join by 4-letter code; cap players; drop idle connections.
- Playtest with artificial 150ms delay (Chrome devtools) from day one.
Watch out for
- Trusting client positions - cheaters and physics divergence both come from this.
- Sending full state every tick at scale; delta-compress or send only changed entities.
- Testing only on localhost where latency is 0ms.
Definition of done
- Two browsers on different networks stay in sync through a 2-minute session
- A refresh rejoins the same room with state intact
- Server validates every message; malformed input can't crash a room