The mental model

  1. Shared game state lives in a room on our servers; every entity has an owner — a client or the server — and only the owner writes it.
  2. Write to what you own exactly like local state; the SDK streams your changes up and everyone else’s down, and the server can veto or correct any write.
  3. Put anything cheat-sensitive or game-logic-shaped in server-owned entities (driven by typed RPCs if needed), deploy the room file with one command, and run simulated players to prove it works.

The ladder

Each rung is a local change, never a rewrite. Start at whichever rung your game needs today and climb when it gets more serious.

RungWhatChange
0Relay (nothing deployed)joinRoom(id)
1Owner-write syncassign owners in onJoin
2Validatorsadd a validate per entity
3Server-owned + RPCsmark serverOwned: true
4Server tick loopadd a tick(state, dt)

Why ownership

Ownership is the whole trick. It turns “who is allowed to change this?” — the hardest question in multiplayer — into a property of your data, checked in one place. A cosmetic position can be client-owned and cheap. A score, a card deck, or a hit result is server-owned and safe. You choose per entity.

What the server can always do

Even for client-owned entities, the server sees every write before it’s broadcast and can reject or clamp it. That’s how you add anti-cheat without moving your whole game server-side.

Next steps

Placeholder content.