Skip to main content
Once players share a session, the SDK connects them over your game’s networking: Netcode for GameObjects on Unity, the engine’s own networking on Unreal. The host’s game is the server. Players on the host’s network connect to it directly, and everyone else goes through Flock’s relay, so nobody forwards a port. The host lets in only the session’s players, and when the host changes, every game starts its networking again for its new part.
Scope: the relay is switched on or off per game, under Multiplayer settings.
Flock’s relay runs on Cloudflare’s network and is on for every game until it is switched off under Multiplayer settings. With it switched off, or while a studio’s relay is paused until its bill is paid, players connect on the host’s network or through a port forwarded to the host, and a player on another network gets RelayFailed (Unreal: relay_failed) with relay_not_offered or relay_paused.

Starting the netcode

One call does the whole hand-shake, for the host and for each player. On the host it starts Netcode for GameObjects as host and says where to reach it. On a player it waits for that (up to 60 seconds), connects, and proves the player’s seat.
A start that neither hosts nor connects keeps the player’s seat; call session.LeaveAsync() if the player cannot play.
How a start ended is its outcome. On Unity it is a FlockNetcodeStartOutcome; on Unreal it is a string, compared with the constants of FlockTravelToSessionOutcomes, which carry the same names (FlockTravelToSessionOutcomes::StartedAsHost is started_as_host). More can come, so keep a default.

Through the relay, or directly

FlockNetcodeOptions.Relay on Unity, and FFlockTravelToSessionOptions::Relay on Unreal, choose who goes through the relay. Set it the same on every player’s game.

Direct paths

With WhenNeeded, once the host has let a relayed player in, the two try to reach each other directly: each asks the relay, or a STUN server Flock lists, where it sees it, they swap those addresses through the relay, and each sends a few small packets to the other. When they get through both ways, the game’s packets go directly, usually a shorter path than the relay’s, and the relay has nothing left to carry. The relay stays ready: a direct path that goes quiet for 4 seconds hands the packets back to it. The game does nothing in either case. Most home routers allow this; when both sides are behind routers that give each destination a port of its own (as some mobile carriers do), the packets stay on the relay. From Unity SDK 1.83.0 and Unreal SDK 1.38.0. On Unreal, the engine’s connection carries on through each move: the host’s net driver hears the player from the same port throughout. Each move is said once in the log, at Info. A game on an Unreal SDK before 1.38.0 at either end keeps the pair on the relay, since the two sides first say whether they understand each other’s direct-path messages. The trade-off: with WhenNeeded, the host and a relayed player learn each other’s IP address once the player is let in. On Unreal, the host publishes its own addresses beside its relay address, so players can read the host’s. Use Always to keep them hidden. When the relay cannot be used, RelayFailureReason is one of these, the same on both engines unless the row says otherwise: The server can add reasons, so keep a default.

Who is joining

The host lets in only players whose seat Flock confirms, one connection each. Name players by their connection, never by what a player’s game sends. The host’s check of each joining player is billed as one API call.
The host started by StartNetcodeAsync checks each joining player itself. Find who a connection is:
Add your own check after Flock’s, such as a ban list or a team limit:
A refused player’s RefusedReason is no_join_token, join_token_invalid, already_connected, flock_unreachable, session_ended, not_host, refused_by_the_game or game_check_failed.
Both ends of a game must run Flock SDK 1.77.0 or later, and the same major version of Netcode for GameObjects: a host refuses players on an older Flock SDK, or on another major version of Netcode.

When the host changes

When the host leaves or its game stops, Flock makes the player seated longest the host and raises the session’s host-changed event on every game (HostChanged on Unity, OnHostChanged on Unreal). Neither Netcode for GameObjects nor Unreal’s networking can move a running game to a new host, so each game starts its networking again: the new host hosts, and the others join it. Do the same when this device’s relay stops working (RelayLost on Unity, OnRelayLost on Unreal).
Shut the netcode down and start it again:
Players are back about 20 seconds after a host leaves, and about a minute after a host’s game crashes (the Host timeout). Everything the old host held is gone: its spawned objects, network variables and scene state. Keep what a new host needs on every player, such as a snapshot of the game the host sends every few seconds, and rebuild from it. While waiting for a crashed host to be replaced, players lose the netcode connection first; keep the session and wait for HostChanged.

Other networking

Games on Steam, Epic Online Services or their own networking still use Flock’s parties, matchmaking, sessions and join check. They publish and read the connection themselves.
PublishDirectConnectionAsync(port) publishes this device’s own address, and a player’s connection.FindDirectAddressAsync() picks the one to use: the host’s local address on a shared network, its public address otherwise. Outside a local network, players reach that address only through a port forwarded to the host.