> ## 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.

# Lobby Quick Start

> A practical guide to creating and managing game lobbies with code examples.

This guide provides a step-by-step walkthrough of how to use the PlayFlow Lobby SDK. We'll cover setting up, creating, managing, and joining lobbies with practical code examples.

For a high-level overview of the concepts, please see the [Beginner's Guide to Lobbies](lobby-overview).

## Prerequisites

Before you write any lobby code, make sure you have:

* **The PlayFlow Unity SDK installed** in your project.
* **A PlayFlow project** created in the [dashboard](https://app.playflowcloud.com), with your API key copied from the project's settings. Use a client key (prefix `pfclient_`) in game builds you ship to players — it is safe to embed. Keep server keys (prefix `pf_`) server-side only.
* **The SDK configured with that API key** so it can reach the lobby API.

The player ID you pass to `Initialize` becomes the identity the lobby API trusts for that client. If you have configured a player-auth provider on your project, the SDK sends a verified player token instead and the player ID is derived from it.

## Initial Setup (5 Minutes)

First, you need to get the Lobby Manager set up in your game.

### Step 1: Configure in Dashboard

Before you write any code, set up a lobby configuration in your PlayFlow project dashboard.

1. Go to your project's **Configuration** → **Lobbies** tab.
2. Create a new lobby configuration (e.g., "Default" or "Ranked").
3. Select the game server build and instance type this lobby will use.
4. Save your configuration.

### Step 2: Initialize the SDK

To use the lobby system, you must initialize it with a unique ID for the current player.

<Tabs>
  <Tab title="Unity">
    Add the `PlayFlowLobbyManagerV2` component to a GameObject in your scene. Then, in a script, call the `Initialize` method.

    ```csharp theme={null}
    using PlayFlow;
    using UnityEngine;

    public class GameInitializer : MonoBehaviour
    {
        void Start()
        {
            // Use a unique ID for each player (e.g., from a login system or device ID)
            string myPlayerId = SystemInfo.deviceUniqueIdentifier;
            
            // Initialize the manager
            PlayFlowLobbyManagerV2.Instance.Initialize(myPlayerId, () => {
                Debug.Log("PlayFlow SDK is ready to use!");
            });
        }
    }
    ```
  </Tab>

  <Tab title="Unreal Engine">
    Coming soon...
  </Tab>

  <Tab title="Godot">
    Coming soon...
  </Tab>
</Tabs>

## Basic Lobby Actions

Once the SDK is initialized, you can start performing lobby actions.

### Creating a Lobby

To create a new lobby, specify a name, the max number of players, and whether it's private.

<Tabs>
  <Tab title="Unity">
    ```csharp theme={null}
    // Create a public lobby for 4 players
    PlayFlowLobbyManagerV2.Instance.CreateLobby(
        name: "My Awesome Game Room",
        maxPlayers: 4,
        isPrivate: false,
        onSuccess: (lobby) => {
            Debug.Log($"Created public lobby! ID: {lobby.id}");
        },
        onError: (error) => Debug.LogError(error)
    );

    // Create a private lobby with an invite code
    PlayFlowLobbyManagerV2.Instance.CreateLobby(
        name: "Friends Only",
        maxPlayers: 4,
        isPrivate: true,
        onSuccess: (lobby) => {
            Debug.Log($"Created private lobby! Share this code: {lobby.code}");
        },
        onError: (error) => Debug.LogError(error)
    );
    ```
  </Tab>

  <Tab title="Unreal Engine">
    Coming soon...
  </Tab>

  <Tab title="Godot">
    Coming soon...
  </Tab>
</Tabs>

### Joining a Lobby

Every lobby gets an invite code when it is created, public and private alike. Players can join a public lobby by its ID or by its code. Private lobbies can only be joined by code — a direct join by ID is rejected.

<Tabs>
  <Tab title="Unity">
    ```csharp theme={null}
    // Join by lobby ID
    string lobbyIdToJoin = "... a lobby ID from the server list ...";
    PlayFlowLobbyManagerV2.Instance.JoinLobby(lobbyIdToJoin,
        onSuccess: (lobby) => Debug.Log("Joined lobby!"),
        onError: (error) => Debug.LogError(error)
    );

    // Join by invite code (works for both public and private lobbies)
    string inviteCode = "... a code shared by a friend ...";
    PlayFlowLobbyManagerV2.Instance.JoinLobbyByCode(inviteCode,
        onSuccess: (lobby) => Debug.Log("Joined lobby via code!"),
        onError: (error) => Debug.LogError(error)
    );
    ```
  </Tab>

  <Tab title="Unreal Engine">
    Coming soon...
  </Tab>

  <Tab title="Godot">
    Coming soon...
  </Tab>
</Tabs>

### Listing Public Lobbies

To build a server browser, you can fetch a list of all available public lobbies.

<Tabs>
  <Tab title="Unity">
    ```csharp theme={null}
    PlayFlowLobbyManagerV2.Instance.GetAvailableLobbies(
        onSuccess: (lobbies) => {
            Debug.Log($"Found {lobbies.Count} lobbies:");
            foreach (var lobby in lobbies)
            {
                Debug.Log($"  - {lobby.name} ({lobby.currentPlayers}/{lobby.maxPlayers})");
            }
            // Now you can display this list in your UI
        },
        onError: (error) => Debug.LogError(error)
    );
    ```
  </Tab>

  <Tab title="Unreal Engine">
    Coming soon...
  </Tab>

  <Tab title="Godot">
    Coming soon...
  </Tab>
</Tabs>

## Managing the Match

### Starting a Match

When everyone is ready, the host can start the match. This will begin the process of launching a dedicated server.

<Tabs>
  <Tab title="Unity">
    ```csharp theme={null}
    var manager = PlayFlowLobbyManagerV2.Instance;
    if (manager.IsHost)
    {
        manager.StartMatch(
            onSuccess: (lobby) => Debug.Log("Match starting! Waiting for server..."),
            onError: (error) => Debug.LogError(error)
        );
    }
    ```
  </Tab>

  <Tab title="Unreal Engine">
    Coming soon...
  </Tab>

  <Tab title="Godot">
    Coming soon...
  </Tab>
</Tabs>

### Connecting to the Server

After a match is started, all players in the lobby need to listen for the `OnMatchRunning` event. This event provides the IP address and port needed to connect to the game server.

<Tabs>
  <Tab title="Unity">
    ```csharp theme={null}
    void Start()
    {
        // Listen for the server ready event
        PlayFlowLobbyManagerV2.Instance.Events.OnMatchRunning.AddListener(OnServerReady);
    }

    void OnServerReady(ConnectionInfo connectionInfo)
    {
        Debug.Log($"Server is ready! Connecting to {connectionInfo.Ip}:{connectionInfo.Port}");
        
        // Use your networking library (Mirror, Netcode, FishNet, etc.) to connect here
        MyGameNetworkManager.Connect(connectionInfo.Ip, connectionInfo.Port);
    }
    ```
  </Tab>

  <Tab title="Unreal Engine">
    Coming soon...
  </Tab>

  <Tab title="Godot">
    Coming soon...
  </Tab>
</Tabs>

## Syncing Player Data

Use `UpdatePlayerState` to sync custom data for the local player, like their ready status or character choice. This data is automatically sent to all other players in the lobby.

<Tabs>
  <Tab title="Unity">
    ```csharp theme={null}
    public void SetReadyStatus(bool isReady)
    {
        var myCustomData = new Dictionary<string, object>
        {
            { "ready", isReady },
            { "character", "Wizard" },
            { "skin", "blue_robe" }
        };
        
        PlayFlowLobbyManagerV2.Instance.UpdatePlayerState(myCustomData);
    }
    ```
  </Tab>

  <Tab title="Unreal Engine">
    Coming soon...
  </Tab>

  <Tab title="Godot">
    Coming soon...
  </Tab>
</Tabs>

To read another player's data, you can access the `lobbyStateRealTime` dictionary from the `CurrentLobby` object.

## Host-Only Actions

Only the host of a lobby can perform sensitive actions:

* **Kicking a Player**: `KickPlayer(playerId)`
* **Updating Lobby Settings**: `UpdateLobby(...)` / `UpdateLobbySettings(...)`

<Info>
  **Host is assigned automatically.** There is no call to hand the host role to a specific player. When the current host leaves, host duty transfers automatically to the next player in the lobby (controlled by the lobby config's `hostLeaveBehavior`).
</Info>

<Info>
  **Player state is self-owned.** Hosts cannot push state onto other players. Each player updates their own state via `UpdatePlayerState()` and everyone reacts via `OnLobbyUpdated`. For team/role assignment, either have players pick their own team or broadcast assignments through `UpdateLobbySettings()` (host-owned) and have each client apply them locally.
</Info>

<Tabs>
  <Tab title="Unity">
    ```csharp theme={null}
    var manager = PlayFlowLobbyManagerV2.Instance;
    if (manager.IsHost)
    {
        // Kick a player
        manager.KickPlayer("... some player id ...");

        // Change the max players
        manager.UpdateLobby(maxPlayers: 8);

        // Broadcast team assignments through lobby settings (host-owned).
        // Each client reads lobby.settings["teamAssignments"] on OnLobbyUpdated.
        var assignments = new Dictionary<string, object>
        {
            { "teamAssignments", new Dictionary<string, string>
                {
                    { "player_1", "blue" }, { "player_2", "red" }
                }
            }
        };
        manager.UpdateLobbySettings(assignments);
    }
    ```
  </Tab>

  <Tab title="Unreal Engine">
    Coming soon...
  </Tab>

  <Tab title="Godot">
    Coming soon...
  </Tab>
</Tabs>

## Next Steps

<CardGroup cols={2}>
  <Card title="Matchmaking Guide" icon="swords" href="matchmaking">
    Learn how to use the matchmaking system to find opponents automatically.
  </Card>

  <Card title="Lobby Events Reference" icon="radio" href="lobby-events">
    See a full list of all the events you can subscribe to for building a responsive UI.
  </Card>
</CardGroup>
