Server authority & validation
Authority is a spectrum, and irt.io lets you dial it per entity. At the low end, a validator lets you keep client ownership but still refuse impossible writes. At the high end, a tick loop lets the server simulate the whole game.
Validators
A validator runs on the server for every write to an entity before it’s broadcast. Return the corrected value, or throw to reject.
export default defineRoom(schema, {
validate: {
players(prev, next, ctx) {
// clamp movement to a sane speed — no teleporting
const maxStep = 12;
next.x = clamp(next.x, prev.x - maxStep, prev.x + maxStep);
next.y = clamp(next.y, prev.y - maxStep, prev.y + maxStep);
return next;
},
},
}); The client still owns the value — this is a cheap guardrail, not a takeover.
The tick loop
For continuous simulation (physics, projectiles, timers), give the room a tick. It runs at a fixed rate on the server, holds the authoritative state, and
its writes sync to everyone.
export default defineRoom(schema, {
tick(state, dt) {
for (const b of Object.values(state.bullets)) {
b.x += b.vx * dt;
b.y += b.vy * dt;
if (offscreen(b)) delete state.bullets[b.id];
}
},
}); Client inputs arrive as RPCs or owned writes; the tick turns them into authoritative outcomes.
Reconciliation
When the server corrects a client-owned value, the SDK reconciles it smoothly on the client (no rubber-banding for small corrections). You can opt into client-side prediction per entity for input-sensitive movement.
Next steps
Placeholder content.