Networking
This is a big topic, so it is divided up:
Some Definitions
- Player: Game representation of one physical human or bot player. Has a player slot in menus and a player figure with controller in a match. Each Player can be customized which is synced over the net. There is always at least one (Main) Player, which cannot be removed, while other local players can be added and removed freely.
- *Client: An instance of the game, which can play offline, host or join a match.
- Main Player: Each Client needs to have at least one human Player, which is set up and loaded during startup and cannot be removed. This is the Main Player.
- MasterClient: The instance of the game having control over a match. In an online game, the Master is the owner of the current room. In an offline game, the current client is considered MasterClient as well (over the local offline room). He is still also a Client.
- JoinedClient: All clients in a room, which are not the MasterClient. They joined the room afterwards.
- Room: Association of one or more Clients as a group playing together. This allows data exchange, instantiation, concurrent scene loading and more features. Being in a room is the precondition for Photon's in-game API to function.
Offline Play
After the startup, the local client is not connected automatically. Offline Play is enable by simulating a connection to the servers via Photon's so-called 'Offline Mode'. Local players can be added and a local match can be started. The goal is to use as much code as possible for offline and online play. Instantiation happens - internally - as usual for offline games, as opposed to online instantiation over the network. In Photon Offline mode, a 'room' for this single client is created as well, allowing use of the same data storage (etc.) functionality which would be used during online play.
Connecting
A connection attempt explicitly ends the simulated 'Offline Mode'. This means data shared via room properties has to be saved locally as well and is to be carried over to a new 'online room'. A connection attempt can fail for a number of reasons, including user or network interruption. See 'Disconnecting' for an overview of this topic.
There are multiple successive steps involved:
- Connecting to the Photon Master Server
- Creation of a new room
- Joining the new room as MasterClient
Hosting (aka. being the MasterClient)
Upon successful connection, the local client acts as the MasterClient of the new room with only him present. Being the MasterClient implies having authority over a number of networking aspects, such as:
- Extended user options as Host of the game (Level selection etc.)
- Scene transitions
- Networked object Instantiation and Destruction
- Match Start, End etc. (Initiation of game state transitions)
Joining (aka. being a JoinedClient)
Joining a game means selecting one of the available hosted rooms. In joining (also as MasterClient), a Client sends information on his players to all other clients in the room. Each client thus keeps track of all players.
- Todo:
- : This is to be changed by using room properties (see below)! A JoinedClient has restricted authority over certain game aspects, see MasterClient section.
Disconnecting
A disconnect comes in two shapes:
- Actual disconnect from the Internet game service -> majority of cases.
- Logical disconnect from the simulated connection to the Master Server during Offline Mode.
While the second form should ideally never happen, we should guard against it. In any case, the requirement after such an event is to:
- Display a message stating the reason to the user
- Regain a stable state in activated Offline Mode, allowing local play at least. The game state must be reset so that no side effects remain.
This requires:
- Detection of a Disconnect: Done via an Event from the NetManager
- Halting of current gameplay
- Restriction of user interaction with Menus & Game Objects: Display a Message Overlay
- Reset of the game state towards the main menu in the background, including re-activation of Offline Mode.
Disconnect of other Clients during Online Play
- Todo:
- Think about Disconnects of other Clients during Online Play
Similarities between Host and joined Clients
This is an important part from an implementation perspective:
- Local players and remote Players are displayed in Slots, with the local players coming first and displayed differently than remote ones.
- An "add Player" button is displayed if new players can still be added. The maximum amount of local and total players thus has to be the same across Clients.
Networked game aspects
There are two main points for what and how to synchronize aspects of the game over the network.
- Consistency of the game state over all clients (Sync): Avoid e.g. a player being hit on one client but not on the other.
- User experience: The game should not offer advantages or disadvantages for hosts or clients introduced by lag or deviating not-networked game object states.
Data synchronization via room properties
- Todo:
- Using room properties for syncing e.g. of player data is not yet implemented!
Other Networking Tasks
- Player Management: Changes to players need to be synced. This is best done via specific events: This encompasses all player information valid independent of match states. Send all local players if:
- Entering a new room -> send to all, unbuffered (bit of overhead for self, as it creates an update)
- A new client enters a room -> send to him specifically Send one local player if:
- A new local player is added -> send to all others
- A local player is changed -> send to all others
- A local player is removed -> (own event) send to all others
- Player Figures: information concerning the state within a match
- Player figure instantiation -> information on spawn positions is sent out by the match manager. Then the spawning is done by each client separately. Additional information on the looks of every figure is read from the player list by each client and applied during or after instantiation.
- Player figure transform -> Photon Transform View
- Hitpoints -> monitor and sync for UI via PhotonView
- Bombs available -> monitor and sync for UI via PhotonView
- Status effects -> monitor and sync for UI via PhotonView (No status effects impl. yet! Could also be done by events.)
- Being Hit -> calculated on owning client for correct user experience, propagation done via hit points
- Death -> calculated on client, propagation via event. (Could also be done via hit points client-side, but those are shared with unreliable transmission, which is not good for something that important.)
- Game objects: in-game objects with influence on game state or UX.
- Bomb instantiation -> Bomb placement sent via RPC and instantiated per client. RPC used to target the player figure instance setting the bomb individually and correctly.
- Bomb explosion -> Calculation per client with Hits on Player figures and environment. This is reliable enough to be calculated client-side. The explosion timing with independent instantiation needs to be tested for potential negative influence. A global explosion target time could be sent with the RPC or the delay calculated and subtracted from the timer.
- Power-Up Spawn: The type is random and thus decided on the master only and spawned for all -> photon view and Photon-based instantiation needed. No sync of transform needed as animation not relevant for gameplay.
- Power-Up Collection: Has to be calculated on client-side for UX. Destroy via network.
Photon Networking mechanisms
- RPCs: Call a specific function on all Client's PhotonViews with the same ID. You can transmit function parameters as well. This is good for keeping the same objects in sync. -> Use to act on objects that have a PhotonView anyway.
- Events: RaiseEvent allows to send an event package with data to specific clients. Any method can be registered to handle this event. No PhotonView is needed. This is good to announce ...err... events, concerning multiple receivers and can be targeted better than the RPC.