Realtime rooms
WebSocket rooms with presence, broadcast, in-transit chat moderation, private rooms, and history.
A realtime room is a broadcast channel with presence, backed by a Durable Object. Join a room to get a live connection; messages you send fan out to everyone else, and presence updates as players come and go.
const room = await tg.realtime.join('lobby');
room.on('presence', ({ members }) => renderRoster(members));
room.on('message', ({ from, data }) => renderChat(from, data));
room.send({ text: 'gg' }); Chat is moderated in transit
Any text in a message (a string, or an object's text field) is moderated before it reaches the room — masked or blocked per the game's policy. Non-text payloads (game state, moves) pass through untouched.
Private rooms
A room name can carry a scope: join('team:<teamId>') requires active team membership, join('match:<matchId>') requires being a participant. Non-members are refused at connect (403). Any other name is a public room.
History
Recent chat is replayed on join — room.history holds the last messages so a joiner has context immediately. Game state isn't persisted, so a high-frequency state room stays cheap.