Appearance
GameInstance, Travel, and Bootstrap
Bootstrap starts RedEngine. GameInstance owns one runner and the application-level services around it. Travel destroys the old runner/world pair and creates a new pair for the requested scene. In the Editor, Multi-Peer creates several game instances inside one Unity process.
Execution model
- Authority — the server controls synchronized network scene changes and world gameplay state.
- Prediction — travel and additive scene loading are not Input-Authority prediction.
- Replicated — Fusion scene information and the network actors created in the destination world.
- Local only — loading screen, progress, fades, selected Multi-Peer view, camera, and audio transition.
Bootstrap pipeline
After Unity loads the initial scene, RedEngine.Runtime.Bootstrap performs this sequence:
- load the single
EngineSettingsasset fromResources; - initialize
ContentManagerwithContentInitializationOptions; - read startup arguments and the Editor peer count;
- create and await a server
GameInstancewhen server mode is enabled; - create one or more clients in parallel after the server session is available;
- select the first client as the input-producing instance;
- use one explicit Fusion session name for the server and all local clients.
On application shutdown or when leaving Play Mode, bootstrap waits for content initialization, shuts down every game instance, then shuts down ContentManager.
EngineSettings controls startup
Keep one asset at Assets/Resources/EngineSettings.asset. It supplies:
- the concrete
GameInstancetype; - the
NetworkRunnerprefab; - default client and server maps;
- default server port;
- content initialization options.
The concrete base GameInstance is valid. Create a subclass only when the project needs additional application-level behavior or subsystems.
TravelURL forms
TravelURL represents both local and network travel, plus case-insensitive query options:
text
/Arena
/Arena?Difficulty=Hard
127.0.0.1:27015/Arena
127.0.0.1:27015/Arena?listen
127.0.0.1:27015/Arena?session=Development
127.0.0.1:27015/Arena?Spectator- a URL without a host starts Fusion in
Singlemode; - a URL with a host starts a client;
- the
listenoption starts a server; - the
sessionoption selects the Fusion session shared by server and clients; MapNameremoves directories and the scene extension;url["Option"],Contains, andGetValue<T>read options.
Use TryParse when the URL comes from a player or command line. The implicit string conversion is convenient for trusted literals.
Start travel and observe it
csharp
GameInstance instance = GameInstance.PrimaryGameInstance!;
instance.OnBeginLoadWorld += url => loadingOverlay.Show(url.MapName);
instance.OnWorldLoadComplete += world => loadingOverlay.Hide();
instance.OnTravelFailure += (url, reason) => ShowTravelError(url, reason);
await instance.BrowseAsync(
"127.0.0.1:27015/Arena?Team=Blue");Browse(scene, options) builds a local URL. Browse(url) starts travel without awaiting it. BrowseAsync(url) returns the travel task. Observe OnWorldLoadComplete and OnTravelFailure when the caller needs the outcome and structured TravelFailureReason.
What happens inside BrowseAsync
- resolve the scene through
ContentManager; - shut down and destroy the current runner;
- instantiate the runner prefab from
EngineSettings; - create a new
Worldand connect it toFusionSceneManager; - call
NetworkRunner.StartGamewith single, client, or server mode; - wait for Fusion's simulation scene, with a 30-second timeout;
- initialize the world and its subsystems;
- wait for the local
PlayerControllerand, when the GameMode has a default character prefab, its spawned character pawn; - publish
OnWorldLoadComplete.
Failures are reported as TravelFailureReason values for map resolution, connection, scene timeout, world initialization, local-player spawn timeout, or an unknown startup problem. WidgetSubsystem listens to the travel events to show and hide the configured loading screen automatically. A loading screen's registered hideAnimation completes before the widget is destroyed, so it can cover the full technical spawn and then leave with a short transition.
Only one travel runs at a time. Additional Browse requests are queued and processed in order after the current request. Completed work does not prevent later travel; startup failures are reported through OnTravelFailure before the incomplete world is shut down.
Load additional levels inside the current World
Browse replaces the current runner and world. For streaming a dungeon, combat arena, or another additive part of the same match, use the current World instead:
csharp
using UnityEngine.SceneManagement;
World world = gameInstance.CurrentWorld;
await world.LoadSceneAsync(
"Arena_UpperFloor",
LoadSceneMode.Additive);
// The match continues in the same World and on the same NetworkRunner.
await world.UnloadSceneAsync("Arena_UpperFloor");Both methods delegate to Fusion's NetworkRunner, so scene operations are synchronized through the active network session. Call them from state authority, use the same scene name on every peer, and make the scene available to Fusion and the active Build Profile. Actors found in a loaded scene are prepared for the existing World; this is level streaming, not a second world or a nested game mode.
Use the two scene paths for different jobs:
| Goal | API |
|---|---|
| Replace the current match, server, or map | GameInstance.BrowseAsync(...) |
| Add another level to the current match | World.LoadSceneAsync(name, LoadSceneMode.Additive) |
| Remove an additive level | World.UnloadSceneAsync(name) |
Multi-Peer and the primary instance
GameInstance.Instances contains every live peer in the process. Only the instance whose ProvideInput is true is considered PrimaryGameInstance; changing it also updates Fusion input, runner visibility, camera, rendering, audio, and UI output.
Use GameInstance.SetActiveGameInstance(instance) in editor tooling. Gameplay code should usually find its owning world or call TryGetGameInstance(runner) rather than assuming the first instance. Dedicated server instances cannot become primary and are omitted from the Editor peer selector.
Next: GameMode pipeline.