> ## Documentation Index
> Fetch the complete documentation index at: https://docs.playflowcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lobbies & Matchmaking Overview

> Understand how PlayFlow lobbies and matchmaking work, and how to pick the right pattern for your game.

PlayFlow's lobby system is the bridge between **"my players want to play together"** and **"here's your dedicated game server."** It handles everything in between: creating rooms, sharing invite codes, queueing for matchmaking, forming matches, and launching game servers.

<Info>
  This is **V3**, PlayFlow's primary lobby API. It's a clean, player-centric REST API with SSE for real-time updates. If you're migrating from the older NestJS lobby system at `api.scale.computeflow.cloud`, that system continues to work — V3 is the new recommended path.
</Info>

## Core Concepts

### Lobbies

A **lobby** is a virtual room where players gather before a game starts. Every lobby has:

* A **host** — the player who created it (has admin powers: kick, settings, start game)
* A list of **players** with their individual state (ready, team, loadout, MMR, etc.)
* **Settings** — game-specific data (map, mode, difficulty) that gets passed to the game server
* A **status**: `waiting`, `in_queue`, `in_game`, etc.
* Optional **invite code** for sharing with friends

### Lobby Configs

A **lobby config** is a reusable template for lobbies. You define it once (in the dashboard or via API) and reference it by name in your code:

* `casual` — 8 players, quick play, no MMR
* `ranked_2v2` — 4 players, MMR-based matchmaking, 2 teams of 2
* `monster_hunt` — asymmetric, 1 monster vs 5 hunters

Each config specifies server size, build, matchmaking modes, rules, and more.

<Tip>
  **No dashboard config needed to get started.** Any config name in the URL path works — PlayFlow falls back to sensible defaults (2 players, 5-minute timeout, small server size, "default" build) when no matching config exists.
</Tip>

### Matchmaking

**Matchmaking** is when players queue up and the system finds them opponents. A matchmaking game is just a **group of lobbies grouped together pointing to the same game server**.

When two (or more) lobbies enter the queue and match:

1. They all transition from `in_queue` to `in_game`
2. One dedicated game server is launched
3. All matched lobbies get the same `matchId` and server connection info
4. Players connect to the server and play

Matchmaking supports:

* **Traditional teams** — 2v2, 5v5, 100-player FFA, 50-duo battle royale
* **Asymmetric roles** — 1 boss vs 5 hunters, custom team compositions
* **5 rule primitives** — `difference` (skill buckets), `equals` / `not_equals` (version, anti-rematch), `region` (overlap), `expression` (CEL for anything custom)
* **Auto-expanding buckets** — MMR ranges grow automatically as wait time grows
* **Region-aware** — weighted voting across player region preferences
* **Match confirmation** — CS2/LoL "Accept Match" dialog with configurable timeout
* **Rematch** — host can end a match and keep the same players in the lobby
* **Self-healing** — lobbies never dead-end, always recover when a server stops
* **Backfill** — new players can join matches already in progress

***

## The Two Core Flows

Most games use one of these patterns. Pick the one that fits your game.

<Tabs>
  <Tab title="Quick Match">
    **"Just put me in a game."** The player presses a button, gets connected to a server within seconds.

    <Steps>
      <Step title="Player creates a lobby">
        `POST /v3/lobbies/ranked` — instant, even with no friends.
      </Step>

      <Step title="Host starts matchmaking">
        `POST /v3/lobbies/ranked/me/matchmaking` with a mode name.
      </Step>

      <Step title="System finds opponents">
        Another queueing lobby matches within seconds.
      </Step>

      <Step title="Game server launches">
        All matched lobbies get a populated `server.network_ports[]`. Connect your game client to `host:external_port`.
      </Step>
    </Steps>

    **Best for:** Ranked ladders, competitive play, quick play modes, Counter-Strike/League of Legends-style matchmaking.
  </Tab>

  <Tab title="Invite a Friend">
    **"Create a game, share a code, friends join, start playing."**

    <Steps>
      <Step title="Host creates a lobby">
        `POST /v3/lobbies/casual` — returns an invite code like `MEOW-42`.
      </Step>

      <Step title="Friend joins with the code">
        `POST /v3/lobbies/casual/join` with `{"code": "MEOW-42"}`.
      </Step>

      <Step title="Ready up, pick teams">
        Each player sets their state: `PATCH /v3/lobbies/casual/me` with `{"state": {"ready": true, "team": "blue"}}`.
      </Step>

      <Step title="Host starts the game">
        `POST /v3/lobbies/casual/me/start` — launches a dedicated server immediately.
      </Step>
    </Steps>

    **Best for:** Party games, Among Us-style lobbies, Minecraft-style private worlds, custom matches.
  </Tab>
</Tabs>

You can combine both. A lobby can host friends, then optionally queue for matchmaking to find more players.

***

## Authentication

Every request has two headers:

| Header        | Purpose                          | Example                      |
| :------------ | :------------------------------- | :--------------------------- |
| `api-key`     | Your project's API key           | `pfclient_abc123...`         |
| `x-player-id` | Unique identifier for the player | `player_12345` or any string |

<Warning>
  `x-player-id` is **not authenticated** — it's just an identifier. PlayFlow trusts whatever value you send. For competitive games, you should verify player identity on your own backend before calling the PlayFlow API (e.g. with a JWT from your auth provider). For Phase 0 / prototyping, a random UUID per session is fine.
</Warning>

**No player auth is required** to start using lobbies. Ship an MVP with random player IDs, add real auth later when you need it.

***

## Response Shape

Every lobby endpoint returns the same consistent shape:

```json theme={null}
{
  "id": "a1b2c3d4-...",
  "code": "MEOW-42",
  "config": "ranked",
  "status": "waiting",
  "host": "player1",
  "maxPlayers": 8,
  "currentPlayers": 2,
  "region": "us-east",
  "isPrivate": false,
  "allowLateJoin": true,
  "settings": { "map": "forest" },
  "players": [
    { "id": "player1", "state": { "ready": true }, "isHost": true },
    { "id": "player2", "state": { "ready": false }, "isHost": false }
  ],
  "server": null,
  "matchmaking": null,
  "matchId": null,
  "createdAt": "2026-04-01T00:00:00Z",
  "updatedAt": "2026-04-01T00:00:01Z"
}
```

When matchmaking is active, `matchmaking` populates with `{ mode, startedAt, queueStats }`. When a game server is running, `server` populates with `{ instanceId, status, region, ports[] }`.

***

## Custom Properties

`customProperties` on a lobby config is arbitrary JSON-serializable metadata attached to every lobby of that type. PlayFlow itself never reads these values — they are surfaced to game clients in the lobby response so you can drive filters, flags, and UI labels.

```json theme={null}
{
  "customProperties": {
    "gameMode": "ctf",
    "mapRotation": ["forest", "desert", "ice"],
    "crossplayEnabled": true
  }
}
```

Use this for whatever your game needs: game modes, map rotations, skill floor labels, feature flags, regional overrides. Anything you want visible to clients when they browse lobbies.

***

## What's Next

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/lobbies/quickstart">
    Get a working lobby in 5 minutes with copy-paste curl commands.
  </Card>

  <Card title="Lobby Lifecycle" icon="arrows-rotate" href="/lobbies/lifecycle">
    Create, join, update state, kick, transfer host, start games.
  </Card>

  <Card title="Matchmaking" icon="swords" href="/lobbies/matchmaking">
    Configure modes, skill-based rules, asymmetric teams, expanding buckets.
  </Card>

  <Card title="Real-time Events" icon="bolt" href="/lobbies/real-time">
    Subscribe to SSE for live lobby updates and queue stats.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/lobbies-and-matchmaking/createlobby">
    Every endpoint with request/response schemas and try-it-out.
  </Card>
</CardGroup>
