State & schema
The schema is one typed description of everything shared in a room. It’s the contract the client, the room file, and the wire format all agree on — change it once and every layer follows, with full type inference in your editor.
Fields
import { defineSchema, entity, map, number, string, boolean, enumOf } from '@irtio/schema';
const player = entity({
x: number(),
y: number(),
name: string({ max: 24 }),
ready: boolean({ default: false }),
team: enumOf(['red', 'blue', 'spectator']),
}); Every primitive takes options — default, min/max, and constraints that the
server enforces automatically.
Collections
| Helper | Use for |
|---|---|
map(entity) | keyed sets that grow and shrink — players, bullets, cards |
list(entity) | ordered sequences — a turn queue, a chat log |
entity({...}) | a fixed nested object — the match, the board |
export const schema = defineSchema({
match: entity({ phase: enumOf(['lobby', 'playing', 'over']), round: number() }),
players: map(player),
}); Diffs on the wire
You never send the whole state. The SDK computes a minimal binary diff each tick and only unchanged-primitive writes are skipped entirely, so idle entities cost nothing. See the room file API for how snapshots and diffs are exposed.
Migrations
Schemas are versioned. Adding an optional field is backward-compatible; renaming or removing one is a migration the CLI will scaffold for you.
Next steps
Placeholder content.