LobbyLab is a hosted multiplayer backend. Your game keeps its own UI, engine and domain; players join LobbyLab rooms over WebSockets through @lobbylab/client, and LobbyLab keeps the rooms, invite codes, matchmaking and shared game state. Game rules that run on LobbyLab's servers come later. Request an alpha key at https://lobbylab.gg/developers.
Status: the room engine below runs every room on lobbylab.gg today. The parts marked (API) arrive with the Multiplayer API alpha and may change before then.
Two kinds of rooms, one engine
- Rooms of games built on LobbyLab (every game on lobbylab.gg): the game's own rules run on LobbyLab's servers, and the room has a lobby, a start and an end.
- Rooms for your own game (API): your game keeps its rules; the room holds shared state, messages and members. It is open from the moment it is created (there is no start call) until it closes.
Both use the same sockets, members, reconnection and the multiplayer-wire/v0 protocol.
Rooms of games built on LobbyLab
lobby ──the host starts──> active ──the host ends it, the game ends it, the time limit, or faults──> ended
| Phase | What happens |
|---|---|
lobby | Players join and take seats. The host picks the settings, for example how many AI players fill empty seats |
active | The game runs: turn-based games change on each accepted action, live games also advance on a fixed tick |
ended | Final. Nothing more happens, and the sockets close. Start a new room to play again |
A finished match does not end the room: games show the results and offer a rematch, so everyone stays together. A live game's room ends after its time limit (at most 120 minutes) or when its rules fail three ticks in a row.
Rooms for your own game (API)
A room is open from creation until it is closed, with one of these reasons:
| Reason | When |
|---|---|
host_closed | The host closed the room |
empty | Everyone left and nobody came back within the room type's emptyTtlSec (live 10 to 600 s, default 60; turn-based 60 s to 24 h, default 15 min) |
time_limit | The room reached maxLifetimeMin (live up to 120 minutes, the default; turn-based up to 24 hours, the default) |
host_left | The host left and the room type does not hand the host role on (hostMigration: "none") |
server_closed | Your backend closed it with the secret key |
project_disabled | The project was turned off |
The host role passes to the longest-seated player when the host leaves (hostMigration: "oldest", the default), after hostGraceSec (default 10 s). A locked room refuses new joins; seated members can still reconnect.
Members
- Everyone connected to a room is a member with a
memberId, a display name, whether they are connected now, and roles. - The host starts the game (rooms of games on LobbyLab) or controls the room (API: kick, lock, room metadata, hand over the host role, close).
- Players hold seats; spectators watch and do not count toward
maxPlayers(API). - AI players fill empty seats in games that have them, chosen by the host before the start. They follow the game's own rules.
Joining
- Get a seat: its credential and socket address. On lobbylab.gg the invite link (
https://lobbylab.gg/join/<room>) does this. With the API:POST /v1/rooms/joinwith a room code,POST /v1/rooms/{roomId}/join, or quick join withPOST /v1/matchmake, which seats you in the fullest open public room of a type or creates one. - Open the WebSocket and send
hello(see the protocol doc). The server answersreadywith yourmemberId, the phase and your roles, then the current view. - Games decide whether friends can join after the start (drop in) or only in the lobby.
Room codes are 6 letters from BCDFGHJKLMNPQRSTVWXZ: no vowels, so a code never spells a word (API).
Staying connected
- Reconnecting. A new
hellowith the same seat returns the same member and a fresh view. Clients reconnect after 0.8 s, 1.6 s, 3.2 s, then every 5 s; the SDK does this for you. - Liveness. The server pings every 4 seconds and drops a socket after 2 missed pings; the member shows as disconnected until it is back.
- Seats. A
4401close means the seat credential is no longer valid: ask for a fresh one once (API:POST /v1/rooms/{roomId}/seat), then reconnect. - Leaving.
POST /v1/rooms/{roomId}/leave(API), a kick, a seat left disconnected pastseatTimeoutSec, or the project turned off. The member's sockets close with4403and the reason.
Turn-based and live rooms
Turn-based (tick: 0) | Live (tick: 20) | |
|---|---|---|
| Changes | One accepted change at a time, each saved | Each player's input slot, applied on a 20 Hz tick |
| What clients get | snapshot after each change | frame messages at the frame rate |
| Sizes (API) | state up to 64 KB | a player slot up to 1 KB; the view up to 8 KB per frame |
| Good for | Board, card, trivia and word games | Racing, arenas, action games |
Limits (API)
- 1 to 16 players per room (default 8), plus spectators (default 8, up to 32 by plan).
- A room seats at most 4 x
maxPlayersmembers over its life; after that, joins getroom_full. - A player can be in at most 3 rooms at once (
player_rooms_limit_reached). - Rooms at once and players online at once have plan limits (
rooms_limit_reached,ccu_limit_reached).
Every error code has its own page: https://lobbylab.gg/docs/errors.
How long rooms are kept
LobbyLab keeps a room's record, including the names used in it, for up to 30 days after the room ends, then deletes it. See the Privacy Policy at https://lobbylab.gg/legal/privacy.