Game Classes

Fusion Online Subsystem

UFusionOnlineSubsystem is a UGameInstanceSubsystem reached via GameInstance->GetSubsystem<UFusionOnlineSubsystem>(). It owns the UFusionClient and UFusionRealtimeClient for the whole process and is the entry point for every connect, join, and room-management call.

The subsystem exposes the room/session flow (ConnectToPhoton, JoinOrCreateRoom, ChangeWorld, StopFusionSession), the status queries (IsConnected, IsInRoom, IsMasterClient, Status, GetLocalPlayerId), and the lifecycle delegates (OnMapLoadRequested, OnMapLoadPerform, OnMapLoadDone).

C++

UFusionOnlineSubsystem* Subsystem =
    GetGameInstance()->GetSubsystem<UFusionOnlineSubsystem>();

GameInstance

UGameInstance is networked under Fusion. Its properties will persist for as long as the UFusionClient remains alive.

Replicated properties on UGameInstance are a good way to store global state that needs to survive world changes. Because the GameInstance persists across ChangeWorld for as long as the UFusionClient is alive, values set on it carry over between maps without re-spawning a networked actor or rebuilding the GameState. See Replicated Properties for the actual sync path. For the same reason it is also a reliable place to fire global RPCs to all connected clients regardless of which world each peer is currently in — the GameInstance is guaranteed to exist on every connected client, so the RPC target is always resolvable. Declare these with the SEND_FUSIONRPC macro; the built-in Server/Client/NetMulticast markers do not route on a UGameInstance, because it is not an actor (see RPC Basics).

GameMode

Every client constructs its own AGameMode locally. Fusion is distributed-authority, not server-only, so there is no single peer that runs the GameMode "for real" while everyone else proxies it. Each peer's AGameMode is a full Unreal instance from the engine's point of view, and all the standard hooks (HandleMatchHasStarted, HandleStartingNewPlayer, RestartGame) fire locally on every peer.

This differs from stock Unreal where only the dedicated server runs the GameMode. The shared-authority model and what "authority" means under Fusion are covered in Ownership.

C++

void AMyGameMode::RestartGame()
{
    if (!OnlineSubsystem->IsMasterClient()) return;
    Super::RestartGame();
}

Gate match-flow code (RestartGame, HandleMatchHasStarted, login hooks) on UFusionOnlineSubsystem::IsMasterClient() so it does not fire on every peer. Without the gate, the same logic runs once per client and effects multiply by player count — exactly the behaviour that the stock UE "server-only" rule prevents in dedicated-server projects.

GameState

The GameState is networked automatically with Master Client ownership, so only the Master Client's writes propagate to other peers — and the ownership auto-transfers to the new Master Client on master migration without application code.

The Network Time from Fusion is patched into the GameState meaning projects can use stock AGameStateBase without a Fusion-specific subclass and the world-time fields stay synchronised automatically.

MatchState is also replicated as part of GameState, but be aware of it being a default value on non-master clients before the remote value has replicated.

PlayerState and the InactivePlayerArray

UFusionClient auto-attaches a UFusionActorComponent with Ownership = EFusionObjectOwnerFlags::PlayerAttached to every APlayerState. The PlayerState's lifetime follows the owning Fusion player: it is created when the player joins and destroyed when the player leaves.

Disconnected players that a client has observed have their PlayerState stored in the standard AGameMode::InactivePlayerArray as in stock Unreal networking.

PlayerController and Pawn

APlayerController and APawn use standard Unreal behaviour. Each client runs the normal HandleStartingNewPlayer / RestartPlayer chain locally and spawns its own APlayerController and pawn — no MasterClient gating is needed in this path. Possession follows the usual APlayerController::Possess flow.

Back to top