Presence & lifecycle
A room is a live membership. irt.io gives you the join/leave lifecycle on the server and a connection state on the client, so “who’s here?” and “am I connected?” are never guesswork.
Server lifecycle
export default defineRoom(schema, {
onJoin(state, ctx) {
state.players[ctx.clientId] = { name: ctx.meta.name, owner: ctx.clientId };
},
onLeave(state, ctx) {
delete state.players[ctx.clientId];
},
}); ctx carries the stable clientId, any meta you passed to joinRoom, and
helpers for ownership and broadcasts.
Client connection state
const room = await joinRoom(schema);
room.onStatus((status) => {
// 'connecting' | 'live' | 'reconnecting' | 'closed'
banner.set(status);
}); Brief drops reconnect automatically and replay missed diffs. A client that stays
gone past the grace window fires onLeave server-side.
Presence metadata
For lightweight “who’s typing / who’s ready” signals that don’t belong in game state, use presence — ephemeral per-client data that isn’t persisted:
room.presence.set({ typing: true });
room.presence.subscribe((all) => renderTypingIndicators(all)); Grace, resume, and idle
| Setting | Default | Meaning |
|---|---|---|
graceMs | 15000 | how long a dropped client can resume its seat |
idleMs | 300000 | when an empty room suspends (and stops billing) |
Next steps
- Guides — put the concepts together.
- Reference: client SDK
Placeholder content.