Networking in Photon

Recently, I posted my findings with Unreal Engine 4’s networking system.  I wanted to compare it to working with Photon Unity Networking, which I’ve grown accustomed to.  The original post can be found here, and I’ll be going over the same concepts.

Setup

Before players can start a game, they need to connect to Photon’s cloud servers, and then find a room to connect to.  Each room represents a collection of PhotonPlayers in a game together, and has a unique string to name itself by.  When rooms are created, they can be accessed by anyone by iterating through PhotonNetwork.roomList.

So to make a new room, a unique name needs to be assigned to it.  Alternatively, feeding null into the CreateRoom function will generate a unique name.

This model is for the sake of simplicity. When the game starts up, it’s just going to attempt to join any room at random, and if that doesn’t work, it’ll create one. It does this by performing actions within OnJoinedLobby and OnPhotonRandomJoinFailed, which are functions that are automatically called when clients join lobbies and attempt to join rooms.

For a more practical system, check out my PUN Server Browser.

RPC Functions


To create an RPC function, the “PunRPC” attribute tag needs to be added above the function declaration.  Depending on what the function does, it should also be conscious of if the client currently executing the function is the owner or MasterClient (server).

Calling the RPC means the PhotonView component on the object needs to be obtained, and used with specific parameters:

  • The name of the function as a string
  • The PhotonTargets: the people that are going to receive and run this function
    • All: every player currently in the room
    • MasterClient: the server
    • Others: everyone but me
    • ViaServer: send the function through the server
    • Buffered: includes all the types above, but also includes anyone who’ll join later
  • Any parameters to the function: these parameters must be supported types by Photon

Any validation must be handled by the code.  When making an authoritative system, I usually handle actions (like adding HP) by sending an RPC to the master client requesting to execute a function , which will be checked first for legitimacy.

Synchronization & Smoothing

Synchronizing data requires implementing the OnPhotonSerializeView function in any class that has data to be watched.  First off, drag and drop the class into the object’s PhotonView

Next off, add the function to the class, and handle sending and receiving the data:

So, the first if statement is saying “is Photon trying to send data, and am I looking at my own character right now?” If so, then send “my” HP so everyone else knows how much I have.
The second statement is setting the HP of everyone’s characters to whatever got sent by their associated clients. An authoritative model would have the master client handle the sending, so no one can say they know their HP value better than the host.

This data is being sent and received at variable time-intervals depending on how long it takes for the packet to reach everyone’s machines. With something like movement, this means that someone’s position is not being updated every frame. Unlike Unreal, smoothing a player’s movement needs to be written, which can be seen in my post on network smoothing in PUN.

Checking Authority

Lastly, the few tools that I rely on very often with Photon are:

  • PhotonNetwork.isMasterClient: am I the host?
  • this.getComponent<PhotonView>().isMine: is this object owned by my client?
  • my PhotonPlayer instance: this has a bunch of properties and IDs that I use.  Each PhotonPlayer has a Custom Properties hashtable, which can be used for storing synchronized values specific to individual players, such as score and stats.  Additionally, it has a unique ID associated with it, which I use in special cases for referencing specific players on the network.

My Take

I’ve been using Photon Unity Networking for a little over a year now for my Unity games, and I think it’s an extremely powerful tool.  Unlike Unreal, there’s very little abstraction when it comes to using Photon: conceptually, it’s pretty similar to working with RakNet, where I have more control over what I’m doing.  Photon is not too different from Unity’s legacy networking, but it eliminates a lot of the hassle with setting up lobbies that go beyond LANs.

Leave a comment