Connect a session’s players over Netcode for GameObjects or Unreal’s own networking, through Flock’s relay when needed.
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.
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.
FlockNetcodeStartResult started = await session.StartNetcodeAsync(NetworkManager.Singleton);switch (started.Outcome){ case FlockNetcodeStartOutcome.Restarted: return; // a newer start on this NetworkManager took over case FlockNetcodeStartOutcome.StartedAsHost: ShowMessage("Hosting. Code: " + session.JoinCode); break; case FlockNetcodeStartOutcome.Connected: ShowMessage(started.ThroughRelay ? "Connected through Flock's relay." : "Connected."); break; case FlockNetcodeStartOutcome.Refused: ShowMessage("The host refused you: " + started.RefusedReason); break; case FlockNetcodeStartOutcome.RelayFailed: ShowMessage("The relay could not be used: " + started.RelayFailureReason); break; default: ShowMessage("Could not connect: " + started.Outcome); break;}
A start that neither hosts nor connects keeps the player’s seat; call session.LeaveAsync()
if the player cannot play.
One call brings each game into the session’s game, the host’s and each player’s:
TravelToSession. On the host it opens the host’s level listening for players (the engine’s
?listen) and says where to reach it. On a player it waits for that (up to 60 seconds), asks
Flock for a join token, and travels to the host, which checks the token before letting the
player in. The engine’s own net driver carries every player, through Flock’s relay too: the SDK
stands in for the other side on the device’s own loopback, so your networking code stays as it
is.Call it from your game instance: it completes once the game is in its new level, and the level
the call was made from is gone by then. Here TravelOptions is an FFlockTravelToSessionOptions
kept on the game instance, so a host change can pass the same one again.
#include "FlockSubsystem.h"#include "Multiplayer/FlockMultiplayerSession.h"// Every player's game, the host's included, once it holds the session.TravelOptions.HostLevel = TEXT("/Game/Maps/Arena"); // the level the host opens; players travel to whatever the host has openconst TWeakObjectPtr<UMyGameInstance> Game = this;Session->TravelToSession(this, TravelOptions, [Game](TFlockResult<FFlockTravelToSessionResult> Result){ if (!Game.IsValid()) { return; } if (!Result.IsSuccess()) { UE_LOG(LogTemp, Warning, TEXT("%s"), *Result.Error.ToDisplayText()); // a mistake, a refused publish or a cancel, with its fix return; } const FFlockTravelToSessionResult& Travel = Result.Value; if (Travel.Outcome == FlockTravelToSessionOutcomes::Restarted) { return; // a newer Travel To Session took over } if (Travel.Outcome == FlockTravelToSessionOutcomes::StartedAsHost) { Game->ShowMessage(TEXT("Hosting. Code: ") + Game->Session->GetJoinCode()); } else if (Travel.Outcome == FlockTravelToSessionOutcomes::Connected) { Game->ShowMessage(Travel.bThroughRelay ? TEXT("Connected through Flock's relay.") : TEXT("Connected.")); } else if (Travel.Outcome == FlockTravelToSessionOutcomes::Refused) { Game->ShowMessage(TEXT("The host refused you: ") + Travel.RefusedReason); } else if (Travel.Outcome == FlockTravelToSessionOutcomes::RelayFailed) { Game->ShowMessage(TEXT("The relay could not be used: ") + Travel.RelayFailureReason); } else { Game->ShowMessage(TEXT("Could not connect: ") + Travel.Outcome); }});
The first argument is anything in the game’s world, such as the game instance. A travel that
neither hosts nor connects keeps the player’s seat; call Session->Leave if the player cannot
play.The host’s game mode checks each joining player. Base it on AFlockGameModeBase or
AFlockGameMode, or call Flock’s check from its own PreLoginAsync; see
Who is joining. A host whose game mode does neither lets nobody in
(join_check_missing).Travel To Session needs the engine’s IP networking. A game whose net driver uses Steam’s
sockets (the Steam online subsystem’s bUseSteamNetworking, on unless set to false) cannot
listen on an IP address, and ends could_not_start. Set bUseSteamNetworking=False under
[OnlineSubsystemSteam] in Config/DefaultEngine.ini, or publish a Steam connection of your
own (see Other networking).In Blueprint, call Flock Travel To Session from the Game Instance Blueprint, where the
engine’s own NetworkError and TravelError events are; called from inside a level, it
warns in the log. It fires On Joined (started as host, or connected), On Not Joined (the
result’s Outcome and Refused Reason say why) or On Failure (a mistake, such as an ended
session), once the level has changed. Its Async Action pin hands out the node, whose
Cancel stops the travel. Compare the Outcome with the Flock Travel Outcome nodes, and
keep a default.
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.
Unity
Unreal
Meaning
StartedAsHost
started_as_host
This device hosts, and players can reach it.
Connected
connected
This device joined the host. ThroughRelay (Unreal: bThroughRelay) says whether through the relay.
Refused
refused
The host refused this player; RefusedReason says why (see Who is joining). On Unreal, the engine has taken the game back to its default level.
RelayFailed
relay_failed
The relay was needed and could not be used; RelayFailureReason says why and what to do (see below).
HostNeverPublished
host_never_published
The host did not say where to reach it within 60 seconds (FlockNetcodeOptions.WaitForHost, or WaitForHostSeconds on Unreal). Make sure the host’s game started too, then start again.
CouldNotConnect
could_not_connect
The host did not answer. On Unreal, the engine gives up after its own timeout (about 20 seconds) and loads the default level. Outside the host’s network with the relay off, forward a port to the host.
CouldNotStart
could_not_start
The host could not start. On Unity, Netcode for GameObjects refused to start, such as when the port is in use: free the port or pick another. On Unreal, the host’s level did not open listening on an IP address, such as with Steam’s sockets: turn bUseSteamNetworking off.
SessionEnded
session_ended
The session ended while waiting. Host or join another session.
NotDirect
not_direct
The host published a connection of its own kind, such as Steam; see Other networking.
Restarted
restarted
The game started again before this start ended, and the newer start took over. Nothing to do: the newer one’s answer follows.
FlockNetcodeOptions.Relay on Unity, and FFlockTravelToSessionOptions::Relay on Unreal, choose
who goes through the relay. Set it the same on every player’s game.
FlockRelayUse / EFlockRelayUse
Who goes through the relay
Pick it for
WhenNeeded (default)
Players on the host’s network try its local address for a few seconds, then the relay if it does not answer. Everyone else goes through the relay, then moves to a direct path when they and the host can reach each other.
Almost every game.
Always
Every player, on the host’s network too, and they stay on the relay. Players never learn the host’s IP address, nor the host theirs. On Unreal, the host turns away a player that reaches it another way (relay_only).
Streamers and competitive play, or networks that keep devices apart.
Never
Nobody. Players reach the host on its network, or on a port forwarded to it.
LAN games, or a game that does not want relay traffic.
await session.StartNetcodeAsync(NetworkManager.Singleton, new FlockNetcodeOptions { Relay = FlockRelayUse.Always });
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:
Reason
When
What to do
relay_not_offered
Hand out relay credentials is off for the game, or Flock lists no relay.
Turn it on under Multiplayer settings, or connect players directly.
relay_paused
The studio’s relay is paused until its bill is paid.
Settle the bill in the dashboard; meanwhile players connect directly.
relay_unreachable
The network blocks UDP to the relay, as some school, office and hotel networks do.
Check the device is online and a firewall lets the game send UDP, or try another network.
relay_not_on_this_platform
Unity only: a web player. A browser cannot send UDP.
Play from a desktop or phone build to use the relay.
relay_not_offered_by_host
The host takes nobody through the relay: its Relay is Never, or its relay could not be opened.
Set Relay the same on every player’s game; the host’s log says why its relay could not be opened.
relay_too_many_logins
More than 12 relay logins in a minute, or 10 for one player in one session.
Do not start the netcode (on Unreal, Travel To Session) in a loop; another session gives a seat of its own.
relay_server_not_listed
Flock does not list, for this player, the relay server the host is on.
Have the host start again, so both use a relay server Flock lists for each.
relay_not_in_session
Flock says the player holds no seat in the session.
Join the session again before connecting.
flock_unreachable, relay_logins_refused
Flock did not answer the request for relay logins, or refused it.
Check the device is online, then start again; the log names what Flock refused.
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.
Unity
Unreal
The host started by StartNetcodeAsync checks each joining player itself. Find who a
connection is:
string playerId = session.PlayerForConnection(clientId); // on the host
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.
The engine asks the host’s game mode about each joining player in PreLoginAsync, so the host’s
game mode calls Flock’s check there, in place of the engine’s own. The simplest way is to base
it on AFlockGameModeBase (on AGameModeBase) or AFlockGameMode (on AGameMode, for match
states): in C++, or as a Blueprint based on Flock Game Mode Base or Flock Game Mode, set
in Project Settings → Maps & Modes. Or call the check from a game mode of your own:
// MyGameMode.hvirtual void PreLoginAsync(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, const FOnPreLoginCompleteDelegate& OnComplete) override;// MyGameMode.cpp#include "Multiplayer/FlockJoinChecks.h"void AMyGameMode::PreLoginAsync(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, const FOnPreLoginCompleteDelegate& OnComplete){ // Flock's check, then the engine's own (PreLogin, such as a full game), then your own below. const TWeakObjectPtr<AMyGameMode> Mode = this; FlockJoinChecks::CheckJoiningPlayer(this, Options, Address, UniqueId, OnComplete, [Mode](const FFlockJoiningPlayer& Player, FString& OutRefusedReason) { if (Mode.IsValid() && Mode->IsBanned(Player.PlayerId)) { OutRefusedReason = TEXT("banned"); // the joining player's RefusedReason return false; } return true; });}
Your own check is optional, and runs only for a player Flock has let in. It gets the PlayerId
Flock verified, the travel’s Options without Flock’s token, and the Address (127.0.0.1 for a
player that came through Flock’s relay). On the Flock game modes, override Approve Joining
Player (ApproveJoiningPlayer) instead; it lets everyone in until overridden.Find who a connection is, on the host, such as in PostLogin:
FString PlayerId = Session->PlayerForConnection(PlayerController); // empty for a connection Flock's check did not let in
A refused player’s RefusedReason is one of FlockTravelToSessionRefusedReasons, your own
reason, or the engine’s (such as Server full.), so keep a default. The joining player’s log
names the fix too.
Reason
When
What to do
no_join_token
The player’s travel carried no token: it did not come through TravelToSession.
Connect with TravelToSession.
join_token_invalid
Flock said the token is not good for this session: made up, another session’s, expired (tokens last 60 seconds), or its player gave up the seat.
Join the session again, then travel.
already_connected
The same player is already in through another connection the host still hears from.
Close the player’s other game, then travel again.
flock_unreachable
Flock did not answer the host within 8 seconds, or the host was over its checks a minute. Nobody is let in unchecked.
Check the host’s device is online, then travel again.
session_ended
The session has ended.
Host or join another session.
not_host
The device reached no longer hosts the session.
Travel again: it finds the new host.
refused_by_the_game
Your own check turned the player away without a reason of its own.
Give the player a reason of your own.
join_check_missing
The host’s game mode does not call Flock’s check, so nobody is let in.
Base the game mode on a Flock game mode, or call CheckJoiningPlayer from its PreLoginAsync.
relay_only
The host’s Relay is Always, and the player reached it another way.
Set Relay the same on every player’s game.
In Blueprint, override Approve Joining Player on a game mode based on Flock Game Mode
Base; its Refused Reason reaches the player’s Travel To Session (empty reads as Refused By
The Game). Name players by Player For Connection on the session, such as in
OnPostLogin.
Run the same Flock Unreal SDK on every player’s game. A player on 1.30.0 or earlier sends no
join token (no_join_token), and one on 1.33.0 or earlier cannot come through the relay.
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).
Unity
Unreal
Shut the netcode down and start it again:
session.HostChanged += StartAgain;session.RelayLost += reason => StartAgain();async void StartAgain(){ if (session.HasEnded) return; NetworkManager.Singleton.Shutdown(); await session.StartNetcodeAsync(NetworkManager.Singleton); // waits for the shutdown to finish}
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.
Call TravelToSession again with the same options, from your game instance. A newer travel
ends the one under way as restarted, and does this device’s part from wherever the game is.
// Once the session is held.Session->OnHostChanged.AddDynamic(this, &UMyGameInstance::PlayAgain);Session->OnRelayLost.AddDynamic(this, &UMyGameInstance::PlayAgainAfterRelayLost);void UMyGameInstance::PlayAgain(){ if (!Session->HasEnded()) { Session->TravelToSession(this, TravelOptions, [](TFlockResult<FFlockTravelToSessionResult> Result) { // restarted: a newer call took over, and its own answer follows. }); }}void UMyGameInstance::PlayAgainAfterRelayLost(const FString& Reason){ PlayAgain();}
This game was
Now
Travel To Session
the host
still the host
Keeps its level and its players, opens its relay address again when it was lost, and publishes again. A refused publish, a cancel or a newer call leaves the level listening.
the host
a player
Stops listening (its players’ connections close), waits for the new host, and joins it.
a player
the host
Opens the level it played with the old host listening, unless HostLevel names another, and publishes.
a player
a player
Waits for the new host in the level it is in, then connects; the engine closes the old connection.
a player in the host’s game
a player, the same host
Answers connected at once and keeps its connection, so a level’s Begin Play that calls it can run on every player.
On a player, On Relay Lost is raised too when its host publishes another relay address (the
host’s own relay was lost), since the player’s relay no longer reaches it. A new host’s address is
On Host Changed’s alone.Games hear On Host Changed within about 20 seconds of a host leaving and are back in the new
host’s game about 10 seconds later (about 30 seconds in all); a host’s game that stops without
leaving is replaced a little over a minute on (the Host timeout, then Flock’s sweep), its
players back about 80 seconds on. Everything the old
host held is gone: its actors, its game state and its level’s state. Keep what a new host needs
on every player, and rebuild from it.A player’s connection to a host that went without a word times out in the engine (a minute by
default), which raises NetworkError and takes the game back to its default level. Calling
Travel To Session again from the game instance’s NetworkError event, while the session lasts,
takes the player to the session’s host, whoever that is by then. The host lets the player’s newer
connection in once it has heard nothing from the earlier one for 5 seconds, with the new join token
Travel To Session brings.In Blueprint, bind the session’s On Host Changed and On Relay Lost in the Game Instance
Blueprint, each to Flock Travel To Session with the same Options. The travel it replaces
fires On Not Joined with the Outcome Restarted, which needs nothing done. The plugin’s
multiplayer sample does exactly this:
The sample's Game Instance holds the session and binds On Host Changed and On Relay Lost to its Travel Again event.
Travel Again: Flock Travel To Session for the session held. Restarted needs nothing; any other way of not getting in gives the seat up.
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.
Unity
Unreal
// The host says how to reach it: a kind of its own and the values it needs, under 4 KB.await session.PublishConnectionAsync("steam", new Dictionary<string, object> { ["lobby"] = lobbyId.ToString() });// A player waits for it; null when the time passes or the session ends.FlockMultiplayerSessionConnection connection = await session.WaitForConnectionAsync(TimeSpan.FromSeconds(60));// The player proves its seat with a token, good for 60 seconds, sent over your own networking.FlockMultiplayerSessionJoinToken token = await session.RequestJoinTokenAsync();// The host checks it and learns who the player is; a bad token throws MultiplayerInvalidJoinToken.string playerId = await session.VerifyJoinTokenAsync(tokenFromPlayer);
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.
// The host says how to reach it: a mode of its own (32 characters at most) and the values it needs, under 4 KB.Session->PublishConnection(TEXT("steam"), FFlockCommandData().Set(TEXT("lobby"), LobbyId), nullptr);// A player waits for it: the session comes back with HasConnection(), HasEnded(), or neither when the time passes.Session->WaitForConnection(60.f, [this](TFlockResult<UFlockMultiplayerSession*> Waited){ FString Lobby; if (Waited.IsSuccess() && Waited.Value->HasConnection() && Waited.Value->GetConnection().Mode.Equals(TEXT("steam"), ESearchCase::CaseSensitive) && Waited.Value->GetConnection().Values.TryGetString(TEXT("lobby"), Lobby)) { JoinSteamLobby(Lobby); }});// The player proves its seat with a token, good for 60 seconds, sent over your own networking.Session->RequestJoinToken([this](TFlockResult<FFlockMultiplayerSessionJoinToken> Token){ if (Token.IsSuccess()) { SendToHost(Token.Value.Token); }});// The host checks it and learns who the player is; a bad token fails with MultiplayerInvalidJoinToken.Session->VerifyJoinToken(TokenFromPlayer, [this](TFlockResult<FString> PlayerId) { /* PlayerId.Value */ });
Travel To Session also ends not_direct when the host published a connection of its own,
holding it in the result’s Connection. PublishDirectConnection(Port) publishes this device’s
own address, and a player’s FindDirectAddress 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.In Blueprint these are Flock Publish Connection, Flock Wait For Connection (On
Connection, On Session Ended, On Timed Out, On Failure), Flock Request Join Token, Flock
Verify Join Token, Flock Publish Direct Connection and Flock Find Direct Address.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Qwacks","description":"Developer documentation for the Qwacks platform — Flock, Protokite, and Data Duck.","colors":{"primary":"#0099FF","light":"#33ADFF","dark":"#0077CC"},"logo":{"light":"https://mintcdn.com/qwacks/TGGmq_oWzDacAqHl/icons/qwacks.svg?fit=max\u0026auto=format\u0026n=TGGmq_oWzDacAqHl\u0026q=85\u0026s=2023abb340d6ec576975601525ab2ce9","dark":"https://mintcdn.com/qwacks/TGGmq_oWzDacAqHl/icons/qwacks.svg?fit=max\u0026auto=format\u0026n=TGGmq_oWzDacAqHl\u0026q=85\u0026s=2023abb340d6ec576975601525ab2ce9"},"favicon":"https://mintcdn.com/qwacks/TGGmq_oWzDacAqHl/icons/qwacks.svg?fit=max\u0026auto=format\u0026n=TGGmq_oWzDacAqHl\u0026q=85\u0026s=2023abb340d6ec576975601525ab2ce9","appearance":{"default":"dark","strict":true},"background":{"image":{"light":"https://mintcdn.com/qwacks/YCE61raZ52-QoE_F/officalbg.jpg?fit=max\u0026auto=format\u0026n=YCE61raZ52-QoE_F\u0026q=85\u0026s=5be5500ff5788565cf90d6a3e2111d47","dark":"https://mintcdn.com/qwacks/YCE61raZ52-QoE_F/officalbg.jpg?fit=max\u0026auto=format\u0026n=YCE61raZ52-QoE_F\u0026q=85\u0026s=5be5500ff5788565cf90d6a3e2111d47"},"color":{"light":"#FFFFFF","dark":"#181E2E"}},"navbar":{"links":[{"href":"https://www.qwacks.com/pricing","label":"Pricing"},{"href":"https://github.com/QwackStack/FlockUnitySdk/releases","label":"Unity SDK"},{"href":"https://github.com/QwackStack/FlockUnrealSdk/releases","label":"Unreal SDK"}],"primary":{"type":"button","label":"Dashboard","href":"https://flock-saas.qwacks.com"}},"fonts":{"heading":{"family":"Readex Pro"},"body":{"family":"Inter"}},"styling":{"latex":false},"navigation":{"languages":[{"language":"en","default":true,"href":"welcome"},{"language":"ar","navbar":{"links":[{"href":"https://www.qwacks.com/pricing","label":"الأسعار"},{"href":"https://github.com/QwackStack/FlockUnitySdk/releases","label":"حزمة Unity"},{"href":"https://github.com/QwackStack/FlockUnrealSdk/releases","label":"حزمة Unreal"}],"primary":{"type":"button","label":"لوحة التحكم","href":"https://flock-saas.qwacks.com"}},"href":"ar/welcome"}]}},"deployment":{"deploymentMetadataValue":{"subdomain":"qwacks","hasAudioNarration":false,"actualSubdomain":"qwacks","customDomains":["docs.qwacks.com"],"gitSource":{"type":"github","owner":"qwackstack","repo":"qwacksdocs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ad7565dec8f6cfd63f72435","collectionId":"683d8a2a-c390-4740-a56a-0aa4239bfbdc","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ad7565dec8f6cfd63f72435"},"feedback":{"thumbs":true},"entitlements":{},"buildId":"6ad7565dec8f6cfd63f72435","clientVersion":"0.0.3926","searchFilterCounts":[{"language":"ar","tag":"Flock","count":29},{"language":"en","tag":"Flock","count":29},{"language":"ar","tag":"الميزات","count":15},{"language":"en","tag":"Features","count":15},{"language":"ar","tag":"Qwacks","count":12},{"language":"en","tag":"Qwacks","count":12},{"language":"ar","tag":"بدء الاستخدام","count":9},{"language":"en","tag":"Getting Started","count":9},{"language":"ar","tag":"اللعب الجماعي","count":5},{"language":"ar","tag":"Protokite","count":5},{"language":"ar","tag":"المدفوعات والفوترة","count":5},{"language":"en","tag":"Multiplayer","count":5},{"language":"en","tag":"Protokite","count":5},{"language":"en","tag":"Payments \u0026 Billing","count":5},{"language":"ar","tag":"المفاهيم","count":3},{"language":"ar","tag":"الاستوديوهات والفريق","count":3},{"language":"en","tag":"Concepts","count":3},{"language":"en","tag":"Studios \u0026 Team","count":3},{"language":"ar","tag":"Unity","count":2},{"language":"en","tag":"Unity","count":2}]},"assistantConfig":{},"hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":true},"customCss":[{"filePath":"style.css","content":".nav-logo{height:2.5rem!important;max-width:none!important}#topbar-cta-button .bg-primary-dark{background-color:#feca13!important}#topbar-cta-button:hover .bg-primary-dark{background-color:#f89c1c!important}#topbar-cta-button a,#topbar-cta-button a *{color:#1a1206!important}.qwacks-lang-toggle{display:inline-flex;align-items:center;align-self:center;gap:.5rem;padding:.25rem 1rem;border:1px solid rgba(255,255,255,.1);border-radius:56px;background:0 0;color:#fafafa;font-family:\"Readex Pro\",sans-serif;font-size:.875rem;line-height:1.25rem;white-space:nowrap;margin-inline-start:auto;margin-inline-end:1rem}.qwacks-lang-toggle__option{color:inherit;text-decoration:none;font-weight:400;opacity:.3}.qwacks-lang-toggle__option:hover{opacity:.7}.qwacks-lang-toggle__option.is-active{font-weight:700;opacity:1}@media (min-width:1024px){#localization-select-trigger{display:none!important}}:is(h1, h2, h3, h4){position:relative}:is(h1, h2, h3, h4)>div.absolute{left:auto;right:auto;inset-inline-end:0}:is(h1, h2, h3, h4)>div.absolute>a{margin-inline:0!important}"},{"filePath":"rtl.css","content":"[dir=rtl],html[data-current-path^=\"/ar\"],html[lang=ar]{direction:rtl}@media (min-width:1024px){html[lang=ar] .lg\\:-ml-12{margin-left:0;margin-right:-3rem}html[lang=ar] .lg\\:pl-\\[5\\.7rem\\]{padding-left:.25rem;padding-right:5.7rem}html[lang=ar] .lg\\:pl-\\[23\\.7rem\\]{padding-left:.25rem;padding-right:23.7rem}}[dir=rtl] :is(pre, code, kbd, samp){direction:ltr;text-align:left}[dir=rtl] :not(pre)>code{unicode-bidi:isolate}[dir=rtl] pre>*{direction:ltr}[dir=rtl] .pl-3\\.5{padding-left:0;padding-right:.875rem}[dir=rtl] .pl-3{padding-left:0;padding-right:.75rem}[dir=rtl] .pl-4{padding-left:0;padding-right:1rem}[dir=rtl] .pr-3{padding-right:0;padding-left:.75rem}[dir=rtl] .pr-4{padding-right:0;padding-left:1rem}[dir=rtl] .pr-8{padding-right:0;padding-left:2rem}[dir=rtl] .ml-2{margin-left:0;margin-right:.5rem}[dir=rtl] .ml-4{margin-left:0;margin-right:1rem}[dir=rtl] .-ml-4{margin-left:0;margin-right:-1rem}[dir=rtl] .-ml-10{margin-left:0;margin-right:-2.5rem}[dir=rtl] .mr-2{margin-right:0;margin-left:.5rem}[dir=rtl] .mr-4{margin-right:0;margin-left:1rem}[dir=rtl] .text-left{text-align:right}[dir=rtl] .text-right{text-align:left}[dir=rtl] .left-0{left:auto;right:0}[dir=rtl] .right-0{right:auto;left:0}[dir=rtl] .space-x-2>:not([hidden])~:not([hidden]),[dir=rtl] .space-x-3>:not([hidden])~:not([hidden]),[dir=rtl] .space-x-4>:not([hidden])~:not([hidden]){--tw-space-x-reverse:1}[dir=rtl] .border-l{border-left-width:0;border-right-width:1px}[dir=rtl] .border-r{border-right-width:0;border-left-width:1px}@media (min-width:1024px){[dir=rtl] .lg\\:-ml-12{margin-left:0;margin-right:-3rem}}[dir=rtl] :is(ul, ol){padding-left:0;padding-right:1.5rem}[dir=rtl] blockquote{border-left:0;border-right:4px solid currentColor;padding-left:0;padding-right:1rem}[dir=rtl] :is(th, td){text-align:right}[dir=rtl] .steps{margin-left:0;margin-right:.875rem}[dir=rtl] .step>.absolute:not(.w-px){margin-left:0;margin-right:-13px}[dir=rtl] .step>:not(.absolute){padding-left:1px;padding-right:2rem}[dir=rtl] #table-of-contents{padding-inline-start:.75rem;scrollbar-gutter:stable}[dir=rtl] #sidebar-content a[style*=padding-left]{padding-left:0!important;padding-right:1rem!important}[dir=rtl] .card .absolute{right:auto;left:1.25rem}[dir=rtl] #topbar-cta-button svg,[dir=rtl] .card .absolute svg{transform:scaleX(-1)}[dir=rtl] :is(.qwacks-flip-icon, [data-flip-rtl]) svg{transform:scaleX(-1)}[dir=rtl] .qwacks-lang-toggle svg{transform:none}[dir=rtl],[dir=rtl] body{font-family:\"Readex Pro\",system-ui,sans-serif;letter-spacing:normal;line-height:1.85}[dir=rtl] :is(h1, h2, h3, h4, h5, h6){font-family:\"Readex Pro\",system-ui,sans-serif;letter-spacing:normal;line-height:1.5}[dir=rtl] :is(pre, code, kbd, samp){font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;line-height:1.6}[dir=rtl]{font-variant-numeric:lining-nums}"}],"page":{"pagePath":"guides/connecting-players","slug":"/guides/connecting-players","pageMetadata":{"title":"Connecting Players","description":"Connect a session's players over Netcode for GameObjects or Unreal's own networking, through Flock's relay when needed.","href":"/guides/connecting-players"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Connect a session’s players over Netcode for GameObjects or Unreal’s own networking, through Flock’s relay when needed.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];const Scope=({children})=>{const{Info}=_provideComponents()||{};if(!Info)_missingMdxReference(`Info`,true);return _jsxs(Info,{children:[_jsx(`b`,{children:`Scope:`}),` `,children]})};function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,..._provideComponents(),...props.components},{CodeBlock,CodeGroup,Frame,Heading,Note,OptimizedImage,Tab,Table,Tabs,_MdxComponentBoundary}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!CodeGroup)_missingMdxReference(`CodeGroup`,true);if(!Frame)_missingMdxReference(`Frame`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);if(!_MdxComponentBoundary)_missingMdxReference(`_MdxComponentBoundary`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Once players share a `,_jsx(_components.a,{href:`/guides/sessions`,children:`session`}),`, the SDK connects them over your game’s\nnetworking: Netcode for GameObjects on Unity, the engine’s own networking on Unreal. The host’s\ngame is the server. Players on the host’s network connect to it directly, and everyone else goes\nthrough `,_jsx(_components.strong,{children:`Flock’s relay`}),`, so nobody forwards a port. The host lets in only the session’s players,\nand when the host changes, every game starts its networking again for its new part.`]}),`\n`,_jsx(_MdxComponentBoundary,{name:`Scope`,children:_jsxs(Scope,{children:[`the relay is switched on or off per `,_jsx(_components.strong,{children:`game`}),`, under `,_jsx(_components.strong,{children:`Multiplayer settings`}),`.`]})}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`Flock’s relay runs on Cloudflare’s network and is on for every game until it is switched off under `,_jsx(_components.strong,{children:`Multiplayer\nsettings`}),`. With it switched off, or while a studio’s relay is paused until its bill is paid, players connect on the\nhost’s network or through a port forwarded to the host, and a player on another network gets `,_jsx(_components.code,{children:`RelayFailed`}),` (Unreal:\n`,_jsx(_components.code,{children:`relay_failed`}),`) with `,_jsx(_components.code,{children:`relay_not_offered`}),` or `,_jsx(_components.code,{children:`relay_paused`}),`.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`starting-the-netcode`,children:`Starting the netcode`}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`Unity`,id:`unity`,children:[_jsx(_components.p,{children:`One call does the whole hand-shake, for the host and for each player. On the host it starts\nNetcode for GameObjects as host and says where to reach it. On a player it waits for that (up to\n60 seconds), connects, and proves the player’s seat.`}),_jsx(CodeBlock,{filename:``,numberOfLines:`21`,language:`csharp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`csharp`,children:_jsxs(_components.code,{language:`csharp`,numberOfLines:`21`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FlockNetcodeStartResult`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` started`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`StartNetcodeAsync`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`NetworkManager`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Singleton`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`switch`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`started`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Outcome`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` case`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockNetcodeStartOutcome`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`Restarted`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`; `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// a newer start on this NetworkManager took over`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` case`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockNetcodeStartOutcome`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`StartedAsHost`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Hosting. Code: \"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` +`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`JoinCode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` break`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` case`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockNetcodeStartOutcome`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`Connected`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`started`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`ThroughRelay`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ?`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Connected through Flock's relay.\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` :`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Connected.\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` break`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` case`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockNetcodeStartOutcome`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`Refused`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"The host refused you: \"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` +`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` started`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RefusedReason`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` break`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` case`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockNetcodeStartOutcome`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`RelayFailed`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"The relay could not be used: \"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` +`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` started`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RelayFailureReason`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` break`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` default`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Could not connect: \"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` +`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` started`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Outcome`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` break`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsxs(_components.p,{children:[`A start that neither hosts nor connects keeps the player’s seat; call `,_jsx(_components.code,{children:`session.LeaveAsync()`}),`\nif the player cannot play.`]})]}),_jsxs(Tab,{title:`Unreal`,id:`unreal`,children:[_jsxs(_components.p,{children:[`One call brings each game into the session’s game, the host’s and each player’s:\n`,_jsx(_components.code,{children:`TravelToSession`}),`. On the host it opens the host’s level listening for players (the engine’s\n`,_jsx(_components.code,{children:`?listen`}),`) and says where to reach it. On a player it waits for that (up to 60 seconds), asks\nFlock for a join token, and travels to the host, which checks the token before letting the\nplayer in. The engine’s own net driver carries every player, through Flock’s relay too: the SDK\nstands in for the other side on the device’s own loopback, so your networking code stays as it\nis.`]}),_jsxs(_components.p,{children:[`Call it from your game instance: it completes once the game is in its new level, and the level\nthe call was made from is gone by then. Here `,_jsx(_components.code,{children:`TravelOptions`}),` is an `,_jsx(_components.code,{children:`FFlockTravelToSessionOptions`}),`\nkept on the game instance, so a host change can pass the same one again.`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`43`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`43`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`#include`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"FlockSubsystem.h\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`#include`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Multiplayer/FlockMultiplayerSession.h\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Every player's game, the host's included, once it holds the session.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TravelOptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`HostLevel`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"/Game/Maps/Arena\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // the level the host opens; players travel to whatever the host has open`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` TWeakObjectPtr`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`UMyGameInstance`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Game `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TravelToSession`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, TravelOptions, [`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`Game`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`](`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`TFlockResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FFlockTravelToSessionResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`Result`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Game`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`IsValid`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`())`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Result`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`IsSuccess`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`())`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` UE_LOG`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(LogTemp, Warning, `}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#9CDCFE`},children:`%s`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`), `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`*`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Result`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Error`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`ToDisplayText`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`());`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // a mistake, a refused publish or a cancel, with its fix`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FFlockTravelToSessionResult`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Travel `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Result`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Value`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Outcome`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ==`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockTravelToSessionOutcomes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::Restarted)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // a newer Travel To Session took over`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Outcome`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ==`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockTravelToSessionOutcomes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::StartedAsHost)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Game`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Hosting. Code: \"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`+`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Game`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`GetJoinCode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`());`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` else`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Outcome`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ==`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockTravelToSessionOutcomes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::Connected)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Game`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`bThroughRelay`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ?`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Connected through Flock's relay.\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Connected.\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`));`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` else`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Outcome`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ==`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockTravelToSessionOutcomes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::Refused)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Game`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"The host refused you: \"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`+`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RefusedReason`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` else`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Outcome`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ==`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockTravelToSessionOutcomes`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::RelayFailed)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Game`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"The relay could not be used: \"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`+`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RelayFailureReason`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` else`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Game`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`ShowMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Could not connect: \"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`+`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Outcome`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),_jsxs(_components.p,{children:[`The first argument is anything in the game’s world, such as the game instance. A travel that\nneither hosts nor connects keeps the player’s seat; call `,_jsx(_components.code,{children:`Session->Leave`}),` if the player cannot\nplay.`]}),_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`The host’s game mode checks each joining player.`}),` Base it on `,_jsx(_components.code,{children:`AFlockGameModeBase`}),` or\n`,_jsx(_components.code,{children:`AFlockGameMode`}),`, or call Flock’s check from its own `,_jsx(_components.code,{children:`PreLoginAsync`}),`; see\n`,_jsx(_components.a,{href:`#who-is-joining`,children:`Who is joining`}),`. A host whose game mode does neither lets nobody in\n(`,_jsx(_components.code,{children:`join_check_missing`}),`).`]}),_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Travel To Session needs the engine’s IP networking.`}),` A game whose net driver uses Steam’s\nsockets (the Steam online subsystem’s `,_jsx(_components.code,{children:`bUseSteamNetworking`}),`, on unless set to false) cannot\nlisten on an IP address, and ends `,_jsx(_components.code,{children:`could_not_start`}),`. Set `,_jsx(_components.code,{children:`bUseSteamNetworking=False`}),` under\n`,_jsx(_components.code,{children:`[OnlineSubsystemSteam]`}),` in `,_jsx(_components.code,{children:`Config/DefaultEngine.ini`}),`, or publish a Steam connection of your\nown (see `,_jsx(_components.a,{href:`#other-networking`,children:`Other networking`}),`).`]}),_jsxs(_components.p,{children:[`In Blueprint, call `,_jsx(_components.strong,{children:`Flock Travel To Session`}),` from the Game Instance Blueprint, where the\nengine’s own `,_jsx(_components.strong,{children:`NetworkError`}),` and `,_jsx(_components.strong,{children:`TravelError`}),` events are; called from inside a level, it\nwarns in the log. It fires `,_jsx(_components.strong,{children:`On Joined`}),` (started as host, or connected), `,_jsx(_components.strong,{children:`On Not Joined`}),` (the\nresult’s Outcome and Refused Reason say why) or `,_jsx(_components.strong,{children:`On Failure`}),` (a mistake, such as an ended\nsession), once the level has changed. Its `,_jsx(_components.strong,{children:`Async Action`}),` pin hands out the node, whose\n`,_jsx(_components.strong,{children:`Cancel`}),` stops the travel. Compare the Outcome with the `,_jsx(_components.strong,{children:`Flock Travel Outcome`}),` nodes, and\nkeep a default.`]})]})]}),`\n`,_jsxs(_components.p,{children:[`How a start ended is its outcome. On Unity it is a `,_jsx(_components.code,{children:`FlockNetcodeStartOutcome`}),`; on Unreal it is a\nstring, compared with the constants of `,_jsx(_components.code,{children:`FlockTravelToSessionOutcomes`}),`, which carry the same names\n(`,_jsx(_components.code,{children:`FlockTravelToSessionOutcomes::StartedAsHost`}),` is `,_jsx(_components.code,{children:`started_as_host`}),`). More can come, so keep a\ndefault.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Unity`}),_jsx(_components.th,{children:`Unreal`}),_jsx(_components.th,{children:`Meaning`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`StartedAsHost`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`started_as_host`})}),_jsx(_components.td,{children:`This device hosts, and players can reach it.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Connected`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`connected`})}),_jsxs(_components.td,{children:[`This device joined the host. `,_jsx(_components.code,{children:`ThroughRelay`}),` (Unreal: `,_jsx(_components.code,{children:`bThroughRelay`}),`) says whether through the relay.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Refused`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`refused`})}),_jsxs(_components.td,{children:[`The host refused this player; `,_jsx(_components.code,{children:`RefusedReason`}),` says why (see `,_jsx(_components.a,{href:`#who-is-joining`,children:`Who is joining`}),`). On Unreal, the engine has taken the game back to its default level.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`RelayFailed`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_failed`})}),_jsxs(_components.td,{children:[`The relay was needed and could not be used; `,_jsx(_components.code,{children:`RelayFailureReason`}),` says why and what to do (see below).`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`HostNeverPublished`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`host_never_published`})}),_jsxs(_components.td,{children:[`The host did not say where to reach it within 60 seconds (`,_jsx(_components.code,{children:`FlockNetcodeOptions.WaitForHost`}),`, or `,_jsx(_components.code,{children:`WaitForHostSeconds`}),` on Unreal). Make sure the host’s game started too, then start again.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`CouldNotConnect`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`could_not_connect`})}),_jsx(_components.td,{children:`The host did not answer. On Unreal, the engine gives up after its own timeout (about 20 seconds) and loads the default level. Outside the host’s network with the relay off, forward a port to the host.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`CouldNotStart`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`could_not_start`})}),_jsxs(_components.td,{children:[`The host could not start. On Unity, Netcode for GameObjects refused to start, such as when the port is in use: free the port or pick another. On Unreal, the host’s level did not open listening on an IP address, such as with Steam’s sockets: turn `,_jsx(_components.code,{children:`bUseSteamNetworking`}),` off.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`SessionEnded`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`session_ended`})}),_jsx(_components.td,{children:`The session ended while waiting. Host or join another session.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`NotDirect`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`not_direct`})}),_jsxs(_components.td,{children:[`The host published a connection of its own kind, such as Steam; see `,_jsx(_components.a,{href:`#other-networking`,children:`Other networking`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Restarted`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`restarted`})}),_jsx(_components.td,{children:`The game started again before this start ended, and the newer start took over. Nothing to do: the newer one’s answer follows.`})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`through-the-relay-or-directly`,children:`Through the relay, or directly`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`FlockNetcodeOptions.Relay`}),` on Unity, and `,_jsx(_components.code,{children:`FFlockTravelToSessionOptions::Relay`}),` on Unreal, choose\nwho goes through the relay. Set it the same on every player’s game.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsxs(_components.th,{children:[_jsx(_components.code,{children:`FlockRelayUse`}),` / `,_jsx(_components.code,{children:`EFlockRelayUse`})]}),_jsx(_components.th,{children:`Who goes through the relay`}),_jsx(_components.th,{children:`Pick it for`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`WhenNeeded`}),` (default)`]}),_jsx(_components.td,{children:`Players on the host’s network try its local address for a few seconds, then the relay if it does not answer. Everyone else goes through the relay, then moves to a direct path when they and the host can reach each other.`}),_jsx(_components.td,{children:`Almost every game.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Always`})}),_jsxs(_components.td,{children:[`Every player, on the host’s network too, and they stay on the relay. Players never learn the host’s IP address, nor the host theirs. On Unreal, the host turns away a player that reaches it another way (`,_jsx(_components.code,{children:`relay_only`}),`).`]}),_jsx(_components.td,{children:`Streamers and competitive play, or networks that keep devices apart.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`Never`})}),_jsx(_components.td,{children:`Nobody. Players reach the host on its network, or on a port forwarded to it.`}),_jsx(_components.td,{children:`LAN games, or a game that does not want relay traffic.`})]})]})]}),`\n`,_jsxs(CodeGroup,{children:[_jsx(CodeBlock,{filename:`Unity`,numberOfLines:`1`,language:`csharp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`csharp`,children:_jsxs(_components.code,{language:`csharp`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`StartNetcodeAsync`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`NetworkManager`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Singleton`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`new`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockNetcodeOptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Relay`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` FlockRelayUse`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Always`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Unreal`,numberOfLines:`2`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TravelOptions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Relay`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` EFlockRelayUse`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::Always;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TravelToSession`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, TravelOptions, [](`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`TFlockResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FFlockTravelToSessionResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`Travel`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` /* ... */`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`]})})})]}),`\n`,_jsx(Heading,{level:`3`,id:`direct-paths`,children:`Direct paths`}),`\n`,_jsxs(_components.p,{children:[`With `,_jsx(_components.code,{children:`WhenNeeded`}),`, once the host has let a relayed player in, the two try to reach each other directly: each asks the relay,\nor 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\nthrough both ways, the game’s packets go directly, usually a shorter path than the relay’s, and the relay has nothing left to\ncarry. The relay stays ready: a direct path that goes quiet for 4 seconds hands the packets back to it. The game does nothing in\neither case. Most home routers allow this; when both sides are behind routers that give each destination a port of its own (as\nsome mobile carriers do), the packets stay on the relay. From Unity SDK 1.83.0 and Unreal SDK 1.38.0.`]}),`\n`,_jsx(_components.p,{children:`On Unreal, the engine’s connection carries on through each move: the host’s net driver hears the player from the same port\nthroughout. 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\nthe relay, since the two sides first say whether they understand each other’s direct-path messages.`}),`\n`,_jsxs(_components.p,{children:[`The trade-off: with `,_jsx(_components.code,{children:`WhenNeeded`}),`, the host and a relayed player learn each other’s IP address once the player is let in. On\nUnreal, the host publishes its own addresses beside its relay address, so players can read the host’s. Use `,_jsx(_components.code,{children:`Always`}),` to keep\nthem hidden.`]}),`\n`,_jsxs(_components.p,{children:[`When the relay cannot be used, `,_jsx(_components.code,{children:`RelayFailureReason`}),` is one of these, the same on both engines unless the row says otherwise:`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Reason`}),_jsx(_components.th,{children:`When`}),_jsx(_components.th,{children:`What to do`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_not_offered`})}),_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`Hand out relay credentials`}),` is off for the game, or Flock lists no relay.`]}),_jsxs(_components.td,{children:[`Turn it on under `,_jsx(_components.strong,{children:`Multiplayer settings`}),`, or connect players directly.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_paused`})}),_jsx(_components.td,{children:`The studio’s relay is paused until its bill is paid.`}),_jsx(_components.td,{children:`Settle the bill in the dashboard; meanwhile players connect directly.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_unreachable`})}),_jsx(_components.td,{children:`The network blocks UDP to the relay, as some school, office and hotel networks do.`}),_jsx(_components.td,{children:`Check the device is online and a firewall lets the game send UDP, or try another network.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_not_on_this_platform`})}),_jsx(_components.td,{children:`Unity only: a web player. A browser cannot send UDP.`}),_jsx(_components.td,{children:`Play from a desktop or phone build to use the relay.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_not_offered_by_host`})}),_jsxs(_components.td,{children:[`The host takes nobody through the relay: its `,_jsx(_components.code,{children:`Relay`}),` is `,_jsx(_components.code,{children:`Never`}),`, or its relay could not be opened.`]}),_jsxs(_components.td,{children:[`Set `,_jsx(_components.code,{children:`Relay`}),` the same on every player’s game; the host’s log says why its relay could not be opened.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_too_many_logins`})}),_jsx(_components.td,{children:`More than 12 relay logins in a minute, or 10 for one player in one session.`}),_jsx(_components.td,{children:`Do not start the netcode (on Unreal, Travel To Session) in a loop; another session gives a seat of its own.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_server_not_listed`})}),_jsx(_components.td,{children:`Flock does not list, for this player, the relay server the host is on.`}),_jsx(_components.td,{children:`Have the host start again, so both use a relay server Flock lists for each.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_not_in_session`})}),_jsx(_components.td,{children:`Flock says the player holds no seat in the session.`}),_jsx(_components.td,{children:`Join the session again before connecting.`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`flock_unreachable`}),`, `,_jsx(_components.code,{children:`relay_logins_refused`})]}),_jsx(_components.td,{children:`Flock did not answer the request for relay logins, or refused it.`}),_jsx(_components.td,{children:`Check the device is online, then start again; the log names what Flock refused.`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`relay_wrong_login`}),`, `,_jsx(_components.code,{children:`relay_full`}),`, `,_jsx(_components.code,{children:`relay_open_refused`}),`, `,_jsx(_components.code,{children:`relay_refused`})]}),_jsx(_components.td,{children:`The relay server refused the login, had no room, would not let the host’s packets in, or refused for another reason.`}),_jsx(_components.td,{children:`Start again, so Flock gives fresh logins; if it keeps refusing, connect players directly.`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`relay_lost`}),`, `,_jsx(_components.code,{children:`relay_closed`})]}),_jsx(_components.td,{children:`The relay let this device’s address go or has answered nothing for 45 s (this device’s packets no longer reach it), or the session’s end closed it.`}),_jsxs(_components.td,{children:[`After `,_jsx(_components.code,{children:`relay_lost`}),`, start again; after `,_jsx(_components.code,{children:`relay_closed`}),`, host or join another session.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_no_thread`})}),_jsxs(_components.td,{children:[`Unreal only: the game runs without threads (`,_jsx(_components.code,{children:`-nothreading`}),`), and the relay needs one of its own.`]}),_jsxs(_components.td,{children:[`Launch the game without `,_jsx(_components.code,{children:`-nothreading`}),`.`]})]})]})]}),`\n`,_jsx(_components.p,{children:`The server can add reasons, so keep a default.`}),`\n`,_jsx(Heading,{level:`2`,id:`who-is-joining`,children:`Who is joining`}),`\n`,_jsx(_components.p,{children:`The host lets in only players whose seat Flock confirms, one connection each. Name players by\ntheir connection, never by what a player’s game sends. The host’s check of each joining player is\nbilled as one API call.`}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`Unity`,id:`unity-2`,children:[_jsxs(_components.p,{children:[`The host started by `,_jsx(_components.code,{children:`StartNetcodeAsync`}),` checks each joining player itself. Find who a\nconnection is:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`csharp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`csharp`,children:_jsxs(_components.code,{language:`csharp`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`string`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` playerId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`PlayerForConnection`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`clientId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`); `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// on the host`})]}),`\n`]})})}),_jsx(_components.p,{children:`Add your own check after Flock’s, such as a ban list or a team limit:`}),_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`csharp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`csharp`,children:_jsxs(_components.code,{language:`csharp`,numberOfLines:`11`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FlockNetcodeOptions`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` options`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockNetcodeOptions`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` ApproveJoiningPlayer`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`player`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`response`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`bannedPlayers`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`Contains`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`player`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`PlayerId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`))`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` response`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Approved`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` false`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` response`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Reason`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"banned\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`};`})}),`\n`]})})}),_jsxs(_components.p,{children:[`A refused player’s `,_jsx(_components.code,{children:`RefusedReason`}),` is `,_jsx(_components.code,{children:`no_join_token`}),`, `,_jsx(_components.code,{children:`join_token_invalid`}),`, `,_jsx(_components.code,{children:`already_connected`}),`,\n`,_jsx(_components.code,{children:`flock_unreachable`}),`, `,_jsx(_components.code,{children:`session_ended`}),`, `,_jsx(_components.code,{children:`not_host`}),`, `,_jsx(_components.code,{children:`refused_by_the_game`}),` or `,_jsx(_components.code,{children:`game_check_failed`}),`.`]}),_jsx(Note,{children:_jsx(_components.p,{children:`Both ends of a game must run Flock SDK 1.77.0 or later, and the same major version of Netcode for\nGameObjects: a host refuses players on an older Flock SDK, or on another major version of Netcode.`})})]}),_jsxs(Tab,{title:`Unreal`,id:`unreal-2`,children:[_jsxs(_components.p,{children:[`The engine asks the host’s game mode about each joining player in `,_jsx(_components.code,{children:`PreLoginAsync`}),`, so the host’s\ngame mode calls Flock’s check there, in place of the engine’s own. The simplest way is to base\nit on `,_jsx(_components.code,{children:`AFlockGameModeBase`}),` (on `,_jsx(_components.code,{children:`AGameModeBase`}),`) or `,_jsx(_components.code,{children:`AFlockGameMode`}),` (on `,_jsx(_components.code,{children:`AGameMode`}),`, for match\nstates): in C++, or as a Blueprint based on `,_jsx(_components.strong,{children:`Flock Game Mode Base`}),` or `,_jsx(_components.strong,{children:`Flock Game Mode`}),`, set\nin `,_jsx(_components.strong,{children:`Project Settings → Maps \u0026 Modes`}),`. Or call the check from a game mode of your own:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`23`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`23`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// MyGameMode.h`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`virtual`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` void`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` PreLoginAsync`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` Options`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` Address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FUniqueNetIdRepl`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` UniqueId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FOnPreLoginCompleteDelegate`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` OnComplete`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`override`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// MyGameMode.cpp`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`#include`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Multiplayer/FlockJoinChecks.h\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`void`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` AMyGameMode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`PreLoginAsync`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` Options`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` Address`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FUniqueNetIdRepl`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` UniqueId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FOnPreLoginCompleteDelegate`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` OnComplete`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Flock's check, then the engine's own (PreLogin, such as a full game), then your own below.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` TWeakObjectPtr`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`AMyGameMode`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Mode `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FlockJoinChecks`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`CheckJoiningPlayer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, Options, Address, UniqueId, OnComplete,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`Mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`](`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FFlockJoiningPlayer`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` Player`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` OutRefusedReason`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`IsValid`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`() `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u0026\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`IsBanned`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Player`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`PlayerId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`))`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` OutRefusedReason `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"banned\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // the joining player's RefusedReason`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` false`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` true`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsxs(_components.p,{children:[`Your own check is optional, and runs only for a player Flock has let in. It gets the `,_jsx(_components.code,{children:`PlayerId`}),`\nFlock verified, the travel’s `,_jsx(_components.code,{children:`Options`}),` without Flock’s token, and the `,_jsx(_components.code,{children:`Address`}),` (127.0.0.1 for a\nplayer that came through Flock’s relay). On the Flock game modes, override `,_jsx(_components.strong,{children:`Approve Joining\nPlayer`}),` (`,_jsx(_components.code,{children:`ApproveJoiningPlayer`}),`) instead; it lets everyone in until overridden.`]}),_jsxs(_components.p,{children:[`Find who a connection is, on the host, such as in `,_jsx(_components.code,{children:`PostLogin`}),`:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`FString PlayerId `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`PlayerForConnection`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(PlayerController);`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // empty for a connection Flock's check did not let in`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`A refused player’s `,_jsx(_components.code,{children:`RefusedReason`}),` is one of `,_jsx(_components.code,{children:`FlockTravelToSessionRefusedReasons`}),`, your own\nreason, or the engine’s (such as `,_jsx(_components.code,{children:`Server full.`}),`), so keep a default. The joining player’s log\nnames the fix too.`]}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Reason`}),_jsx(_components.th,{children:`When`}),_jsx(_components.th,{children:`What to do`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`no_join_token`})}),_jsxs(_components.td,{children:[`The player’s travel carried no token: it did not come through `,_jsx(_components.code,{children:`TravelToSession`}),`.`]}),_jsxs(_components.td,{children:[`Connect with `,_jsx(_components.code,{children:`TravelToSession`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`join_token_invalid`})}),_jsx(_components.td,{children:`Flock said the token is not good for this session: made up, another session’s, expired (tokens last 60 seconds), or its player gave up the seat.`}),_jsx(_components.td,{children:`Join the session again, then travel.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`already_connected`})}),_jsx(_components.td,{children:`The same player is already in through another connection the host still hears from.`}),_jsx(_components.td,{children:`Close the player’s other game, then travel again.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`flock_unreachable`})}),_jsx(_components.td,{children:`Flock did not answer the host within 8 seconds, or the host was over its checks a minute. Nobody is let in unchecked.`}),_jsx(_components.td,{children:`Check the host’s device is online, then travel again.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`session_ended`})}),_jsx(_components.td,{children:`The session has ended.`}),_jsx(_components.td,{children:`Host or join another session.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`not_host`})}),_jsx(_components.td,{children:`The device reached no longer hosts the session.`}),_jsx(_components.td,{children:`Travel again: it finds the new host.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`refused_by_the_game`})}),_jsx(_components.td,{children:`Your own check turned the player away without a reason of its own.`}),_jsx(_components.td,{children:`Give the player a reason of your own.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`join_check_missing`})}),_jsx(_components.td,{children:`The host’s game mode does not call Flock’s check, so nobody is let in.`}),_jsxs(_components.td,{children:[`Base the game mode on a Flock game mode, or call `,_jsx(_components.code,{children:`CheckJoiningPlayer`}),` from its `,_jsx(_components.code,{children:`PreLoginAsync`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`relay_only`})}),_jsxs(_components.td,{children:[`The host’s `,_jsx(_components.code,{children:`Relay`}),` is `,_jsx(_components.code,{children:`Always`}),`, and the player reached it another way.`]}),_jsxs(_components.td,{children:[`Set `,_jsx(_components.code,{children:`Relay`}),` the same on every player’s game.`]})]})]})]}),_jsxs(_components.p,{children:[`In Blueprint, override `,_jsx(_components.strong,{children:`Approve Joining Player`}),` on a game mode based on `,_jsx(_components.strong,{children:`Flock Game Mode\nBase`}),`; its Refused Reason reaches the player’s Travel To Session (empty reads as Refused By\nThe Game). Name players by `,_jsx(_components.strong,{children:`Player For Connection`}),` on the session, such as in\n`,_jsx(_components.strong,{children:`OnPostLogin`}),`.`]}),_jsx(Note,{children:_jsxs(_components.p,{children:[`Run the same Flock Unreal SDK on every player’s game. A player on 1.30.0 or earlier sends no\njoin token (`,_jsx(_components.code,{children:`no_join_token`}),`), and one on 1.33.0 or earlier cannot come through the relay.`]})})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`when-the-host-changes`,children:`When the host changes`}),`\n`,_jsxs(_components.p,{children:[`When the host leaves or its game stops, Flock makes the player seated longest the host and raises\nthe session’s host-changed event on every game (`,_jsx(_components.code,{children:`HostChanged`}),` on Unity, `,_jsx(_components.code,{children:`OnHostChanged`}),` on\nUnreal). Neither Netcode for GameObjects nor Unreal’s networking can move a running game to a new\nhost, so each game starts its networking again: the new host hosts, and the others join it. Do the\nsame when this device’s relay stops working (`,_jsx(_components.code,{children:`RelayLost`}),` on Unity, `,_jsx(_components.code,{children:`OnRelayLost`}),` on Unreal).`]}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`Unity`,id:`unity-3`,children:[_jsx(_components.p,{children:`Shut the netcode down and start it again:`}),_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`csharp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`csharp`,children:_jsxs(_components.code,{language:`csharp`,numberOfLines:`10`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`HostChanged`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` +=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` StartAgain`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RelayLost`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` +=`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` reason`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` StartAgain`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`async`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` void`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` StartAgain`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`HasEnded`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` NetworkManager`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Singleton`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`Shutdown`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`StartNetcodeAsync`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`NetworkManager`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Singleton`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`); `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// waits for the shutdown to finish`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsxs(_components.p,{children:[`Players are back about 20 seconds after a host leaves, and about a minute after a host’s game\ncrashes (the `,_jsx(_components.strong,{children:`Host timeout`}),`). Everything the old host held is gone: its spawned objects, network\nvariables and scene state. Keep what a new host needs on every player, such as a snapshot of the\ngame the host sends every few seconds, and rebuild from it. While waiting for a crashed host to be\nreplaced, players lose the netcode connection first; keep the session and wait for `,_jsx(_components.code,{children:`HostChanged`}),`.`]})]}),_jsxs(Tab,{title:`Unreal`,id:`unreal-3`,children:[_jsxs(_components.p,{children:[`Call `,_jsx(_components.code,{children:`TravelToSession`}),` again with the same options, from your game instance. A newer travel\nends the one under way as `,_jsx(_components.code,{children:`restarted`}),`, and does this device’s part from wherever the game is.`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`19`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`19`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Once the session is held.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`OnHostChanged`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`AddDynamic`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`UMyGameInstance`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::PlayAgain);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`OnRelayLost`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`AddDynamic`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`UMyGameInstance`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::PlayAgainAfterRelayLost);`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`void`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` UMyGameInstance`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`PlayAgain`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`HasEnded`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`())`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TravelToSession`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, TravelOptions, [](`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`TFlockResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FFlockTravelToSessionResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`Result`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // restarted: a newer call took over, and its own answer follows.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`void`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` UMyGameInstance`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`PlayAgainAfterRelayLost`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` FString`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\u0026`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` Reason`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` PlayAgain`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`This game was`}),_jsx(_components.th,{children:`Now`}),_jsx(_components.th,{children:`Travel To Session`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`the host`}),_jsx(_components.td,{children:`still the host`}),_jsx(_components.td,{children:`Keeps its level and its players, opens its relay address again when it was lost, and publishes again. A refused publish, a cancel or a newer call leaves the level listening.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`the host`}),_jsx(_components.td,{children:`a player`}),_jsx(_components.td,{children:`Stops listening (its players’ connections close), waits for the new host, and joins it.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`a player`}),_jsx(_components.td,{children:`the host`}),_jsxs(_components.td,{children:[`Opens the level it played with the old host listening, unless `,_jsx(_components.code,{children:`HostLevel`}),` names another, and publishes.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`a player`}),_jsx(_components.td,{children:`a player`}),_jsx(_components.td,{children:`Waits for the new host in the level it is in, then connects; the engine closes the old connection.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`a player in the host’s game`}),_jsx(_components.td,{children:`a player, the same host`}),_jsxs(_components.td,{children:[`Answers `,_jsx(_components.code,{children:`connected`}),` at once and keeps its connection, so a level’s Begin Play that calls it can run on every player.`]})]})]})]}),_jsxs(_components.p,{children:[`On a player, `,_jsx(_components.strong,{children:`On Relay Lost`}),` is raised too when its host publishes another relay address (the\nhost’s own relay was lost), since the player’s relay no longer reaches it. A new host’s address is\n`,_jsx(_components.strong,{children:`On Host Changed`}),`’s alone.`]}),_jsxs(_components.p,{children:[`Games hear On Host Changed within about 20 seconds of a host leaving and are back in the new\nhost’s game about 10 seconds later (about 30 seconds in all); a host’s game that stops without\nleaving is replaced a little over a minute on (the `,_jsx(_components.strong,{children:`Host timeout`}),`, then Flock’s sweep), its\nplayers back about 80 seconds on. Everything the old\nhost held is gone: its actors, its game state and its level’s state. Keep what a new host needs\non every player, and rebuild from it.`]}),_jsxs(_components.p,{children:[`A player’s connection to a host that went without a word times out in the engine (a minute by\ndefault), which raises `,_jsx(_components.strong,{children:`NetworkError`}),` and takes the game back to its default level. Calling\nTravel To Session again from the game instance’s NetworkError event, while the session lasts,\ntakes the player to the session’s host, whoever that is by then. The host lets the player’s newer\nconnection in once it has heard nothing from the earlier one for 5 seconds, with the new join token\nTravel To Session brings.`]}),_jsxs(_components.p,{children:[`In Blueprint, bind the session’s `,_jsx(_components.strong,{children:`On Host Changed`}),` and `,_jsx(_components.strong,{children:`On Relay Lost`}),` in the Game Instance\nBlueprint, each to `,_jsx(_components.strong,{children:`Flock Travel To Session`}),` with the same Options. The travel it replaces\nfires `,_jsx(_components.strong,{children:`On Not Joined`}),` with the Outcome `,_jsx(_components.strong,{children:`Restarted`}),`, which needs nothing done. The plugin’s\nmultiplayer sample does exactly this:`]}),_jsx(Frame,{caption:`The sample's Game Instance holds the session and binds On Host Changed and On Relay Lost to its Travel Again event.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-play.png?fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=792db93d3303064888af1fe309d5da21`,alt:`Set Session, then Bind Event to On Host Changed, On Relay Lost and On Ended; the bound HostChanged and RelayLost events each call Travel Again`,\"data-og-width\":`2353`,width:`2353`,\"data-og-height\":`619`,height:`619`,\"data-path\":`images/guides/unreal-multiplayer-sample-play.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-play.png?w=280\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=4c908684aab2dc4d3f169296f45aa9d7 280w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-play.png?w=560\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=c2827c3223d7cc953a9c239c4942b0c1 560w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-play.png?w=840\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=255f13d3e83de18f288fe24fd0137871 840w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-play.png?w=1100\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=c66969e76b4e92ad16321fab6fc64b57 1100w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-play.png?w=1650\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=f7eb027a07a1bb022b7a94b662749531 1650w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-play.png?w=2500\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=985ebef4cca6dd85b9cc1741c711edd1 2500w`})}),_jsx(Frame,{caption:`Travel Again: Flock Travel To Session for the session held. Restarted needs nothing; any other way of not getting in gives the seat up.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-travel-again.png?fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=d4b8c6f1750cf95f0eeae1cf5066f9fe`,alt:`Two Branches, Flock Travel To Session, On Joined setting the status, On Not Joined comparing the Outcome with Restarted, On Failure leaving the session`,\"data-og-width\":`2338`,width:`2338`,\"data-og-height\":`670`,height:`670`,\"data-path\":`images/guides/unreal-multiplayer-sample-travel-again.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-travel-again.png?w=280\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=6eeaefa2993938f9145e8b073694f625 280w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-travel-again.png?w=560\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=50d607646de55a7d4923be4025a2f2bc 560w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-travel-again.png?w=840\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=d65c1ccdccb714cc241fcffb3d7c5c7f 840w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-travel-again.png?w=1100\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=133d4a385843917f46babedde7670a08 1100w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-travel-again.png?w=1650\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=37833fcb32aaed51549da2a5631b9400 1650w, https://mintcdn.com/qwacks/sKCVX05gMuqzHxSa/images/guides/unreal-multiplayer-sample-travel-again.png?w=2500\u0026fit=max\u0026auto=format\u0026n=sKCVX05gMuqzHxSa\u0026q=85\u0026s=1953bf819237eac0865de75aea4fb335 2500w`})})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`other-networking`,children:`Other networking`}),`\n`,_jsx(_components.p,{children:`Games on Steam, Epic Online Services or their own networking still use Flock’s parties,\nmatchmaking, sessions and join check. They publish and read the connection themselves.`}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`Unity`,id:`unity-4`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`11`,language:`csharp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`csharp`,children:_jsxs(_components.code,{language:`csharp`,numberOfLines:`11`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// The host says how to reach it: a kind of its own and the values it needs, under 4 KB.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`PublishConnectionAsync`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"steam\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`new`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Dictionary`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`string`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`object`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> { [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"lobby\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`] `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` lobbyId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`ToString`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`() });`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// A player waits for it; null when the time passes or the session ends.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FlockMultiplayerSessionConnection`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` connection`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`WaitForConnectionAsync`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TimeSpan`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`FromSeconds`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`60`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`));`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// The player proves its seat with a token, good for 60 seconds, sent over your own networking.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FlockMultiplayerSessionJoinToken`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` token`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`RequestJoinTokenAsync`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// The host checks it and learns who the player is; a bad token throws MultiplayerInvalidJoinToken.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`string`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` playerId`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`VerifyJoinTokenAsync`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`tokenFromPlayer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`]})})}),_jsxs(_components.p,{children:[_jsx(_components.code,{children:`PublishDirectConnectionAsync(port)`}),` publishes this device’s own address, and a player’s\n`,_jsx(_components.code,{children:`connection.FindDirectAddressAsync()`}),` picks the one to use: the host’s local address on a shared\nnetwork, its public address otherwise. Outside a local network, players reach that address only\nthrough a port forwarded to the host.`]})]}),_jsxs(Tab,{title:`Unreal`,id:`unreal-4`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`23`,language:`cpp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`cpp`,children:_jsxs(_components.code,{language:`cpp`,numberOfLines:`23`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// The host says how to reach it: a mode of its own (32 characters at most) and the values it needs, under 4 KB.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`PublishConnection`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"steam\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`), `}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`FFlockCommandData`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`().`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`Set`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"lobby\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`), LobbyId), `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`nullptr`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// A player waits for it: the session comes back with HasConnection(), HasEnded(), or neither when the time passes.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`WaitForConnection`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`60.`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#B5CEA8`},children:`f`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, [`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`](`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`TFlockResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`UFlockMultiplayerSession`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`*`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`Waited`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FString Lobby;`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Waited`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`IsSuccess`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`() `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u0026\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Waited`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Value`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`HasConnection`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u0026\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Waited`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Value`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`GetConnection`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`().`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`Equals`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"steam\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`), `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`ESearchCase`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`::CaseSensitive)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` \u0026\u0026`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Waited`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Value`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`GetConnection`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`().`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Values`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TryGetString`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`TEXT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"lobby\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`), Lobby))`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` JoinSteamLobby`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(Lobby);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// The player proves its seat with a token, good for 60 seconds, sent over your own networking.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`RequestJoinToken`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`([`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`](`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`TFlockResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FFlockMultiplayerSessionJoinToken`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`Token`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Token`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`IsSuccess`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()) { `}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`SendToHost`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Token`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Value`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Token`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`); }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// The host checks it and learns who the player is; a bad token fails with MultiplayerInvalidJoinToken.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Session`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`->`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`VerifyJoinToken`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(TokenFromPlayer, [`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`this`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`](`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`TFlockResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FString`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`PlayerId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` /* PlayerId.Value */`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`Travel To Session also ends `,_jsx(_components.code,{children:`not_direct`}),` when the host published a connection of its own,\nholding it in the result’s `,_jsx(_components.code,{children:`Connection`}),`. `,_jsx(_components.code,{children:`PublishDirectConnection(Port)`}),` publishes this device’s\nown address, and a player’s `,_jsx(_components.code,{children:`FindDirectAddress`}),` picks the one to use: the host’s local address\non a shared network, its public address otherwise. Outside a local network, players reach that\naddress only through a port forwarded to the host.`]}),_jsxs(_components.p,{children:[`In Blueprint these are `,_jsx(_components.strong,{children:`Flock Publish Connection`}),`, `,_jsx(_components.strong,{children:`Flock Wait For Connection`}),` (On\nConnection, On Session Ended, On Timed Out, On Failure), `,_jsx(_components.strong,{children:`Flock Request Join Token`}),`, `,_jsx(_components.strong,{children:`Flock\nVerify Join Token`}),`, `,_jsx(_components.strong,{children:`Flock Publish Direct Connection`}),` and `,_jsx(_components.strong,{children:`Flock Find Direct Address`}),`.`]})]})]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{Scope,default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Connecting Players","description":"Connect a session's players over Netcode for GameObjects or Unreal's own networking, through Flock's relay when needed.","href":"/guides/connecting-players"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Starting the netcode","slug":"starting-the-netcode","depth":2,"children":[]},{"title":"Through the relay, or directly","slug":"through-the-relay-or-directly","depth":2,"children":[{"title":"Direct paths","slug":"direct-paths","depth":3,"children":[]}]},{"title":"Who is joining","slug":"who-is-joining","depth":2,"children":[]},{"title":"When the host changes","slug":"when-the-host-changes","depth":2,"children":[]},{"title":"Other networking","slug":"other-networking","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/qwacks/05763fd4e1d53e37/lang-toggle.js"],"subdomain":"qwacks","siteName":"Qwacks","title":"Connecting Players - Qwacks","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{"en":{"href":"/guides/connecting-players","matchLevel":0},"ar":{"href":"/ar/guides/connecting-players","matchLevel":1}}},"lastModified":"2026-10-20T11:54:11.011Z","originalFileLocation":"guides/connecting-players.mdx","locale":"en"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=\"dark\";if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Connect a session\u0026#x27;s players over Netcode for GameObjects or Unreal\u0026#x27;s own networking, through Flock\u0026#x27;s relay when needed.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Qwacks\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Connecting Players - Qwacks\">\u003cmeta data-mint-head property=\"og:description\" content=\"Connect a session\u0026#x27;s players over Netcode for GameObjects or Unreal\u0026#x27;s own networking, through Flock\u0026#x27;s relay when needed.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Qwacks\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.qwacks.com/guides/connecting-players\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://qwacks.mintlify.app/_mintlify/api/og/v2?division=Multiplayer\u0026amp;title=Connecting+Players\u0026amp;description=Connect+a+session%27s+players+over+Netcode+for+GameObjects+or+Unreal%27s+own+networking%2C+through+Flock%27s+relay+when+needed.\u0026amp;theme=c8444a292735843f142f05ff\u0026amp;signature=4f11e28ea3f2bd271020e6a584f589abe38f7108cb6aac1f91f8569d2ce7314e\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Connecting Players - Qwacks\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Connect a session\u0026#x27;s players over Netcode for GameObjects or Unreal\u0026#x27;s own networking, through Flock\u0026#x27;s relay when needed.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://qwacks.mintlify.app/_mintlify/api/og/v2?division=Multiplayer\u0026amp;title=Connecting+Players\u0026amp;description=Connect+a+session%27s+players+over+Netcode+for+GameObjects+or+Unreal%27s+own+networking%2C+through+Flock%27s+relay+when+needed.\u0026amp;theme=c8444a292735843f142f05ff\u0026amp;signature=4f11e28ea3f2bd271020e6a584f589abe38f7108cb6aac1f91f8569d2ce7314e\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/qwacks/UqcSWN8cDTjx2Nmd/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Qwacks\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0099FF\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.qwacks.com/guides/connecting-players\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/guides/connecting-players.md\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"en\" href=\"https://docs.qwacks.com/guides/connecting-players\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"ar\" href=\"https://docs.qwacks.com/ar/guides/connecting-players\">\u003clink data-mint-head rel=\"alternate\" hreflang=\"x-default\" href=\"https://docs.qwacks.com/guides/connecting-players\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.qwacks.com/#organization\",\"name\":\"Qwacks\",\"url\":\"https://docs.qwacks.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/qwacks/TGGmq_oWzDacAqHl/icons/qwacks.svg?fit=max\u0026auto=format\u0026n=TGGmq_oWzDacAqHl\u0026q=85\u0026s=2023abb340d6ec576975601525ab2ce9\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.qwacks.com#website\",\"name\":\"Qwacks\",\"url\":\"https://docs.qwacks.com\",\"publisher\":{\"@id\":\"https://docs.qwacks.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.qwacks.com/guides/connecting-players#webpage\",\"url\":\"https://docs.qwacks.com/guides/connecting-players\",\"name\":\"Connecting Players\",\"description\":\"Connect a session's players over Netcode for GameObjects or Unreal's own networking, through Flock's relay when needed.\",\"dateModified\":\"2026-10-20T11:54:11.011Z\",\"isPartOf\":{\"@id\":\"https://docs.qwacks.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.qwacks.com/guides/connecting-players#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.qwacks.com/guides/connecting-players#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Multiplayer\",\"item\":\"https://docs.qwacks.com/guides/multiplayer\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Connecting Players\",\"item\":\"https://docs.qwacks.com/guides/connecting-players\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.qwacks.com/guides/connecting-players#article\",\"headline\":\"Connecting Players\",\"name\":\"Connecting Players\",\"description\":\"Connect a session's players over Netcode for GameObjects or Unreal's own networking, through Flock's relay when needed.\",\"url\":\"https://docs.qwacks.com/guides/connecting-players\",\"mainEntityOfPage\":{\"@id\":\"https://docs.qwacks.com/guides/connecting-players#webpage\"},\"dateModified\":\"2026-10-20T11:54:11.011Z\",\"publisher\":{\"@id\":\"https://docs.qwacks.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.qwacks.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Qwacks\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Qwacks","nav":{"global":null,"languages":[{"language":"en","default":true,"tabs":[{"tab":"Qwacks","icon":"https://mintlify.s3.us-west-1.amazonaws.com/qwacks/icons/qwacks.svg","pages":[{"title":"Qwacks","href":"/welcome"}]},{"tab":"Flock","icon":"https://mintlify.s3.us-west-1.amazonaws.com/qwacks/icons/flock.svg","groups":[{"group":"Getting Started","pages":[{"title":"Flock","href":"/introduction"},{"title":"Quickstart","href":"/quickstart"},{"title":"Authentication","href":"/authentication"}]},{"group":"Concepts","pages":[{"title":"Studios \u0026 Games","href":"/concepts/studios-and-games"},{"title":"Versions","href":"/concepts/versions"},{"title":"Players","href":"/concepts/players"}]},{"group":"SDKs","pages":[{"title":"Unity SDK","href":"/sdk/unity"},{"title":"Unreal SDK","href":"/sdk/unreal"}]},{"group":"Features","pages":[{"title":"Players \u0026 Auth","href":"/guides/players-and-auth"},{"title":"Account Linking","href":"/guides/account-linking"},{"title":"Player Data","href":"/guides/player-data"},{"title":"Achievements","href":"/guides/achievements"},{"title":"Shops \u0026 Inventory","href":"/guides/shops-and-inventory"},{"title":"Currencies \u0026 Wallets","href":"/guides/currencies-and-wallets"},{"title":"Leaderboards","href":"/guides/leaderboards"},{"title":"Segments","href":"/guides/segments"},{"title":"Game Notifications","href":"/guides/notifications"},{"title":"Bans","href":"/guides/bans"},{"title":"Remote Config","href":"/guides/remote-config"},{"title":"Game Patches","href":"/guides/game-patches"},{"title":"Assets","href":"/guides/assets"},{"title":"Analytics \u0026 Events","href":"/guides/analytics-and-events"},{"title":"Developer Alerts","href":"/guides/developer-alerts"}]},{"group":"Multiplayer","pages":[{"title":"Multiplayer","href":"/guides/multiplayer"},{"title":"Parties","href":"/guides/parties"},{"title":"Matchmaking","href":"/guides/matchmaking"},{"title":"Sessions","description":"One game: a host, its players and a join code.","href":"/guides/sessions"},{"title":"Connecting Players","href":"/guides/connecting-players"}]},{"group":"Reference","pages":[{"title":"Changelog","description":"Notable changes to Flock and its SDKs.","href":"/changelog"}]}]},{"tab":"Protokite","icon":"https://mintlify.s3.us-west-1.amazonaws.com/qwacks/icons/protokite.svg","pages":[{"title":"Protokite","href":"/protokite/getting-started"}]},{"tab":"Data Duck","icon":"https://mintlify.s3.us-west-1.amazonaws.com/qwacks/icons/data-duck.svg","pages":[{"title":"Data Duck","href":"/data-duck/getting-started"}]}]},{"language":"ar","navbar":{"links":[{"href":"https://www.qwacks.com/pricing","label":"الأسعار"},{"href":"https://github.com/QwackStack/FlockUnitySdk/releases","label":"حزمة Unity"},{"href":"https://github.com/QwackStack/FlockUnrealSdk/releases","label":"حزمة Unreal"}],"primary":{"type":"button","label":"لوحة التحكم","href":"https://flock-saas.qwacks.com"}},"pages":[{"title":"ar","href":"/ar/guides/connecting-players"}]}]},"title":"Connecting Players - Qwacks","buildId":"dpl_9DauxEjb9gzCtcuhPQFbquJvx7FJ","deploymentId":"dpl_9DauxEjb9gzCtcuhPQFbquJvx7FJ","dynamics":["07c022d89b","a74be98ba7"],"chunks":["Frame-DpBmNN95.js","DynamicMarkdown-BY_qDhTn.js","zoom-image-lightbox-D4WcYaf4.js","PlusIcon-CwhPVjTe.js","lightbox-handle-r17bVUz3.js"]}