Getting started
Build a Real Game Loop
End-to-end flow from backend auth to realtime gameplay updates.
Build a Real Game Loop
This page shows the practical production loop most games need.
1. Backend mints short-lived token
Your backend (not the client) calls control API:
curl -X POST http://localhost:3000/tokens \
-H "content-type: application/json" \
-d '{"project_id":"<project-id>","key_id":"<key-id>","ttl_seconds":900}'Return the token to your authenticated player session.
2. Client connects to data plane
async function (: string) {
const = await ("ws://localhost:4000", {
: "<project-id>",
,
});
const = await .("duel_room", { : "arena-1" });
.("player.move", { : 10, : 4, : 1001 });
}Client receives initial state.snapshot.
5. Plugin/server applies authoritative logic
Room/plugin on_message handles:
input.typeinput.data
It returns new authoritative room state and optional event payload.
6. Client receives state and events
room.onStateChange((state) => {
renderWorld(state);
});
room.onMessage("combat.hit", (payload) => {
showHitMarker(payload);
});7. Reconnect and resume
On network interruption:
- SDK reconnects (if enabled)
- session resume can recover room state within configured TTL
- if sequence/checksum mismatch occurs,
state.resyncpath restores consistency
8. Production guardrails
- keep tokens short-lived
- rate-limit gameplay message types
- validate message payload schema per room type
- monitor handshake/join/error rates