State and schema
A schema describes shared state and gives both server and client TypeScript types. Put it in irtio/schema.ts and import it on both sides.
// irtio/schema.ts
import {
bool,
defineSchema,
entity,
enumOf,
f32,
list,
ref,
singleton,
str,
u8,
u16,
} from '@irtio/schema';
import { rpc } from './rpc.js';
export const schema = defineSchema(
{
players: entity({ x: f32, y: f32, name: str(24), score: u16 }),
cards: entity({ x: f32, y: f32, faceUp: bool, heldBy: ref('players').opt }),
match: singleton(
{ phase: enumOf('lobby', 'play', 'over'), round: u8, log: list(str(48), 20) },
{ serverOwned: true },
),
},
{
project: 'p_c0ffee1234abcd56',
roles: ['player', 'spectator'] as const,
rpc,
},
); Choose a collection
Use entity() for keyed records such as players or items. Use singleton() for one shared object such as the match phase. The room creates and updates these records; clients can write instances they own.
Choose field types that fit your values. For example, u8 holds integers from 0 to 255 and str(24) holds up to 24 UTF-8 bytes. f32 stores a 32-bit float. Optional values use .opt; defaults use .default(value).
The schema reference lists all field types, collection methods, options, and limits. See ownership for creating player records and controlling writes.