Connection

App ID and Fusion Settings

Project-wide Fusion configuration lives in UFusionOnlineSubsystemSettings, exposed under Project Settings > Photon in the Unreal editor. The fields read at connect time are AppId, AppVersion, UseLocalServer, LocalServerUrl, and CloudServerUrl. The App ID identifies the project on the Photon Cloud; AppVersion segments players by client build so incompatible versions cannot share rooms; UseLocalServer swaps the cloud endpoint for a local Photon Hive build when developing the server-side plugin against a local relay.

Get an App ID for the project from the Photon Dashboard — the walk-through is in Create a Photon Fusion App ID — and paste it into the App ID field as shown in the Quick Start Guide.

The same settings asset hosts a few fields that belong to other chapters: LoadMapAutomatically shapes the map-load callback sequence (see Map Changes) and DefaultArraySize sets the default capacity for replicated TArray properties (see Replicated Properties).

Connecting to Photon

Every connection and room operation goes through UFusionOnlineSubsystem, a UGameInstanceSubsystem reached the standard Unreal way: GameInstance->GetSubsystem<UFusionOnlineSubsystem>(). The subsystem owns the underlying UFusionClient and the lifecycle of the Fusion session.

The entry point is ConnectToPhoton(FFusionConnectOptions, WorldContextObject). It returns a UFusionConnectToPhotonAsync — a Blueprint latent action with OnSuccess and OnFailure multicast pins. In Blueprints the call appears as the latent node "Connect To Photon"; in C++ the same node is activated explicitly.

C++

UFusionConnectToPhotonAsync* Connect = OnlineSubsystem->ConnectToPhoton(ConnectOpts, this);
Connect->OnSuccess.AddDynamic(this, &UMyGameInstance::HandleConnected);
Connect->OnFailure.AddDynamic(this, &UMyGameInstance::HandleConnectFailed);
Connect->Activate();

Joining or Creating a Room

Once connected, the subsystem exposes five room entry points. CreateRoom, JoinOrCreateRoom, and JoinOrCreateRandomRoom all take an FFusionRoomOptions struct describing the room to create. JoinRoom(RoomName) and JoinRandomRoom join an existing room without creating one — the by-name variant requires the exact room name, the random variant picks any open and visible room.

C++

FFusionRoomOptions RoomOpts;
RoomOpts.RoomName = TEXT("Match-42");
RoomOpts.MaxPlayers = 8;
RoomOpts.PlayerTTL = 60;
RoomOpts.InitialWorld = LobbyWorldPtr;

UFusionJoinOrCreateRoomAsync* Join = OnlineSubsystem->JoinOrCreateRoom(RoomOpts, this);
Join->OnSuccess.AddDynamic(this, &UMyGameInstance::HandleJoined);
Join->Activate();

For the common case of "connect and then join a room in one step", the convenience one-shot ConnectAndJoinRoom(ConnectOptions, RoomOptions, WorldContextObject) chains a UFusionConnectToPhotonAsync and a UFusionJoinOrCreateRoomAsync internally, so application code only binds to one OnSuccess / OnFailure pair.

Prefer JoinOrCreateRoom for invite-style flows where a known room name is shared between players (a friend code, a lobby ID surfaced through an external service). Prefer JoinOrCreateRandomRoom for quick-match flows where the player does not care which room they end up in.

Async Actions

Every connect and room call returns a UFusionRoomActionBase subclass — a Blueprint latent action that exposes OnSuccess and OnFailure multicast delegates as exec pins in BP and as FMulticastDynamicDelegate members in C++. OnFailure carries an EFusionActionFailureCodes value describing the reason.

Async class Subsystem method Wraps
UFusionConnectToPhotonAsync ConnectToPhoton Initial cloud connection
UFusionDisconnectFromPhotonAsync DisconnectFromPhoton Full disconnect from the cloud
UFusionJoinOrCreateRoomAsync JoinOrCreateRoom, JoinOrCreateRandomRoom Join a matching room or create one
UFusionCreateRoomAsync CreateRoom Create a new room unconditionally
UFusionJoinRoomAsync JoinRoom, JoinRandomRoom Join an existing room
UFusionLeaveRoomAsync LeaveRoom Leave the current room, stay connected
UFusionConnectAndJoinRoomAsync ConnectAndJoinRoom Connect plus join in one action

EFusionActionFailureCodes covers the practical failure cases: TimeOut, InvalidRegion, ClientAlreadyExists, Disconnected, and the in-progress states Connecting, JoiningRoom, and InRoom — which fire when an action is attempted while another action of the same kind is still mid-flight.

Connection Options and Regions

FFusionConnectOptions carries two fields. Region is a region code string such as "us" or "eu" — see Regions for the full list. RegionSelectionMode is an EFusionRegionSelectionMode enum that decides how the Region field is interpreted.

Mode Behavior
Default Use the first available region. The Region string is ignored.
Select Connect to the region named in the Region string.
Best Ping every available region, pick the lowest-RTT one, and cache the result.

C++

FFusionConnectOptions ConnectOpts;
ConnectOpts.Region = TEXT("us");
ConnectOpts.RegionSelectionMode = EFusionRegionSelectionMode::Select;

For production, ship with Best on first launch so the player lands on the lowest-RTT region without any UI. Persist the chosen region and switch to Select with that value on subsequent launches to skip the ping pass.

Room Options

FFusionRoomOptions describes the room being created or joined.

Field Type Effect
RoomName FString Unique name within the App ID. Required for invite-style flows; auto-generated when joining randomly.
MaxPlayers int32 Maximum concurrent players in the room.
bIsOpen bool If false, the room rejects new joins. Set false to seal a match in progress.
bIsVisible bool If false, the room does not appear in random-join results. Invite-only rooms set this false.
EmptyTTL int32 (seconds) How long the room survives after the last player leaves. Converted to ms internally.
PlayerTTL int32 (seconds) How long a disconnected player can rejoin into their old slot. Converted to ms internally.
InitialWorld TSoftObjectPtr<UWorld> World to load when the local player joins. Skips a separate ChangeWorld call on the Master Client.

C++

FFusionRoomOptions RoomOpts;
RoomOpts.RoomName = TEXT("Match-42");
RoomOpts.MaxPlayers = 8;
RoomOpts.PlayerTTL = 60;
RoomOpts.EmptyTTL = 0;
RoomOpts.InitialWorld = LobbyWorldPtr;

Set InitialWorld whenever the room creator already knows the starting map. The local client loads that world automatically as it joins, and the Master Client does not need to issue a separate ChangeWorld call after OnSuccess.

Lobbies and Matchmaking Filters

FFusionRoomOptions does not expose lobby properties or a custom-property filter. There is no equivalent of a lobby_properties dictionary, no custom-keys filter, and no filter expression on the random-join path.

The built-in matchmaking surface is JoinRandomRoom and JoinOrCreateRandomRoom, which pick any room that is bIsOpen=true and bIsVisible=true, without further filter criteria.

For projects that need richer matchmaking, the conversion seam where Fusion's FFusionRoomOptions becomes the Photon Hive's create-room call is FusionMatchmakingHelpers::CreatePhotonRoomOptions. Custom matchmaking criteria can be plumbed through there in conjunction with a parallel surface on the server-side Photon Hive plugin.

Leaving the Room and Reconnecting

LeaveRoom(WorldContextObject) returns a UFusionLeaveRoomAsync and optionally accepts a LobbyWorld soft pointer. When LobbyWorld is set, the client streams back into that world after OnSuccess fires, so the player lands on a clean offline level rather than on the now-detached networked map.

After OnSuccess the client is back in EFusionStatus::Connected. It can call JoinOrCreateRoom again without re-running ConnectToPhoton. For a full teardown of the Photon connection, use DisconnectFromPhoton, which returns the client to EFusionStatus::None.

Tune PlayerTTL together with LeaveRoom flows. PlayerTTL on the original room governs how long a dropped client can rejoin into its old player slot — a LeaveRoom followed by a rejoin within the TTL preserves the player's APlayerState and any PlayerAttached ownership.

Connection Status and Events

Status() returns the current EFusionStatus. The normal lifecycle traces NoneConnectingConnectedJoiningRoomInRoomLeavingRoom, with Disconnected and Error reachable from any non-terminal state. The transitions are introduced in Concepts.

Query Returns
IsConnected() True when the client has reached at least Connected.
IsInRoom() True when the client is fully in a room (InRoom).
IsJoiningOrInRoom() True for both JoiningRoom and InRoom — useful for "session is forming or formed" gates.
IsMasterClient() True when this client is the elected Master Client of the current room.
PlayerCount() Current number of players in the room.
GetLocalPlayerId() Stable int32 id of the local player for this session.
GetRtt() Round-trip time to the Photon relay, in milliseconds.
CurrentRoomInfo(Name, Players) Room name and current player count as out params.

The one global event in this chapter is OnConnectedToPhoton, a multicast on UFusionOnlineSubsystem that fires once the initial cloud connection is up. Per-action success and failure are surfaced through the OnSuccess and OnFailure pins on the async nodes — there is no global OnRoomJoined multicast, since the async-action pins already cover that case.

C++

void UMyGameInstance::Init()
{
    Super::Init();
    OnlineSubsystem = GetSubsystem<UFusionOnlineSubsystem>();
    OnlineSubsystem->OnConnectedToPhoton.AddDynamic(this, &UMyGameInstance::HandleConnected);
}
Back to top