Multiplayer And Networking
The Escapists 2 - Multiplayer And Networking system documentation
The multiplayer system is built on Photon PUN 2 (specifically PUN 2.45) and provides a custom abstraction layer (T17Net*) over Photon's raw API. The architecture is split into three tiers:
- Photon PUN 2 – Low-level transport (rooms, RPCs, custom properties, load balancing).
- T17Net Abstraction – Custom wrapper providing connection state machines, agent-based room management, property synchronization, load sync, and object locking.
- Application Layer – MonoBehaviour consumers (lobby UI, character controllers, prison details, etc.) that use T17Net classes.
Table of Contents
- Core Architecture
- Connection State Machine
- Room & Matchmaking
- Photon Integration Layer
- Load Synchronization
- Game State Synchronization
- Player / Character Synchronization
- Object Interaction (Locks)
- Crossplay
- Lobby UI
- Debug & Tools
- Networking Peer (Photon Peer)
- Encryption & Security
- Friend Invites
- Time Management
- User Data & Analytics
- Room Details (Prison / Blueprint)
- Glossary
Core Architecture
T17NetManager (Singleton)
Entry point for all multiplayer operations. Lives at the Persistent scene level.
Key Responsibilities:
- Initializes
PhotonNetworkviaT17NetInit.Start()which callsPhotonNetwork.ConnectUsingSettings(). - Holds the connection state machine (
T17NetConnectAndJoinRoom). - Holds the PhotonView registration dictionary (
NetViews) mappingNetViewIDs->T17NetViewobjects. - Manages the room name generator (
T17NetRoomNameGenerator) for creating unique room IDs. - Stores the local player's data (
T17NetLocalPlayerData): userId, userName, platform, gameVersion, appVersion, etc. - Provides cross-scene persistence of networking state.
Transitions between scenes:
T17NetPersistence→ carries theT17NetManagerinstance across additive scene loads.- When entering game sessions, instantiates a
T17NetRoomGameViewfor room property sync.
Local Player Data (T17NetLocalPlayerData):
UserId/UserName– from platform auth (Steam ID, Epic Account ID, etc.)Platformenum:None, Steam, EGS, PSN, Xbox, DevGameVersion/AppVersion– used for version-gating matchmakingUseUDPflagRegion– preferred Photon regionQueueType– PvP vs CoopIsPrivateRoom– whether hosting a private roomIsQuickMatch– whether using quick matchNetEncryptionKeyType– symmetric key variantCrossplayMask– bitmask of allowed platforms for crossplayGameModeType– GameType (Prison vs Blueprint)
T17NetConfig (ScriptableObject)
Configuration asset holding:
PhotonAppId/PhotonAppVersionServerAddress/UseNameServer/FixedRegionEncryptionKeysarrayEnableTrafficStats,LagSimulationSettings,PeerLogLevel- Timeout and disconnect thresholds
- Room creation limits (
MaxPlayers,EmptyRoomTTL,PlayerTTL) PUNLogLevel- Crossplay platform icons
T17NetworkManager
A small manager that provides an Awake() hook to configure PhotonNetwork settings from T17NetConfig before Photon initializes.
Connection State Machine (T17NetConnectAndJoinRoom)
Drives all connection workflow via a stack-based state machine. Each state is a T17NetAgentBase subclass.
Agent Stack & Execution
- Agents exist as a flat list, with an active index (
_currentAgentIndex). - Only one agent executes at a time.
- Agents can push follow-up agents onto the stack, creating sequences.
- When an agent
Done()s (success), the next agent begins. - When an agent
Failed()(error), anOnNetConnectionFailedevent fires and a retry/quit prompt is shown.
States are implemented as these agents:
| Agent | Purpose |
|---|---|
T17NetAgentInit | Ensures Photon is connected; if not, connects. |
T17NetAgentEnsureLobby | Ensures we join the correct Photon lobby (PvP or Coop). |
T17NetAgentCreateRoom | Calls PhotonNetwork.CreateRoom() with room options (max players, visibility, custom properties). |
T17NetAgentJoinRoom | Calls PhotonNetwork.JoinRoom() by name. |
T17NetAgentJoinRandomRoom | Calls PhotonNetwork.JoinRandomRoom() with matchmaking filters. |
T17NetAgentStartGame | Final state: loads the game scene additively, spawns the T17NetRoomGameView, and signals completion. |
T17NetAgentWaitForCloudWait | Handles a "cloud wait" period (room list before rejoin). |
Execution Flow Examples
Host Game: Init → EnsureLobby → CreateRoom (with room options) → StartGame
Join (by name or invite): Init → EnsureLobby → JoinRoom (by name) → StartGame
Quick Match: Init → EnsureLobby → JoinRandomRoom (with filters) → StartGame
Reconnect: Init → EnsureLobby → WaitForCloudWait → JoinRoom → StartGame
Room Options (T17NetRoomOptions)
Built before creating a room:
MaxPlayers(from T17NetConfig or game mode)IsVisible/IsOpenCustomRoomProperties(aHashtable):RoomCode– 6-character join codeMapName– level identifierMapDisplayName– localized display nameCurrentPlayerCount,MaxPlayerCountGameMode– "PVP" or "COOP"GameType– "Prison" or "Blueprint"HostPlatform– platform of the hostHostUserId/HostUserNameCrossplayMaskEncryptionKeyTypeVersionCompatibility– game version stringLevels– semicolon-separated level list (BluePrints)Tags– Free-form tag list
CustomRoomPropertiesForLobby– which keys are visible in the room list
Error Handling & Retry
On failure, the OnNetConnectionFailed event fires with:
FailReasonenum:None, CreateRoomFailed, JoinRoomFailed, JoinRandomRoomFailed, NotConnectedToMaster, NotJoinedLobby, StartGameFailed- A UI prompt offers Retry or Quit to Main Menu (if not in-game).
Room & Matchmaking
Room List
When in a Photon lobby, PhotonNetwork.GetRoomList() returns available rooms. The system filters these:
T17NetRoomInfoFilter – a ScriptableObject filter used to pre-filter rooms:
MinimumNumberOfPlayers/MaximumNumberOfPlayersMinLevelsX/MaxLevelsXGameModefilter (PvP, Coop, or Any)GameTypefilter (Prison, Blueprint, or Any)
PunRoomListHelper – MonoBehaviour that:
- Listens to
PhotonNetwork.OnRoomListUpdate(internal Photon callbacks) - Caches the filtered list of rooms
- Emits
RoomListChangedevent - Exposes
RoomCountproperty
Lobby room list UI (T17NetRoomListScreen):
- Populates a scroll list from
PunRoomListHelper - Each entry is a
RoomInfoListEntry(UI prefab) - Shows: room name, player count, map, game mode, host name
- Join button triggers
T17NetAgentJoinRoom
Quick Match
- Calls
PhotonNetwork.JoinRandomRoom()with matchmaking filters derived from local player preferences:- Game Mode (PvP/Coop)
- Game Type (Prison/Blueprint)
- Crossplay settings
ExpectedMaxPlayersExpectedUsers(for party join)
- On failure, optionally creates a new room.
Private Rooms
- Rooms created with
IsVisible = false - A 6-character RoomCode is generated (uppercase alphanumeric, no ambiguous chars)
- The code is set as a custom room property (
RoomCode) and also exposed as theRoomCodeproperty onT17NetManager - A shareable URL is built:
teardown://join?room=<code> - The invite system uses this URL for deep linking
Lobby Types
PunLobbyTypeenum inPunLobbyTypeHelper:Default, PvP, Coop, SqlSqlis used for SQL-style lobby queries if using Photon's matchmakingPvP/Coopare custom lobby names
Room Cleanup
EmptyRoomTTLandPlayerTTLare set from config- On
PhotonNetwork.LeaveRoom(), theT17NetManageremitsLeftRoomevent
Photon Integration Layer
T17NetView (MonoBehaviour)
Custom wrapper around PhotonView:
- Has a unique
NetViewID(int) - Registers/unregisters itself with
T17NetManager.NetViews - Provides
OwnerID(who owns/controls this networked object) - Provides
IsMine– true if the local client is the owner - Provides
IsRoomView– true if this is the room-global view (not owned by any player) - Synchronization: Component-based synch via
T17NetSyncBehaviour(see below) - Ownership: Supports
OwnerShipMode:Fixed– owner never changesRequest– ownership can be requested (e.g., object lock)Takeover– ownership can be taken
- Custom Properties per view via
T17NetViewCustomProperty
Room View – A special T17NetView with IsRoomView = true. Used for room-global synchronization (game state, load sync).
T17NetSyncBehaviour
Component attached to a T17NetView to synchronize specific data. Works in two modes:
- Owner Write → Others Read: The owner (IsMine) writes data; all other instances read.
- All Write (for room views): Everyone can write.
Key methods:
OnSync(stream)– Serialize/deserialize custom data viaT17NetSyncStreamOnRequestWrite()– Called to determine if a write should happenHasDataToSync/HadDataToSync– Write pending/just-wrote flagsNetSyncTypeenum:Delta, Full, Once, Off
Example implementors:
T17NetRoomGameView– syncs game stateNetCharacterObserved– syncs character transforms and stateNetPlayerObserved– syncs player dataNetObjectLock– syncs lock stateT17NetLoadSync– syncs loading progress
T17NetSyncStream
Custom binary stream for T17NetSyncBehaviour serialization:
- Wraps
PhotonStream(or a custom byte buffer) - Provides typed read/write:
Bool,Int,Float,Vector3,Quaternion,String,Byte,Bytes,ByteEnum IsWritingproperty to differentiate serialize vs deserialize path
T17NetSendMonoMessageTarget
Attribute-like system for sending RPCs to MonoBehaviour targets:
T17NetSendMonoMessage(string methodName, T17NetSendMonoMessageTarget target, object[] args)- Target types:
All,AllBuffered,Others,OthersBuffered,MasterClient - Internally uses
PhotonView.RPC()to call the method on the target component - Used for sending "mono messages" to all players (e.g., start game, load complete)
T17NetHelpers
Static utility methods:
GetLocalPlayerData()– returnsT17NetLocalPlayerDataGetNetViewManager()– returnsT17NetManagerinstanceGetCurrentRoom()– returnsT17NetRoomGameViewfor the current roomGetRoomViewT17NetView()– returns the room'sT17NetViewIsRoomOwner()– checks if local client owns the roomGetT17NetView(NetViewID)/GetT17NetView(PhotonView)– lookupAreWeOffline()– are we in offline/menu modeIsNetViewIdValid(int)– checks > 0IsNetViewOurs(int)/IsNetViewTheirs(int)BroadcastNetMessage(string methodName, object[] args)– sends mono message to allSendNetMessageSecure/SendNetMessageToMasterClientSecure– encrypted sendsGetNetworkObject<T>(NetViewID)– generic typed lookupInstantiateNetObject(GameObject prefab)/DestroyNetObject(T17NetView)– networked instantiationGetRandomJoinCode()– generates a 6-char room code
PhotonView / RPC Management
T17NetRPC – class that wraps a Photon RPC call:
- For reliability, falling back to raw
photonView.RPC()ifT17NetSendMonoMessagefails - Handles buffered vs. non-buffered sends
Load Synchronization
T17NetLoadSync (MonoBehaviour)
Attached to the Room View. Synchronizes all player load states across the network.
Process:
- Each player reports their loading progress via
UpdatePlayerLoadState(PlayerLoadState). - Data is serialized into
T17NetSyncStreamonOnSync(). - Deserialized on all clients to build a complete picture of who is loaded.
PlayerLoadState – enum:
NoneLoadingLevelDownloadingDependenciesLoadingDependenciesSettingUpPlayerReadyFailed
Events:
OnAllPlayersReady– All players have reachedReady.OnPlayerLoadStateChanged(T17NetPlayer, PlayerLoadState)– Individual updates.OnPlayerJoinedLate– Someone joined after the game started (late join).
NetLoadManagerSync
Manages the game ready state:
- When all players are
Ready, callsStartGame()onGameManager. - If a player is
Failed, handles error flow.
PlayerLoadState
Tracks loading progress with these states:
None– hasn't started loadingLoadingLevel– loading main sceneDownloadingDependencies– downloading assetsLoadingDependencies– loading downloaded assetsSettingUpPlayer– player setup logicReady– fully loaded and ready to playFailed– loading failed
Each player reports their state to the room view, which aggregates and triggers events.
Game State Synchronization
T17NetRoomGameView (MonoBehaviour)
Central game state synch object. Created when the game starts (by T17NetAgentStartGame).
Custom Properties (Room → All clients):
Synchronized via Photon's Room.SetCustomProperties():
CurrentPlayerCount(int)MaxPlayerCount(int)GameState(enum:WaitingForPlayers,Loading,Playing,GameOver)CurrentLevelIndex(int) – which level the group is on (BluePrints mode)SelectedLevels(string) – semicolon-separated list of chosen levelsDifficulty(int/float)StartTime(long) – epoch timestamp when game startedGameTimeRemaining(float) – for timed modesPrisonDetails(serialized JSON) – prison-specific dataBlueprintDetails(serialized JSON) – blueprint-specific dataMapName/MapDisplayNameServerAnnouncement(string) – admin broadcast messages
Sync Behaviour:
- Implements
T17NetSyncBehaviourto sync aT17NetRoomGameState:GamePhaseenumCurrentLevelLevelsRemainingElapsedGameTimePrisonDetails/BlueprintDetailsblob
- Updated by the Room Owner (MasterClient) and read by all others.
Events (UnityEvents):
OnGameStateChangedOnLevelChangedOnPlayerJoined/OnPlayerLeftOnAllPlayersLoadedOnGameTimeUpdated
NetRoomCustomProperties
Helper to read/write typed properties from Room.CustomProperties:
SetProp<T>(key, value)– sets a propertyGetProp<T>(key, defaultValue)– gets a property with fallback- Change callbacks via
OnPropertyChanged
Player / Character Synchronization
NetPlayerObserved
Synchronizes player-level data (not character):
PlayerNamePlayerPlatform+ Platform icon IDPlayerReadystatus (lobby ready toggle)PlayerTeam(for team-based modes)PlayerColor/PlayerCosmeticsselectionPing/LatencyIsAlive/IsSpectatingKills/Deaths/Score(stat tracking)CustomizationData(serialized customization choices like outfit, hat, etc.)
Attached to each player's T17NetView. Owner writes, others read.
NetCharacterObserved
Synchronizes per-frame character state:
Position(Vector3) – smoothed via interpolation/ extrapolationRotation(Quaternion)Velocity/MovementDirectionIsGrounded,IsJumping,IsSprinting,IsCrouchingHealth/ShieldAnimationState(enum / int) – current animation state IDAnimationFloatParams– float parameters for blend treesWeaponEquipped– ID of currently held weaponAmmoInClip/ReserveAmmoInteractionState– what the character is interacting withEmoteState– currently playing emote
Owner writes → Others interpolate. Uses T17NetSyncBehaviour with NetSyncType.Delta for efficiency.
CharacterNetEvents
Manages one-shot networked events for characters:
TakeDamage(float amount, int attackerId, string damageType)Heal(float amount)Die(int killerId, string cause)Respawn(Vector3 position)PlayEffect(string effectName, Vector3 position, Quaternion rotation)PlaySound(string soundName)TriggerAnimation(string triggerName)EquipWeapon(int weaponId)DropWeapon(Vector3 position)Interact(int objectId, string interactionType)
Uses T17NetSendMonoMessage (RPCs) for reliable delivery.
CharacterSerializer
Handles efficient binary serialization of character state:
- Position delta compression
- Quaternion smallest-three compression
- Animation state as byte
- Health as half-float or byte
- Bitpacking for boolean flags
Object Interaction (Locks)
NetObjectLock
Synchronizes lock state on interactable objects (doors, gates, levers, etc.).
Properties synced:
IsLocked(bool)LockOwnerId(int – player ID who locked it)LockStateenum:Unlocked, Locked, Locking, UnlockingLockTimeRemaining(float) – for timed locksInteractionCooldown(float)
Ownership Handling:
- Objects use
OwnerShipMode.Request - When a player interacts, they request ownership via
T17NetView.RequestOwnership() - On ownership transfer, the new owner writes lock state
- After lock state is written, ownership returns to original (if
Fixedmode) or stays (ifRequestmode)
Events:
OnLockStateChanged(bool isLocked, int ownerId)OnLockInteractionStart(int playerId)OnLockInteractionComplete(int playerId)
T17NetView Ownership
Methods:
RequestOwnership()– asks MasterClient to transfer ownershipTransferOwnership(int playerId)– force-transfer (MasterClient only)OnOwnershipRequest(PhotonView ownerView, int requestingPlayer)– callback for authOnOwnershipTransferred(int newOwnerId)
Crossplay
CrossplayLobbyManager (ScriptableObject)
Manages platform-specific room filtering and crossplay settings.
Key Properties:
AllPlatforms– list of supported platform enumsPlatformIcons– mapping from Platform to SpritePlatformNames– localized display namesCrossplayMask– bitmask computed from enabled platforms
Room Filtering:
- Stores the
CrossplayMaskas a room custom property - When querying room list, filters rooms whose
CrossplayMaskmatches the local player's mask - Quick match includes
CrossplayMaskin matchmaking filters
Platform Detection:
T17NetLocalPlayerData.Platformis set at loginPhotonNetwork.LocalPlayer.SetCustomProperty("Platform", platformString)is set on join- Other players' platforms read from their player custom properties
Crossplay Icons:
- Each room list entry shows platform icons of connected players
CrossplayLobbyManager.GetPlatformIcon(Platform)provides the Sprite
Quick Match with Crossplay
PhotonNetwork.JoinRandomRoom()usesExpectedPropertiesfilter includingCrossplayMask- Matchmaking ensures only rooms with compatible crossplay settings are returned
- If no match, a new room with the player's crossplay mask is created
Lobby UI
LobbyPlayerObject
Displays a player in the lobby (before game starts):
- Player name, platform icon, ready state toggle/indicator
- Color/cosmetic selection UI
- "Kick" button (host only)
- Ready state synchronized via
NetPlayerObserved
CoopPlayerObject
Similar to LobbyPlayerObject but for cooperative mode:
- Shows role/class selection (if applicable)
- Shows loadout preview
- Ready state indicator
LobbyRoomInfoObject
Displays room information in the room list:
- Room name (truncated)
- Player count (current / max)
- Map name and thumbnail
- Game mode (PvP / Coop)
- Game type (Prison / Blueprint)
- Host name
- Platform icons of connected players
- Lock icon (if private room)
- Ping indicator
- Join button with click handler
T17NetRoomListScreen
Main room list screen controller:
- Populates scroll rect from
PunRoomListHelper - Refresh button to manually refresh room list
- Filter toggles (game mode, game type, player count range)
- Quick match button
- Host game button → navigates to host settings screen
- Join by code input field (for private rooms / invites)
- Empty state ("No rooms found" message)
Debug & Tools
T17NetDebugPanel (MonoBehaviour)
In-game debug overlay for networking info:
- Connection status (Connected to Master/Lobby/Room, disconnected)
- Room name, player count
- Local player ID and ping
- RTT (Round Trip Time)
- Traffic statistics (bytes sent/received per second)
- Photon peer state (PeerState enum)
- List of connected players with their IDs, platforms, pings
- Custom room properties dump
- Log output window (last N log messages)
- Toggle for lag simulation
- Buttons: "Force Leave Room", "Quick Reconnect", "Show Traffic Stats"
Toggle visibility with a hotkey (F8 or configurable).
T17NetPhotonLagSimulationGui
Wrapper around Photon's LagSimulationGui:
- Adds/removes the
LagSimulationGuiMonoBehaviour onPhotonNetwork.PhotonView - Configurable lag/loss settings from
T17NetConfig - Can be enabled/disabled via debug panel
T17NetPhotonTrafficStatsGui
Wrapper around Photon's TrafficStatsGui:
- Toggle visibility of Photon's built-in traffic stats overlay
- Configurable update interval
PhotonRoomLog
Logging utility for room events:
PhotonRoomLog.Log(string message)– timestamps and logs room events- Output target configurable (console, file, debug panel)
Networking Peer (Photon Peer)
NetworkingPeer
A custom extension/wrapper around PhotonPeer / LoadBalancingPeer:
- Provides detailed logging of peer-level operations
- Tracks connection state transitions:
Disconnected → Connecting → Connected → JoinedLobby → JoinedRoom → Leaving - Handles disconnect detection and auto-reconnect logic
- On disconnect: waits a configurable delay, then re-runs the connection state machine from
Init MaxReconnectAttemptsbefore giving up
- On disconnect: waits a configurable delay, then re-runs the connection state machine from
PeerStateenum:Disconnected, Connecting, Connected, JoinedLobby, JoinedRoom, Disconnecting, Reconnecting- Exposes
BasePeerfor direct Photon access
PhotonNetwork Layer
The system configures PhotonNetwork at startup:
PhotonNetwork.UsePunAppSettings = false(usesT17NetConfigdirectly)PhotonNetwork.EnableCloseConnection = truePhotonNetwork.NetworkingClient.EnableProtocolFallback = true(TCP fallback if UDP fails)PhotonNetwork.KeepAliveInBackground = 120(seconds)
Encryption & Security
T17NetEncryptionKeys (ScriptableObject)
Manages symmetric encryption keys used for secure room communication:
- Array of
EncryptionKeystructs:KeyTypeenum:None, AES256, XOR_Simple, CustomKey1/Key2(byte arrays) – the actual key materialHash– SHA256 hash for verification
- Selected via
T17NetLocalPlayerData.NetEncryptionKeyType - Used by
SendNetMessageSecure/SendNetMessageToMasterClientSecuremethods - Encryption applied at the application layer (above Photon)
Secure Messaging:
T17NetHelpers.SendNetMessageSecure(string methodName, object[] args):- Serializes args to byte array
- Encrypts with selected key
- Sends via
T17NetSendMonoMessageasbyte[]encrypted payload
- Receiver decrypts and invokes method
Friend Invites
T17NetInvites
Integrates with platform invite systems (Steam, Epic, etc.):
Workflow:
- Host creates a private room and gets the room code
T17NetInvites.BuildInviteUrl()generatesteardown://join?room=<CODE>- Platform-specific invite mechanism opens (Steam overlay, EGS overlay, etc.)
- Recipient clicks the invite link → deep link opens the game
- Game reads room code from deep link URL → calls
T17NetAgentJoinRoomwith the code
Platform Overlay Integration:
OpenSteamInviteOverlay()– opens Steam's friend invite UIOpenEGSInviteOverlay()– opens Epic's invite UI- Fallback: clipboard copy of invite URL
Time Management
T17NetTimeManager
Manages synchronized game time across clients:
NetworkTime(double) – Photon'sPhotonNetwork.Time, synced via serverGameStartTime– set by host when game beginsGameElapsedTime–NetworkTime - GameStartTimeGameTimeRemaining– for timed game modes (countdown)IsPaused– if the game is paused (all clients agree via room property)TimeScale– synced time scale (for slow-mo effects)
Provides:
GetSyncedTime()– returns the authoritative game timeGetLocalTimeOffset()– difference between local clock and network clock- Events:
OnGameTimePaused,OnGameTimeResumed,OnGameTimeExpired
User Data & Analytics
T17UserDataStore
Per-user persistent data store with network awareness:
UserId→ associates data with authenticated users- Stores: display name, preferences (graphics, audio, controls), friend list, blocked list, recent players
- Syncs selected data to Photon custom player properties (e.g., display name)
- Provides
GetRecentPlayers()– players met in recent games (by UserId)
NetAnalytics
Sends telemetry/analytics events:
- Connection success/failure rates
- Matchmaking queue times
- Room join times (from room list to in-game)
- Player count distributions
- Disconnect reasons
- Performance metrics (RTT, packet loss)
- Platform distribution tracking
Events are queued and sent in batches to reduce overhead.
Room Details (Prison / Blueprint)
NetPrisonViewDetails
Prison-mode specific room properties:
PrisonId/PrisonNameDifficulty(Easy/Medium/Hard/Nightmare)EscapePlan– which escape method is activeGuardCount/GuardBehaviorToolsAvailable– list of tools in the prisonTimeLimit– for timed escapeObjectiveState– current prison objective progress- Syncs via room custom properties (
PrisonDetailsJSON blob)
NetBluePrintDetails
BluePrint-mode specific room properties:
BlueprintId/BlueprintNameLevels– array of level identifiersCurrentLevelIndex– which level the group is playingLevelProgress– per-level completion stateDifficultyProgression– difficulty curve across levelsContinueOnFail– whether failing a level ends the run- Syncs via room custom properties (
BlueprintDetailsJSON blob)
Glossary
| Term | Definition |
|---|---|
| PUN | Photon Unity Networking, the multiplayer framework |
| T17Net | Custom abstraction layer over PUN |
| NetViewID | Unique int identifying a networked object |
| Room View | Global T17NetView for room-scoped state |
| Room Owner | MasterClient – the player who created the room |
| NetSyncBehaviour | Component for custom data synch |
| Mono Message | RPC targeting a MonoBehaviour method |
| CrossplayMask | Bitmask of platforms allowed in a room |
| RoomCode | 6-char alphanumeric code for private room invites |
| PlayerLoadState | Enum tracking a player's loading progress |
| NetObjectLock | Lock state for interactable objects |
| Agent | A state in the connection state machine |
| Load Balancing | Photon's server infrastructure (Master → Lobby → Room) |