# Matchmaking Get started with Matchmaking quickly and explore example scenarios for various genres. Matchmaking in match-based games generally aims to: * **find other players** based on criteria like region, latency, skill, or game parameters; * **search for servers** to join based on available capacity \[or ping, region, skill, map, mode]; * **start new server** if existing servers are full or don't satisfy player criteria. Player experience comes first, defining our core objectives: * high match fill rate and social feature integration (play with friends in groups), * fast matches with controlled match quality (low latency, shared preferences), * reliable and predictable matchmaking process with global availability. {% hint style="success" %} Alternatively, let players **pick a persistent (always online) server** from a list with [server-browser](https://docs.edgegap.com/learn/server-browser "mention"). {% endhint %} Follow along this video to get started with our Matchmaker service: {% embed url="" %} ## ✔️ Preparation **Testing this service is entirely free, no credit card required.** Free Tier allows up to 3 hours of runtime on our shared test cluster, after each restart. This tutorial assumes you have already: * [understood Edgegap’s deployment model](https://docs.edgegap.com/orchestration/deployments#id-1.-just-in-time-deployment-dedicated-servers), * published your server application on Edgegap ([unreal-engine](https://docs.edgegap.com/unreal-engine "mention"), [unity](https://docs.edgegap.com/unity "mention")), * successfully connected from a game client to your server on Edgegap. ### Matchmaking Architecture This guide will focus on **Matchmaking API and Backfill API**.
There are four (4) important flows of data when matchmaking is involved: 1. [Matchmaking API](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-api) **is used by Game Clients to communicate with Matchmaker:** 1. for group management, server assignment, and monitoring, 2. for ping measurement with [ping-beacons](https://docs.edgegap.com/learn/orchestration/ping-beacons "mention"). 2. [deployments](https://docs.edgegap.com/learn/orchestration/deployments "mention") API is used to deploy, scale, and manage your Dedicated Servers by Matchmaker. 3. [Netcode Transports](https://docs.edgegap.com/docs/sample-projects) are used to communicate between Game Clients and Dedicated Servers. 4. [#backfill-match](https://docs.edgegap.com/learn/matchmaker-in-depth#backfill-match "mention") **to replace or add players to a running Server.** {% hint style="info" %} After release, **your matchmaker will need to run 24/7** to ensure players across the world can join servers. {% endhint %} ## 🍀 Simple Example Start with a simple example and test the basic matchmaking player flow: * creating the matchmaker instance on the shared [#hosting-cluster](https://docs.edgegap.com/learn/matchmaker-in-depth#hosting-cluster "mention"), * defining rules and settings in your matchmaker [#configuration](https://docs.edgegap.com/learn/matchmaker-in-depth#configuration "mention"), * testing player flow and managing tickets with [#matchmaking-api](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-api "mention"). ### 1. Set Up on Free Tier ☑️ [Register for your free Edgegap account](https://app.edgegap.com/auth/register) and open the [Matchmaker dashboard page](https://app.edgegap.com/matchmaker-management-v2/matchmakers/list). ☑️ Click on **Create Matchmaker** first, then input: * matchmaker name - for your own reference, e.g. `quickstart-dev` , * upload our Simple Example JSON configuration. 🍀 **Simple Example (Minimal Recommended Configuration):** {% hint style="danger" %} **Make sure to change the application** **`name`** **and** **`version`** **to match your** [application-and-versions](https://docs.edgegap.com/learn/orchestration/application-and-versions "mention"). {% endhint %}
{
  "version": "3.2.2",
  "inspect": true,
  "max_deployment_retry_count": 3,
  "profiles": {
    "simple-example": {
      "ticket_expiration_period": "5m",
      "ticket_removal_period": "1m",
      "group_inactivity_removal_period": "5m",
      "application": {
        "name": "my-game-server",
        "version": "2024.01.30-16.23.00-UTC"
      },
      "rules": {
        "initial": {
          "match_size": {
            "type": "player_count",
            "attributes": {
              "team_count": 1,
              "min_team_size": 2,
              "max_team_size": 2
            }
          },
          "beacons": {
            "type": "latencies",
            "attributes": {
              "difference": 100,
              "max_latency": 200
            }
          }
        },
        "expansions": {}
      }
    }
  }
}
**Troubleshooting and FAQ:**
The application configuration is not valid for profile XYZ. * We couldn’t find your [application-and-versions](https://docs.edgegap.com/learn/orchestration/application-and-versions "mention"), please verify `application` values.
Docker image for '2024.01.30-16.23.00-UTC' is not cached. [**🌟 Upgrade to Pay as You Go tier**](https://app.edgegap.com/user-settings?tab=memberships) **to unlock** [**instant deployments with Caching**](https://docs.edgegap.com/orchestration/deployments#id-1.-start-a-deployment)**.** * 4GB+ uncached images may take longer to deploy, resulting in [#id-4.-deployment-error](https://docs.edgegap.com/orchestration/deployments#id-4.-deployment-error "mention"). Consider optimizing your server image size ([Unreal Engine](https://docs.edgegap.com/unreal-engine#optimize-server-build-size) / [Unity](https://docs.edgegap.com/unity#optimize-server-build-size)). * You may proceed anyway, though we recommend testing your deployment time.
☑️ If no validation errors appear, hit **Create and Start** and wait for the process to complete. This will result in a new free cluster starting, with your Simple Example matchmaker. ✅ You may now proceed to the next step. ### 2. Explore Configuration As we release updates to Matchmaker, each new version uses [semantic versioning](https://docs.edgegap.com/learn/matchmaker-in-depth#changelog) to clearly communicate the impact of changes by interpreting format `major.minor.patch`: * 🔥 `major` versions include breaking changes and require integration review, * 🌟 `minor` versions include substantial backwards-compatible improvements, * 🩹 `patch` versions include bug fixes and minor improvements. [Inspect tickets](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-api) to better understand and debug possible matchmaking flows while in development. We recommend disabling inspect API for your live matchmaker. **Some** [**deployments may result in Errors**](https://docs.edgegap.com/orchestration/deployments#id-4.-deployment-error)**.** We attempt to resolve this by retrying deployment up to `max_deployment_retry_count` times automatically (without client confirmation). To ensure that unexpected client crashes or abandoned tickets do not linger and take up your matchmaker resources, unmatched tickets will be cancelled after `ticket_expiration_period` causing their status to change to `CANCELLED` and then permanently deleted after `ticket_removal_period` . {% hint style="info" %} [Learn how matchmaker maximizes match fill rate and reduce queue times to less than 10 seconds.](https://docs.edgegap.com/learn/matchmaker-in-depth#find-match) {% endhint %} The core of our matchmaking logic is configured in [#matchmaking-profiles](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-profiles "mention"). Each profile is a completely isolated matchmaking queue, pointing to [#app-versions](https://docs.edgegap.com/orchestration/application-and-versions#app-versions "mention") with pre-defined amount of required CPU and memory (RAM) resources. [#matchmaking-rules](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-rules "mention") in the initial rule set must be met for players to be grouped together, each defined by three properties: * name of your choosing, e.g. - `match size`, * rule type, also known as operator, e.g. - `player_count`, * and lastly operator attributes, e.g. `team_count` or `max_team_size`. **Player Count Rule** This is a special rule defining how many players need to match to initiate assignment: * `team_count` refers to number of teams, 1 team may be used for cooperative or free-for-all modes, * `min_team_size` refers to the minimum number of players per team. * `max_team_size` refers to the maximum number of players per team. Our simple example demonstrates a cooperative game with 2 players. {% hint style="warning" %} Player Count rule **is required and may only be defined once** in your initial configuration rules. {% endhint %} **Latencies Rule** **`latencies`** is a special rule optimizing the ping of player matches: * reduce client-server latency by removing regions with high latency (above threshold), * improve match fairness by grouping players with similar latency (below difference).
Rule Example: beacons `beacons` rule configured with `"difference": 100, "max_latency": 200` will match: :white\_check\_mark: Alice and Bob may match: * Tokyo is discarded (>200 ms), * latency for Chicago within 100 ms absolute difference.
Beacon CityMatchabs(A - B) [ms]Alice [ms]Bob [ms]
Chicago75.012.387.3
Los Angeles113.2 145.632.4
Tokyon/an/a233.2 253.2
:x: Alice and Charlie will never match: * no beacons have < 200 ms latency for both players, * Alice lives in North America - Illinois, * Charlie lives in Asia - Japan.
Beacon CityMatchabs(A - B) [ms]Alice [ms]Charlie [ms]
Chicagon/an/a12.3215.6
Los Angelesn/an/a145.6238.3
Tokyon/an/a233.2 24.2
{% hint style="warning" %} Rule `latencies` is **optional and may only be defined once in your initial configuration** rules. {% endhint %} ✅ You may now proceed to the next step. ### 3. Review Instance Details ☑️ Review details of your new matchmaker in our dashboard once it’s initialized:
* **Status** indicates service health, may be ONLINE, OFFLINE, or ERROR. * **Identifier** helps Edgegap staff find your matchmaker quickly if you need help troubleshooting. * **Started at** can be useful to track down the latest update time. * **Size** corresponds to one of our [Pricing Tiers](https://edgegap.com/resources/pricing#matchmaker). * **API URL** will be used by Game Clients and Game Servers to communicate with your matchmaker. * **Swagger URL** is a handy openAPI specification GUI we provide to explore API schema. * **Auth Token** is a unique secret token used by Game Clients and Game Server for authentication. {% hint style="danger" %} **Edgegap staff will never ask for your tokens. Regenerate your token if you suspect a security breach.** {% endhint %} To test your new matchmaker, **you will need the Swagger URL, API URL and Auth Token**. ✅ You may now proceed to the next step. {% hint style="info" %} To update your matchmaker rules in development, edit your configuration and restart it. {% endhint %} {% hint style="success" %} See [#rolling-updates-and-ab-tests](https://docs.edgegap.com/learn/matchmaker-in-depth#rolling-updates-and-ab-tests "mention") for live games and zero-downtime updates. {% endhint %} ### 4. Test Tickets API {% hint style="info" %} **Please wait for up to 5 minutes** after starting your matchmaker to allow DNS propagation to complete. {% endhint %} ☑️ First, **open your Swagger URL** to inspect your openAPI schema in the swagger GUI:
☑️ Click on **Authorize** 🔒, paste your **Auth Token**, and confirm by clicking on **Authorize**.
☑️ Scroll down to **Ticket API** **- POST /tickets**, expand and click **Try it out**.
☑️ Preview your request: * notice `player_ip` set to `null` - this will cause Matchmaker to use the IP address automatically added to your request (see [#server-to-server-api](https://docs.edgegap.com/learn/matchmaker-in-depth#server-to-server-api "mention") for alternatives), * `profile` refers to your [#matchmaking-profiles](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-profiles "mention"), * `attributes` include values for your matchmaker rules, in this case for the `latencies` rule, * rule `player_count` is the only rule which doesn’t require any attributes in player tickets. ☑️ Click **Execute** and review the response to your player ticket request: * `id` is your unique matchmaking ticket ID, save this to check on your ticket later, * `profile` confirming the choice of [#matchmaking-profiles](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-profiles "mention"), * `group_id` is a unique [group ID issued to every ticket, a solo player is represented as a group of 1](https://docs.edgegap.com/learn/matchmaker-in-depth#group-up), * `team_id` is a unique team ID issued to every player once `TEAM_FOUND` status is reached, * [each team can contain multiple groups, not exceeding the configured team size](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-rules), * `player_ip` is the resolved public IP address of the player, regardless of the identification method, * `assignment` is set to `null` to indicate the ticket has not been matched or assigned to a server, * `created_at` provides information about when the player ticket was created for game UI usage, * `status` indicates the current status of the ticket, all tickets start in `SEARCHING` .
☑️ Create a second ticket by hitting **Execute** again, so our two players match and a server is started. ☑️ Collapse POST /tickets and open **GET /tickets/{ticketId}**, then click **Try it out**. ☑️ Input ticket ID from the response in previous step and click **Execute**.
☑️ Review the updated assignment for your player ticket: * status changed to `MATCH_FOUND` first, while keeping `assignment` set to `null` to indicate players have matched and a server is being assigned,
☑️ Click **Execute** again to check on your ticket, and review the updated assignment for your ticket: * status changed to `HOST_ASSIGNED` with `assignment` containing details of the assigned server.
Troubleshooting & FAQ My ticket is stuck in `SEARCHING` . * Please verify that you’ve created enough tickets with overlapping criteria adhering to your configuration. *** My ticket is stuck switching between `MATCH_FOUND` and `TEAM_FOUND` repeatedly. * Free Tier accounts are limited to 1 deployment at a time. Please consider upgrading or stop your current deployment to start a new one. *** My ticket goes straight to `CANCELLED`. * Your ticket reached it’s expiration. Recreate a new ticket or increase the expiration period in your configuration for testing purposes. *** I receive HTTP 404 Not Found when checking on my ticket. * Your ticket was removed either by a DELETE request, or by reaching it’s removal period (starts after ticket is expired, defined in your configuration). Recreate a new ticket or increase the expiration/removal periods in your configuration for testing purposes.
☑️ [Inspect your new deployment in our dashboard](https://app.edgegap.com/deployment-management/deployments/list): * notice each deployment is tagged with all ticket IDs and profile for added traceability.
A few seconds after finding a match, memberships proceed to `status:HOST_ASSIGNED` indicating that your [deployment is now ready and your game server is initializing](https://docs.edgegap.com/orchestration/deployments#id-3.-deployment-ready). Each player reads their `ticket_id` and `assignment` and attempt connection using the [**FQDN**](#user-content-fn-5)[^5] **(deployment URL)** and the **External Port**. Your game server may be still initializing at this time, so **players must retry connection several times**, until exceeding your usual server initialization time: {% tabs %} {% tab title="Unreal Engine" %} To **connect from PIE (Editor)** during development and testing, press the tilde key `~` and type `open {URL}:{port}` and wait for your editor to load the map. To **connect from a game client build** (and in live production environment) try * Unreal Engine [⚡ Integration Kit](https://docs.edgegap.com/learn/unreal-engine-games/developer-tools#integration-kit): * [install from Fab Marketplace](https://www.fab.com/listings/ff17ad88-12a1-49cf-9a41-31695ed11e16) (free for Personal use), * [import simple example blueprint](https://blueprintue.com/blueprint/m33u1okj/) and customize to your needs. {% hint style="success" %} In case of failed connections or dark screen consult our [troubleshooting guide](https://docs.edgegap.com/unreal-engine#troubleshooting-and-faq). {% endhint %} {% endtab %} {% tab title="Unity" %} To **connect your Unity Editor** or **game client** to your cloud deployment, input: * **Deployment** **URL** pointing to the server's IP, usually in `NetworkManager` component. * **External port** mapping to the [server's internal listen port](https://docs.edgegap.com/orchestration/application-and-versions#port-mapping), usually in a Transport component. {% hint style="success" %} In case of connection timeout or other issues consult our [troubleshooting guide](https://docs.edgegap.com/unity#troubleshooting-and-faq-4). {% endhint %} {% endtab %} {% endtabs %} {% hint style="info" %} We do not ask players to confirm the match, as we aim to provide shortest possible time to gameplay, high match fill rate, and minimize queue dodging and match cancellations. {% endhint %} Players should **save their assignment ID persistently between game restarts**, so that in case of game client crash they can retrieve the connection details and attempt reconnecting. {% hint style="success" %} See [matchmaking](https://docs.edgegap.com/learn/matchmaking "mention") and our SDKs with automatic reconnect function and more. {% endhint %} ☑️ Try connecting from your game client to the assigned server. {% hint style="warning" %} If you’re experiencing high latency, your netcode integration may be configured to simulate network latency. **Disable VPN when testing** for more realistic conditions and receive a [low-latency deployment](https://docs.edgegap.com/orchestration/deployments#server-placement). {% endhint %} ☑️ Once you verify you’re able to connect to your Deployment without issues and are done testing, **Stop your Deployment** to free up capacity in your account for the next build. ✅ You may now proceed to the next step. {% hint style="info" %} Find the openAPI specification for testing at `{matchmaker-url}/swagger/v1/swagger.json`. {% endhint %} ### 5. Game Integration Matchmaker integrates with: * **Game Client**, to [manage groups, memberships, assignments, and tickets](https://docs.edgegap.com/learn/matchmaker-in-depth#group-up), * **Dedicated Server**, to [#backfill-match](https://docs.edgegap.com/learn/matchmaker-in-depth#backfill-match "mention") after a player leaves. ☑️ In **Game Client**, we recommend providing ticket status updates to players using in-game UI for best player experience. See: * Unity [#matchmaking-sdk](https://docs.edgegap.com/unity/developer-tools#matchmaking-sdk "mention") by Edgegap: * [install package using Unity Package Manager for free](https://github.com/edgegap/edgegap-unity-gen2-sdk?tab=readme-ov-file#install-with-git-recommended), * [import simple example script](https://github.com/edgegap/edgegap-unity-gen2-sdk?tab=readme-ov-file#import-simple-example) and customize for your needs, * Unreal Engine [#integration-kit](https://docs.edgegap.com/unreal-engine/developer-tools#integration-kit "mention"): * [install from Fab Marketplace](https://www.fab.com/listings/ff17ad88-12a1-49cf-9a41-31695ed11e16) (free for Personal use), * [import simple example blueprint](https://blueprintue.com/blueprint/m33u1okj/) and customize to your needs. ☑️ In **Game Client**, ensure you’re handling retryable `429 Too Many Requests` errors with an exponential backoff and retry, giving matchmaker time to recover during sudden traffic bursts. ☑️ In **Game Client**, ensure you’re handling non-retryable errors: * `404 Not Found` - ticket has been deleted, * `500 Internal Server Error` - temporary service outage. ☑️ In **Game Server**, read player preferences and initial server context: 1. [Injected Variables (Matchmaker)](https://docs.edgegap.com/learn/matchmaker-in-depth#injected-environment-variables) **to retrieve initial players’ matchmaking data.** 2. [Injected Variables (App Versions)](https://docs.edgegap.com/orchestration/application-and-versions#other-parameters-optional) for version parameters, settings, and secrets. 3. [Injected Variables (Deployment)](https://docs.edgegap.com/orchestration/deployments#injected-environment-variables) for deployment information, IP, location, etc... {% hint style="info" %} Use [GetEnvironmentVariable in C#](https://learn.microsoft.com/en-us/dotnet/api/system.environment.getenvironmentvariable?view=net-8.0) or [GetEnvironmentVariable in C++](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Core/GenericPlatform/FGenericPlatformMisc/GetEnvironmentVariable) to get variable values. {% endhint %} ☑️ Once players connect, **Game Server and Game Clients** start a loading scene - 3D scene, a lobby-like social UI, or a loading screen with a progress bar, to indicate initialization is progressing. ☑️ Ensure your [deployment will be stopped](https://docs.edgegap.com/docs/deployment#stop-a-deployment) properly once the match concluded. 🙌 Congratulations, you’ve completed Matchmaking integration! To learn more, keep reading. ## 🏁 Advanced Example A full fledged configuration utilizing all matchmaking features including [#matchmaking-profiles](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-profiles "mention"), [#matchmaking-rules](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-rules "mention"), and [#rule-expansion](https://docs.edgegap.com/learn/matchmaker-in-depth#rule-expansion "mention") may look like this:
🏁 Advanced Example (Complete Example Configuration) ```json { "version": "3.2.2", "inspect": true, "max_deployment_retry_count": 3, "allowed_cors_origins": [ "https://*.my-game-server.com" ], "profiles": { "advanced-example": { "ticket_expiration_period": "5m", "ticket_removal_period": "1m", "group_inactivity_removal_period": "5m" "application": { "name": "my-game-server", "version": "2024.01.30-16.23.00-UTC" }, "rules": { "initial": { "match_size": { "type": "player_count", "attributes": { "team_count": 1, "min_team_size": 4, "max_team_size": 4 } }, "beacons": { "type": "latencies", "attributes": { "difference": 125, "max_latency": 125 } }, "elo_rating": { "type": "number_difference", "attributes": { "max_difference": 50 } }, "selected_game_mode": { "type": "string_equality" }, "selected_map": { "type": "intersection", "attributes": { "overlap": 1 } }, "backfill_group_size": { "type": "intersection", "attributes": { "overlap": 1 } } }, "expansions": { "30": { "elo_rating": { "max_difference": 150 }, "beacons": { "difference": 125, "max_latency": 250 } }, "60": { "elo_rating": { "max_difference": 200 } }, "180": { "match_size": { "team_count": 1, "min_team_size": 1, "max_team_size": 4 }, "beacons": { "difference": 99999, "max_latency": 99999 } } } } } } } ```
## 🎾 Custom Lobby Custom lobbies (private lobbies, sandbox levels) are a very popular option for couch multiplayer and testing new features in games before they enter main game modes. Typically require the least amount of restrictions, but aim to ensure that players can [#group-up](https://docs.edgegap.com/learn/matchmaker-in-depth#group-up "mention").
🎾 Custom Lobby Example ```json { "version": "3.2.2", "inspect": true, "max_deployment_retry_count": 3, "profiles": { "custom-lobby-example": { "ticket_expiration_period": "3m", "ticket_removal_period": "1m", "group_inactivity_removal_period": "5m" "application": { "name": "my-game-server", "version": "2024.01.30-16.23.00-UTC" }, "rules": { "initial": { "match_size": { "type": "player_count", "attributes": { "team_count": 1, "min_team_size": 4, "max_team_size": 4 } }, "lobby_id": { "type": "intersection", "attributes": { "overlap": 1 } } }, "expansions": { "10": { "match_size": { "team_count": 1, "min_team_size": 1, "max_team_size": 4 } } } } } } } ```
{% hint style="info" %} For private lobbies without public access, set `"team_size": 1` and make the group owner start the game alone. Owner may share group and host assignment details to any number of members to join up. {% endhint %} {% hint style="success" %} Add `custom-lobby-example` profile **in your existing matchmaker** to support custom lobbies. {% endhint %} ## 🥛 Backfill Showcase Building on [#simple-example](#simple-example "mention"), this configuration showcases [Backfill](https://docs.edgegap.com/learn/matchmaker-in-depth#backfill-match) with [Groups](https://docs.edgegap.com/learn/matchmaker-in-depth#group-up).
🥛 Backfill Configuration Example ```json { "version": "3.2.2", "inspect": true, "max_deployment_retry_count": 3, "profiles": { "backfill-example": { "ticket_expiration_period": "5m", "ticket_removal_period": "1m", "group_inactivity_removal_period": "5m", "application": { "name": "my-game-server", "version": "2024.01.30-16.23.00-UTC" }, "rules": { "initial": { "match_size": { "type": "player_count", "attributes": { "team_count": 1, "min_team_size": 4, "max_team_size": 4 } }, "beacons": { "type": "latencies", "attributes": { "difference": 100, "max_latency": 200 } }, "backfill_group_size": { "type": "intersection", "attributes": { "overlap": 1 } } }, "expansions": {} } } } } ```
Optionally, some games may have special matchmaking needs, such as: * allow new players to join games in progress (friends or "randoms"), * replace players who abandon (leavers) after server starts to avoid restarting match, * allow spectators to join and observe tournament or friends’ matches (e-sports), * centralize players in larger servers to provide more social interactions (MMOs). Backfill is a **server-owned ticket representing players currently connected to the server.** This ensures newly added players will respect your matchmaking rules when matched with current players. {% hint style="warning" %} [#backfill-match](https://docs.edgegap.com/learn/matchmaker-in-depth#backfill-match "mention") to replace Seat/Match sessions. Matchmaker only supports Default session. {% endhint %}

Backfill Scenarios Visualized

{% hint style="success" %} **Backfills ignore** `player_count` **rule, and always match exactly one group**. `backfill_group_size` controls team capacity with round-robin strategy, filling teams evenly in a controlled manner. {% endhint %} **The steps to complete a successful backfill are:** 1. Server creates one Backfill per team missing players, using values from: * Real `assignment` data retrieved from [#injected-environment-variables](https://docs.edgegap.com/orchestration/deployments#injected-environment-variables "mention") (deployment). * Currently connected players' `tickets`: * from [#injected-variables](https://docs.edgegap.com/learn/matchmaker-in-depth#injected-variables "mention") (matchmaker), previous backfills' `assigned_ticket` response, or mock data manipulated to match specific players, * replace `backfill_group_size` values with possible group sizes [up to available capacity](#user-content-fn-6)[^6], 2. Game clients create new tickets (memberships) and include `backfill_group_size` values: * `"1"` if the player is matchmaking alone. * [`"2"` if the player is a part of a matchmaking group with 2x members total](#user-content-fn-7)[^7]. * `"new"` if players enabled starting new games in addition to joining in-progress games. 3. Game clients proceed to [#find-match](https://docs.edgegap.com/learn/matchmaker-in-depth#find-match "mention") and pair players with the matching backfill. 4. If the backfilled group didn't completely fill the team, the server may repeat this process with the newly backfilled players' tickets, to add more players and reach desired team sizes. {% hint style="info" %} To create a Backfill-only profile, set `min_team_size` to 999,999 and disable ticket + ticket matches. {% endhint %}
🥛 Backfill Example (Backfill Showcase) ```json { "profile": "backfill-example", "attributes": { "assignment": { "request_id": "cd28e6c66554", "fqdn": "cd28e6c66554.pr.edgegap.net", "public_ip": "192.168.2.14", "ports": { "game": { "internal": 7777, "external": 56890, "link": "cd28e6c66554.pr.edgegap.net:56890", "protocol": "UDP" }, "web": { "internal": 22, "external": 57440, "link": "cd28e6c66554.pr.edgegap.net:57440", "protocol": "TCP" }, "server": { "internal": 80, "external": 50110, "link": "cd28e6c66554.pr.edgegap.net:50110", "protocol": "TCP" } }, "location": { "city": "Montreal", "country": "Canada", "continent": "North America", "administrative_division": "Quebec", "timezone": "America/Toronto" } } }, "tickets": { "c3d057h5h6f7j889fk43": { "player_ip": "174.25.48.238", "attributes": { "beacons": { "New York": 12.2, "Los Angeles": 45.3, "Paris": 78.3 }, "backfill_group_size": [ "2", "1" ] }, "group_id": "192bb97e-7fd6-4d86-8ce4-61c53c9fef16", "id": "c3d057h5h6f7j889fk43", "created_at": "2024-08-20T13:38:05.251393+00:00" }, "cqg0bg9583s738h9dkf6": { "player_ip": "217.34.85.142", "attributes": { "beacons": { "New York": 21.0, "Los Angeles": 30.2, "Paris": 101.1 }, "backfill_group_size": [ "2", "1" ] }, "group_id": "aea7df3c-d391-4ea3-a3ec-dded422fe7c8", "id": "cqg0bg9583s738h9dkf6", "created_at": "2024-08-20T13:38:05.251393+00:00" } }, "assigned_ticket": null } ```
🥛 Backfill Assignment Example (Backfill Showcase) ```json { "profile": "backfill-example", "attributes": { "assignment": { "request_id": "cd28e6c66554", "fqdn": "cd28e6c66554.pr.edgegap.net", "public_ip": "192.168.2.14", "ports": { "game": { "internal": 7777, "external": 56890, "link": "cd28e6c66554.pr.edgegap.net:56890", "protocol": "UDP" }, "web": { "internal": 22, "external": 57440, "link": "cd28e6c66554.pr.edgegap.net:57440", "protocol": "TCP" }, "server": { "internal": 80, "external": 50110, "link": "cd28e6c66554.pr.edgegap.net:50110", "protocol": "TCP" } }, "location": { "city": "Montreal", "country": "Canada", "continent": "North America", "administrative_division": "Quebec", "timezone": "America/Toronto" } } }, "tickets": { "c3d057h5h6f7j889fk43": { "player_ip": "174.25.48.238", "attributes": { "beacons": { "New York": 12.2, "Los Angeles": 45.3, "Paris": 78.3 }, "backfill_group_size": [ "2", "1" ] }, "group_id": "192bb97e-7fd6-4d86-8ce4-61c53c9fef16", "id": "c3d057h5h6f7j889fk43", "created_at": "2024-08-20T13:38:05.251393+00:00" }, "cqg0bg9583s738h9dkf6": { "player_ip": "217.34.85.142", "attributes": { "beacons": { "New York": 21.0, "Los Angeles": 30.2, "Paris": 101.1 }, "backfill_group_size": [ "2", "1" ] }, "group_id": "aea7df3c-d391-4ea3-a3ec-dded422fe7c8", "id": "cqg0bg9583s738h9dkf6", "created_at": "2024-08-20T13:38:05.251393+00:00" } }, "assigned_ticket": { "profile": "backfill-example", "player_ip": "244.13.201.244", "attributes": { "beacons": { "New York": 30.2, "Los Angeles": 10.5, "Paris": 123.9 }, "backfill_group_size": [ "new", "1" ] }, "id": "cqg0bg550h7uujd77khg", "group_id": "e0cf41c0-f88f-456e-a032-03b1d6821a9a", "created_at": "2024-08-20T13:38:08.251393+00:00", "status": "HOST_ASSIGNED" } } ```
{% hint style="info" %} See [Mirror Seat Management](https://docs.edgegap.com/docs/sample-projects/mirror-on-edgegap#bonus-seat-sessions-management) and [FishNet Seat Management](https://docs.edgegap.com/docs/sample-projects/fishnet-on-edgegap#bonus-seat-sessions-management) for **player connection monitoring**. {% endhint %} ## ⚔️ Competitive Games Competitive games focus on players competing against each other to achieve victory, whether as individuals (free for all) or teams. Ensure fair and balanced matches by pairing players or teams of similar skill levels, and maintain game pace by quickly finding fair competition.
⚔️ Competitive Game Example ```json { "version": "3.2.2", "inspect": true, "max_deployment_retry_count": 3, "profiles": { "casual-example": { "ticket_expiration_period": "5m", "ticket_removal_period": "1m", "group_inactivity_removal_period": "5m", "application": { "name": "my-game-server", "version": "2024.01.30-16.23.00-UTC" }, "rules": { "initial": { "match_size": { "type": "player_count", "attributes": { "team_count": 2, "min_team_size": 5, "max_team_size": 5 } }, "beacons": { "type": "latencies", "attributes": { "difference": 125, "max_latency": 150 } }, "selected_maps": { "type": "intersection", "attributes": { "overlap": 1 } }, "backfill_group_size": { "type": "intersection", "attributes": { "overlap": 1 } } }, "expansions": { "30": { "beacons": { "difference": 125, "max_latency": 250 } }, "180": { "beacons": { "difference": 99999, "max_latency": 99999 } } } } }, "competitive-example": { "ticket_expiration_period": "5m", "ticket_removal_period": "1m", "group_inactivity_removal_period": "5m" "application": { "name": "my-game-server", "version": "2024.01.30-16.23.00-UTC" }, "rules": { "initial": { "match_size": { "type": "player_count", "attributes": { "team_count": 2, "min_team_size": 5, "max_team_size": 5 } }, "beacons": { "type": "latencies", "attributes": { "difference": 125, "max_latency": 150 } }, "versus_ranks": { "type": "intersection", "attributes": { "overlap": 1 } } }, "expansions": { "120": { "beacons": { "difference": 125, "max_latency": 250 } } } } }, "challenger-example": { "ticket_expiration_period": "5m", "ticket_removal_period": "1m", "group_inactivity_removal_period": "5m" "application": { "name": "my-game-server", "version": "2024.01.30-16.23.00-UTC" }, "rules": { "initial": { "match_size": { "type": "player_count", "attributes": { "team_count": 2, "min_team_size": 5, "max_team_size": 5 } }, "beacons": { "type": "latencies", "attributes": { "difference": 125, "max_latency": 150 } }, "elo_rating": { "type": "number_difference", "attributes": { "max_difference": 50 } } }, "expansions": { "120": { "beacons": { "difference": 125, "max_latency": 250 } } } } } } } ```
You may **define multiple teams with 1 or more players each**, for example:
Game ModeTeam CountTeam SizeTotal Players
5v5 FPS2510
5v5 MOBA2510
20x3 Battle Royale20360
10p Free For All11010
Define multiple [#matchmaking-profiles](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-profiles "mention") for game mode specific rules and settings, and [expand as needed](https://docs.edgegap.com/learn/matchmaker-in-depth#rule-expansion). * **For all matches:** * restrict [matchmaking latency](https://docs.edgegap.com/learn/matchmaker-in-depth#ping-optimization) to prevent matching players far away, * [#group-up](https://docs.edgegap.com/learn/matchmaker-in-depth#group-up "mention") for pre-made parties and prevent exceeding team sizes, * slowly relax latency restrictions over time to find more players, * allocate more CPU or memory with different [#app-versions](https://docs.edgegap.com/orchestration/application-and-versions#app-versions "mention") for specific profiles, * **For casual matches:** * omit rank restrictions to maximize match speed and match fill rate, * let players provide their map preferences to find a map suitable for everyone, * specify backfill group size to replace leavers without exceeding team sizes, * remove latency limitations to guarantee a match after 3 minutes (180s) of queue time. * **For competitive matches:** * restrict rank to only allow opponents with similar skill level, * use rank-up or rank-down ranks to match players at the league's rank extremes. * **For the top 1% of high skill matches (challengers):** * use numerical skill ratings (ELO) to gain fine control over skill distribution in matches, * wait longer before relaxing latency requirements due to lower amount of players. {% hint style="success" %} Using multiple profiles to **separate casual game modes, competitive game modes, and top-tier challenger** players allows you to customize rules and expansions for each type of player separately. {% endhint %} ## 🤝 Cooperative Games Cooperative games require players to work together as a team towards a common goal, or AI opponent. Align players with similar preferences and gameplay habits. Replace players who leave, and improve [#connection-quality](https://docs.edgegap.com/orchestration/ping-beacons#connection-quality "mention") to provide a responsive player experience.
🤝 Cooperative Game Example ```json { "version": "3.2.2", "inspect": true, "max_deployment_retry_count": 3, "profiles": { "cooperative-example": { "ticket_expiration_period": "3m", "ticket_removal_period": "1m", "group_inactivity_removal_period": "5m", "application": { "name": "my-game-server", "version": "2024.01.30-16.23.00-UTC" }, "rules": { "initial": { "match_size": { "type": "player_count", "attributes": { "team_count": 1, "min_team_size": 4, "max_team_size": 4 } }, "beacons": { "type": "latencies", "attributes": { "difference": 125, "max_latency": 150 } }, "selected_difficulty": { "type": "string_equality" }, "selected_map": { "type": "intersection", "attributes": { "overlap": 1 } }, "player_level": { "type": "number_difference", "attributes": { "max_difference": 10 } }, "backfill_group_size": { "type": "intersection", "attributes": { "overlap": 1 } }, "moderation_flags": { "type": "intersection", "attributes": { "overlap": 1 } } }, "expansions": { "30": { "beacons": { "difference": 125, "max_latency": 250 }, "player_level": { "max_difference": 20 } }, "60": { "match_size": { "team_count": 1, "min_team_size": 2, "max_team_size": 4 } }, "150": { "match_size": { "team_count": 1, "min_team_size": 1, "max_team_size": 4 } } } } } } } ```
With team count 1 and maximum team size of 4, **require up to 4 players per match**. Define multiple [#matchmaking-profiles](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-profiles "mention") for game modes specific rules and settings: * start with minimum of 4 players to keep players in queue and maximize match fill rate, * restrict [matchmaking latency](https://docs.edgegap.com/learn/matchmaker-in-depth#ping-optimization) to prevent matching players far away, * let players choose a particular game difficulty to suit everybody’s skill level, * let players provide their map preferences to find a map suitable for everyone, * restrict player level difference to require similar degree of game progression, * specify backfill group size to replace leavers without exceeding server capacity, * use moderation flags to separate low-karma players and cheaters from general population, * [#group-up](https://docs.edgegap.com/learn/matchmaker-in-depth#group-up "mention") for pre-made parties and to fill teams without exceeding server capacity, * allocate more CPU or memory using different [#app-versions](https://docs.edgegap.com/orchestration/application-and-versions#app-versions "mention") for other profiles. Start with the ideal conditions, and [expand restrictions](https://docs.edgegap.com/learn/matchmaker-in-depth#rule-expansion) to ensure quick matches: * relax latency restrictions over time to find more players, * increase allowed player level difference to find more players, * decrease minimum team size to require less players and start the game sooner, * server may fill empty slots with AI teammates, * or [#backfill-match](https://docs.edgegap.com/learn/matchmaker-in-depth#backfill-match "mention") to add players later, * set minimum team size to 1 to launch the game solo after 150s of queue time ## 🎈 Social Games Social games focus on building connections and relationships between players through collaboration, communication, and shared experience. Support high number of players, maximize match fill rate, and align player preferences and gameplay habits. Replace players who leave, and ensure high [#connection-quality](https://docs.edgegap.com/orchestration/ping-beacons#connection-quality "mention") to provide a responsive player experience.
🎈 Social Game Example ```json { "version": "3.2.2", "inspect": true, "max_deployment_retry_count": 3, "profiles": { "social-example": { "ticket_expiration_period": "3m", "ticket_removal_period": "1m", "group_inactivity_removal_period": "5m", "application": { "name": "my-game-server", "version": "2024.01.30-16.23.00-UTC" }, "rules": { "initial": { "match_size": { "attributes": { "team_count": 1, "min_team_size": 50, "max_team_size": 50 }, "type": "player_count" }, "beacons": { "attributes": { "difference": 125, "max_latency": 150 }, "type": "latencies" }, "selected_mode": { "type": "intersection", "attributes": { "overlap": 1 } }, "backfill_group_size": { "type": "intersection", "attributes": { "overlap": 1 } }, "moderation_flags": { "type": "intersection", "attributes": { "overlap": 1 } } }, "expansions": { "15": { "beacons": { "difference": 125, "max_latency": 250 }, "match_size": { "team_count": 1, "min_team_size": 20, "max_team_size": 50 } }, "30": { "match_size": { "team_count": 1, "min_team_size": 10, "max_team_size": 50 } }, "150": { "match_size": { "team_count": 1, "min_team_size": 1, "max_team_size": 50 } } } } } } } ```
With team count 1 (free for all) and maximum team size of 50, **require up to 50 players per match**. Define [#matchmaking-profiles](https://docs.edgegap.com/learn/matchmaker-in-depth#matchmaking-profiles "mention") for game modes specific rules and settings: * restrict [matchmaking latency](https://docs.edgegap.com/learn/matchmaker-in-depth#ping-optimization) to prevent matching players far away, * let players provide their game mode preferences and find a mode suitable for everyone, * specify backfill group size to replace leavers without exceeding server capacity, * use moderation flags to separate low-karma players and cheaters from general population, * [#group-up](https://docs.edgegap.com/learn/matchmaker-in-depth#group-up "mention") for pre-made lobbies or to fill teams without exceeding server capacity, * allocate more CPU or memory using different [#app-versions](https://docs.edgegap.com/orchestration/application-and-versions#app-versions "mention") for other profiles. Start with the ideal conditions, and [expand restrictions](https://docs.edgegap.com/learn/matchmaker-in-depth#rule-expansion) to ensure quick matches: * relax latency restrictions over time to find more players, * slowly decrease minimum team size to require less players and start the game sooner, * server may fill empty slots with AI players, * or [#backfill-match](https://docs.edgegap.com/learn/matchmaker-in-depth#backfill-match "mention") to add players later, * set minimum team size to 1 to launch the game solo after 150s of queue time. [^1]: replace with your own application name [^2]: replace with your own application version [^3]: maximum difference exceeded [^4]: maximum latency exceeded [^5]: Fully Qualified Domain Name [^6]: e.g. for 3 free slots = \["3", "2", "1"] [^7]: replace "2" with the number of actual group members