Implementing In Your Game
With a FIFO 2v2 matchmaker published (see Creating a Matchmaker), your backend wires up to it through three ticket calls: create a ticket, poll for the assigned server, and cancel if the player stops searching. This page follows that FIFO flow. The examples are TypeScript, matching the Colyseus example, but the API is plain REST and works from any language.
Backend-driven matchmaking
Your backend holds the GameFlow API key and makes every ticket call. The game client only asks your backend to "find a match" and waits for a server. Keeping the key on the backend means it never ships to players.
Game Client ──► Your Backend ──► GameFlow ticket API
"find match" holds API key create / poll / cancel
All calls go to the GameFlow API base URL and send your key in the X-Api-Key header.
1. Create a ticket
When a player starts searching, enqueue one ticket.
const res = await fetch(`${GAMEFLOW_API_URL}/matchmaking/tickets`, {
method: "POST",
headers: { "X-Api-Key": apiKey, "Content-Type": "application/json" },
body: JSON.stringify({
player_id: player.accountId,
game_id: gameId,
game_mode: "standard", // must match the matchmaker's Ticket Input
preferred_az: "us-east",
mu: 25, // neutral rating placeholder for FIFO
sigma: 8.333, // must be > 0
rating_bucket: 0,
tags: [],
}),
});
const { ticketId } = await res.json();
| Field | Description |
|---|---|
player_id | The player being matched. |
game_id | Your GameFlow game id. |
game_mode | Routes the ticket to the matchmaker. Must equal its Ticket Input game mode. |
preferred_az | The player's region. |
mu, sigma | The player's rating. FIFO ignores it, so send neutral placeholders. sigma must be greater than 0. |
rating_bucket | Numeric rating bucket. Send 0 for FIFO. |
tags | Optional string tags for use in Bucket or Split nodes. |
A failed create is terminal (a bad request, no published matchmaker for that mode, or a bad key). There is nothing to retry, so report it and stop.
2. Poll for the assigned server
The status endpoint long-polls: it waits up to timeout_seconds and returns as soon as
the ticket is assigned a server, or pending if still searching. Call it in a loop until
the ticket is assigned or the player cancels.
const url =
`${GAMEFLOW_API_URL}/matchmaking/tickets/${ticketId}/status?timeout_seconds=20`;
while (searching) {
const res = await fetch(url, { headers: { "X-Api-Key": apiKey } });
const { status, connection } = await res.json();
if (status === "assigned" && connection) {
const [address, port] = splitHostPort(connection); // "host:port"
sendServerToPlayer(address, port);
break;
}
// status is "pending": the request already long-polled, so just loop again.
}
For a robust loop, treat network errors, 408, 429, and 5xx as transient (back off
and retry, giving up after a few consecutive failures), and other 4xx as terminal.
3. Cancel on stop or disconnect
If the player stops searching or disconnects before matching, drop the ticket. Otherwise it lingers in the queue and gets paired with the next player, sending them to an empty server.
await fetch(
`${GAMEFLOW_API_URL}/matchmaking/tickets/${ticketId}?player_id=${playerId}`,
{ method: "DELETE", headers: { "X-Api-Key": apiKey } },
);
player_id must be the ticket owner. A 404 means the ticket was already matched or
removed, so treat it as success. Cancel from both your "stop search" handler and your
socket-close handler.
Receiving the match on the server
The status returns connection as host:port. Your backend forwards it to the player,
who connects directly to that dedicated server.
For a FIFO matchmaker the match is formed by GameFlow, but no roster is sent to the game server. The server assigns team slots as players connect, in arrival order. This is the opposite of direct allocation, where your backend already knows the teams and passes them in the payload. Read the payload only in the allocation flow; in the matchmaking flow there is none.
Full example
The Colyseus multiplayer example is a complete, working implementation of this FIFO flow: a backend-driven Quick Match that creates a ticket, long-polls with backoff, cancels on stop and disconnect, and a Colyseus server that seats matched players into a 2v2.
Related
- Creating a Matchmaker: build and publish the FIFO matchmaker.
- Custom Game Backend: direct allocation, when you already know the teams.
- Environment Variables & Metadata: the payload the server reads in the allocation flow.
- Game Server SDK: the server-side lifecycle.