PlayFlow’s matchmaking system seamlessly integrates with the lobby system to provide automated opponent finding based on skill, region, and custom criteria. This guide shows you how to implement it.

How Matchmaking Works

In PlayFlow, matchmaking always works through lobbies:
  1. A player creates a lobby (for just themself, or for a party of friends).
  2. The player (or players) sets their matchmaking data, like skill or region preference.
  3. The lobby host starts the search.
  4. The system finds a compatible lobby that is also searching.
  5. When a match is found, a game server automatically starts for all players.
This lobby-based approach naturally supports party matchmaking (friends queuing together).

Dashboard Configuration

Before writing code, you must configure your matchmaking rules in the PlayFlow Dashboard.
  1. Go to your project’s ConfigurationLobbies tab.
  2. Create or edit a lobby configuration.
  3. Click the Matchmaking tab.
  4. Add and configure matchmaking modes (e.g., “Ranked-1v1”, “Casual-4v4”).
Here is an example configuration for a 1v1 ranked mode that matches players based on their mmr and region.
{
  "teams": 2,
  "playersPerTeam": 1,
  "timeout": 120,
  "rules": [
    {
      "attribute": "mmr",
      "operator": "difference",
      "maxDifference": 200
    },
    {
      "attribute": "regions",
      "operator": "intersection"
    }
  ]
}

Implementation Guide

Here are the steps to implement matchmaking in your game.

Step 1: Set Player Matchmaking Data

Before a player starts searching for a match, they must set their matchmaking attributes (like skill and region preferences). You do this using the same UpdatePlayerState method used for other lobby data.
This example shows how to set a player’s mmr (matchmaking rating) and preferred regions. These keys must match the attributes you defined in your dashboard configuration.
using System.Collections.Generic;
using PlayFlow;
using UnityEngine;

public class MatchmakingData : MonoBehaviour
{
    public void SetMyMatchmakingData(int playerMMR)
    {
        var matchmakingData = new Dictionary<string, object>
        {
            { "mmr", playerMMR },
            { "regions", new List<string> { "us-west", "us-east" } }
        };

        PlayFlowLobbyManagerV2.Instance.UpdatePlayerState(matchmakingData,
            onSuccess: (lobby) => {
                Debug.Log("Player matchmaking data has been set.");
            },
            onError: (error) => {
                Debug.LogError($"Could not set matchmaking data: {error}");
            }
        );
    }
}
Once the player’s data is set, the lobby host can start the search by calling FindMatch. The mode parameter must match the name of the matchmaking mode you created in the dashboard.
public void StartSearch(string matchmakingMode = "Ranked-1v1")
{
    var manager = PlayFlowLobbyManagerV2.Instance;

    if (!manager.IsInLobby || !manager.IsHost)
    {
        Debug.LogWarning("Must be the host of a lobby to start matchmaking.");
        return;
    }

    manager.FindMatch(matchmakingMode,
        onSuccess: (lobby) => {
            Debug.Log($"Successfully entered the '{lobby.matchmakingMode}' queue.");
            // Update your UI to show a "searching..." state
        },
        onError: (error) => {
            Debug.LogError($"Failed to start matchmaking: {error}");
        }
    );
}

Step 3: Handle Matchmaking Events

After starting the search, you need to listen for events to know what happens next.
  • OnMatchmakingStarted: Confirms you have entered the queue.
  • OnMatchFound: The most important event! This fires when a match is found. The game server is now being launched.
  • OnMatchmakingCancelled: Fires if you cancel the search.
  • OnMatchRunning: Fires when the server is ready and provides the connection details.
void Start()
{
    var events = PlayFlowLobbyManagerV2.Instance.Events;
    
    events.OnMatchFound.AddListener(HandleMatchFound);
    events.OnMatchmakingCancelled.AddListener(HandleMatchmakingCancelled);
}

private void HandleMatchFound(Lobby lobby)
{
    Debug.Log("Match has been found! A server is being prepared.");
    // Update your UI to a "Connecting..." or "Server Ready!" state.
    // The OnMatchRunning event will fire next with the IP and Port.
}

private void HandleMatchmakingCancelled(Lobby lobby)
{
    Debug.Log("Matchmaking was cancelled.");
    // Update your UI to return to the main menu or lobby screen.
}
The host can cancel the matchmaking search at any time by calling CancelMatchmaking.
public void CancelSearch()
{
    var manager = PlayFlowLobbyManagerV2.Instance;

    if (!manager.IsHost || manager.CurrentLobby?.status != "in_queue")
    {
        return; // Can only cancel if you are the host and in the queue
    }

    manager.CancelMatchmaking(
        onSuccess: (lobby) => {
            Debug.Log("Successfully cancelled matchmaking.");
        },
        onError: (error) => {
            Debug.LogError($"Failed to cancel matchmaking: {error}");
        }
    );
}

Next Steps