Multiplayer --> Choose a room type
Inspect the game first. Do not infer player count, teams, or simulation type from the name. If a material field is ambiguous, stop and ask.
Decision
- Discrete actions →
createSynchronizedRoom() - A continuous host tick →
createRealtimeRoom() - Do not pick realtime because the game animates at 60 FPS.
- Do not run both room types for the same mode.
- Native clients cannot join realtime rooms. Cross-client modes use synchronized rooms.
Run the room flow with the lobby controller
Call client.createLobby({ makeRoom, minPlayers, leaderboardId }) and draw its state. It covers creating a private or public room, joining by code or from the public list, matchmaking with cancel and timeouts, leaving, and the leaderboard. Public rooms, Match, and the Leaderboard are required in every game, so do not ask the creator whether to build them. The controller draws no screens: build every one in the game’s own theme, for touch and desktop.
What every mode still needs
- Create with
createRoom()/room.create(). Create stays invite-only unless the game passes{ visibility: "public" }. - Join with
joinRoom({ inviteCode })/room.join({ inviteCode }) - Public browsing:
listPublicRooms()thenjoinPublic({ roomId }), orrefreshPublicRooms()andjoinPublic(roomId)on the lobby controller. Required in every game; do not make every room public. - A 6-digit invite code issued by Loki (16-character hex codes from 0.2.0 still join)
- Loading, waiting, reconnecting, and error UI, including a game-owned public lobby, drawn in the game’s own theme
leave()only from an explicit Leave / End Game control- Before another match from the menu,
await leave()to completion, then reset game-local match state when the room id changes - A timeout, an error message, and a way back to the menu on every Creating, Joining, and Searching screen
- The match starts from the roster: begin once the minimum members are present and the local player has a seat, and show a count such as "1 / 2" with the invite code until then. Do not gate the start on
membership === "ready"alone. - For a synchronized room, a control that commits a match action calls
dispatch()while connected, using the same snapshot check that enables the control. Draw the result from the snapshot that comes back. If the player cannot act, ordispatch()rejects, the control says so. - A Create private room control, a Create public room control, and a public room list in every game
Fine-tuning after install means confirming those fields for this title, not copying a chess lobby onto a racer. Players see the result on the play link only after the next ship.
What Loki does not supply
Physics, collision, rendering, interpolation math you did not provide, or competitive integrity. Overlay UI does not start a match.