Skip to main content
This guide shows you how to pair Epic Online Services (EOS) lobbies with PlayFlow game-server hosting. Players group up in an EOS lobby; when the lobby owner starts the match, a dedicated server is launched on PlayFlow and its address is shared back through EOS Lobby Properties so everyone can connect. The PlayFlow side is a handful of REST calls, so this works with any engine — Unreal, Unity, or custom — that can call the EOS lobby APIs and make HTTP requests.
Never ship a PlayFlow server key (pf_...) inside a game client. A client holding it could start unlimited servers on your account. Route the “start the server” call through a trusted service you control (your backend, or a serverless function). See Keeping the API key safe below for the exact options PlayFlow gives you.
Before getting started, we expect that:
  • You have a working EOS lobby flow (players can create/join a lobby and read lobby & member properties).
  • You have a PlayFlow project and an uploaded dedicated Linux server build. See Docker builds.

How it works

Step 1 — Choose a region

Edgegap places servers from a list of player IPs. PlayFlow instead takes an explicit region (one of 13 regions) — there is no IP-based auto-placement. Pick one of these approaches:
  • Simple: use a fixed region per lobby (for example, a region the players chose in a menu).
  • Geo-aware: have each member store a coarse location (from their platform or a client-side lookup) as an EOS member property, then have your service average them and pick the nearest PlayFlow region. The nearest-region helper from the PlayFab Bridge guide works unchanged here.
region is required on POST /v3/servers/start. If you can’t determine a good region, default to the one closest to most of your player base.

Step 2 — Start the server when the owner starts the match

When the lobby owner decides the match is ready, your trusted service starts a PlayFlow server. PlayFlow allocates the network ports up front, so the response already contains the address — you just have to wait for the server to finish booting before handing it out.
Start the server
Response (abridged)
Pass a ttl (seconds) as a safety net so an abandoned lobby can’t leave a server running forever. version_tag is the name of the build you uploaded to PlayFlow.

Step 3 — Wait for running, then publish the address

The server starts as launching. Poll its status until it reports running — that’s your “ready” signal — then read the address for your named port from network_ports and store it as EOS Lobby Properties.
Poll until ready
From the port named game, take host and external_port and set them as EOS Lobby Properties (for example SERVER_HOST and SERVER_PORT). EOS notifies every member of the property change.
For UDP ports (most game netcode), host is a proxy IP and external_port is the allocated port. For TCP ports, host is a PlayFlow relay hostname. Always read both from the response — never hardcode a port; it is allocated per server.

Step 4 — Members connect

When members receive the EOS property-changed notification for SERVER_HOST / SERVER_PORT, they connect their netcode transport to that address and join the match. Because you only publish the address once the server is running, members never receive a dead endpoint.

Step 5 — End the match (and rematch)

When the match is over, your service clears the EOS Lobby Properties (signalling everyone to disconnect gracefully) and terminates the PlayFlow server:
Terminate the server
If the players stay in the lobby, repeat from Step 2 to run a rematch with the same group. You can also let the server terminate itself — every PlayFlow server is handed PLAYFLOW_API_KEY, PLAYFLOW_API_URL, and PLAYFLOW_INSTANCE_ID, so it can call DELETE /v3/servers/$PLAYFLOW_INSTANCE_ID when the last player leaves.

Keeping the API key safe

The security concern is the same as any host: a client that can start servers can be abused. PlayFlow gives you two key types: By default a client key can start/stop servers. If you want a trusted service to be the only thing that can launch servers, set client_key_server_control to false in your project settings — server lifecycle calls then require a server key, closing the door on client-triggered starts entirely. Recommended: the lobby owner’s client asks your trusted service to start the match; the service holds the server key and makes the PlayFlow calls. The client never sees pf_....
Prefer not to run your own service? PlayFlow’s native lobbies and matchmaking launch the server for you and deliver connection details over a real-time channel — no external key handling required.