Game Modes & Sessions
Three modes, one prefab, one set of gameplay code. What changes between them is which layer wakes up — and getting two machines into one game is a host reading four numbers out loud.
Three modes
GameContextis the session-lifetime source of truth for which mode is running. Every system that behaves differently across modes reads this one place, rather than each inventing its own "am I online?" flag.
| Field | Type | What it does |
|---|---|---|
SinglePlayer | GameMode | One player, one machine. No session, no lobby, no split-screen. Pure component stack, zero networking overhead. |
LocalCoop | GameMode | Several players, one machine, split-screen. Still no networking — but per-player cameras, HUDs and spawn points are all active. |
OnlineMultiplayer | GameMode | Several players, several machines. The full network stack, with replicators active on every networked object. |
using Curitor.PartyCoreKit.Core;
// At session start -- the lobby already does this for you.
GameContext.SetMode(GameMode.OnlineMultiplayer);
// Anywhere that genuinely differs between modes:
if (GameContext.Current.IsOnline) ShowLobbyPanel();
if (GameContext.Current.IsMultiplayer) ShowSplitScreenHud();
// Back to the menu.
GameContext.ResetSession();| Field | Type | What it does |
|---|---|---|
Mode | GameMode | The active mode. |
IsOnline | bool | True only in OnlineMultiplayer — a live networked session. |
IsMultiplayer | bool | True in LocalCoop and OnlineMultiplayer. The question 'is more than one person playing?', which is a different question from 'is there a network?'. |
IsAuthority | bool | True when this machine decides. Always true offline; online it means you are the server. This is the check that lets one piece of code be correct in all three modes. |
You should rarely need to ask
The mode flag exists for the decisions the architecture cannot make for you — whether to show a lobby, which save backend to use, whether to run matchmaking. It is deliberately not how features become network-aware.
Features are network-aware through the replicator split: a pure logic component, and a transport adapter beside it that simply never wakes up offline. No #if, no IsOnline branch inside the feature. If you find yourself reaching for IsOnline inside gameplay code, that is usually the signal that the thing wants a replicator instead. See Replicators.
What the lobby does
The lobby scene offers three doors: Play Local (single-player or split-screen, depending on how many devices join), Host, and Join. Picking one sets the game mode, loads the chosen level, and places players at the level's spawn points.
A hosted session is described by a SessionInfo: title, id, address and port, which level, how many players it holds, how many are in it, and whether the round is already underway.
Getting two machines into one game
Online play is direct connect: one player hosts, the others connect straight to them. No accounts, no subscription, no service in the middle.
One player hosts
On the Host panel, the session shows its id and the address other machines join at — something like192.168.1.42. That address is picked from the machine's own network interfaces, preferring the local network one.They read it out
To the room, over voice chat, in a message. It is four numbers.Everyone else types it into the lobby
The Join panel has an address field under the session list. Type the address and press Join by address. The port is filled in for you unless you type one with a colon.
One prefab, three modes
The claim in the lead is worth spelling out, because it is what the architecture is for:
| Field | Type | What it does |
|---|---|---|
The player prefab | identical | The same prefab in all three modes, carrying its replicators. Offline they never spawn; online they do. Nothing is added or removed per mode. |
Gameplay code | identical | Stats, inventory, interactions, rounds — the logic components import nothing from the transport layer, so what you write against them works everywhere. |
Cameras and HUDs | per player | One per local player. In split-screen that is several at once; online it is one, with remote players' camera objects switched off. |
Ownership | mode-dependent | Offline every character is locally controlled. Online, ownership decides who drives what — which is what the owner-authoritative replicators key off. |
One prefab, or one per level
"One prefab" above is the default, not a hard rule. A game mode that wants a damage-free shove instead of a real melee hit, a different stat set, or extra components for just ONE level does not have to reconfigure Player.prefab and every other level along with it. LevelDefinition carries an optional playerPrefabOverride: set it, and every spawn path — a local join, an online connection, a bot — instantiates that prefab instead of the default while this level is active. Leave a level without one, and it keeps spawning the shared default exactly as before.
| Field | Type | What it does |
|---|---|---|
Local join (CoopSpawner) | offline | Resolves the override into PlayerInputManager.playerPrefab the moment the level's spawner enables, before the first player joins. |
Online connect | OnlineMultiplayer | SceneFlowController's connection-approval callback points the connecting client's PlayerPrefabHash at the override's registered NetworkObject. |
Bots (BotSpawner) | hosted | A bot is instantiated from the same prefab a human joining that level would get — override or default, whichever applies. |