Tier 6Lobby27 / 29
Long-lived Lobbies: less client code than you'd expect
Lobbies for the baseline matchmaking flow this article is a variant of.
There is no separate SDK call for "a lobby that outlives one match" versus "a lobby for one round." Lobby lifetime, TTL, and whether it disbands when the match starts are portal-configured per lobby type, not client parameters. The client-side flow for creating, joining, and reading a lobby is identical either way. What changes is which lobby type the client points at, and how it reads back what the server already decided.
How it works
- Lifetime is a lobby-type property read back from the server, not a call the client makes. A lobby event's payload can include a lobbyTypeDef object with a rules.disbandOnStart flag (and a teams map). A UI that needs to know "does this lobby type end when the match starts" reads that flag; it can't be set from the client.
- jsonSettings/config-override calls exist for per-instance tuning, but the meaning of that blob is server-defined. createLobbyWithConfig/createLobbyWithConfigAndPingData override a lobby type's default config for one specific instance. Which fields actually mean anything in that blob (TTL, keep-alive, which backing infrastructure) is entirely a portal/lobby-type concern, not something documented on the client method signature.
- A "room browser" instead of algorithmic matchmaking is a different call, not a different lobby type. findLobby/findOrCreateLobby do algorithmic matchmaking: rating and rules decide who a player is placed with. getLobbyInstances/getLobbyInstancesWithPingData instead list visible, existing lobby instances so a player can browse and pick one directly. That's the natural fit for a persistent "come join my room" pattern, regardless of how long that room type lives.
- The RelayTestApp/CursorParty rematch flow is this pattern in practice. END_MATCH only tears down the relay connection and per-round match state; it never calls leaveLobby/destroyLobby. From the Match Summary screen, lobby members call updateReady(false) and then updateReady(true) to queue for a rematch; once every current member has re-readied, the same lobby instance fires STARTING/ROOM_READY for the next round exactly as it did for the first, with no new findOrCreateLobby call and no new lobby. The lobby itself outlives any single match; only per-round state (relay connection, gameStartTimeMs, splotch canvas, coverage/scoreboard) resets between rounds.
Code
Reading lifetime back from a lobby event (JavaScript)
const lobbyTypeDef = result.data.lobby.lobbyTypeDef
if (lobbyTypeDef) {
state.disbandOnStart = lobbyTypeDef.rules.disbandOnStart
state.lobbyTeamNames = Object.keys(lobbyTypeDef.teams)
}
// lobbyTypeDef is only present on fuller events (e.g. MEMBER_JOIN).
// Cache it the first time you see it; it's stripped from lighter events like MEMBER_UPDATEBrowsing existing instances instead of matchmaking (C++ / any SDK, same pattern)
pBCWrapper->getLobbyService()->getLobbyInstances(lobbyType, criteriaJson, callback);
// vs. findOrCreateLobby, which algorithmically places you rather than letting you pickGotchas worth knowing up front
- What the reference ports don't demonstrate is cross-session persistence, not cross-round persistence. The rematch flow above (see "How it works" #4) is a real, working long-lived-lobby example: one lobby instance survives repeated END_MATCH → ready-up → STARTING cycles for as long as players keep queuing. None of the ports go further than that, though: nobody fully quits the app and reconnects to the same still-alive lobby later, so that narrower scenario (and the portal-side TTL/keep-alive config it depends on) is still unvalidated. Check current brainCloud docs before relying on it.
- jsonSettings/config-override fields are opaque from the client's point of view. The SDK just passes through whatever JSON it's given; the portal's lobby-type definition decides what any of those fields actually do. Pull the field list from the current lobby-type config in the portal, not a guess based on the client method signature.