This article is intended to cover the basics of real-time multiplayer game development in Unity and will help you get started with it. Since networking is at the heart of multiplayer games, we will start by exploring different network architectures used in different types of games. We will then evaluate the pros and cons of each network architecture and help you decide which one is most suitable for your game. Lastly, we will share our experience of the challenges and problems that we faced when we developed our first multiplayer demo using Photon Unity Networking (PUN) and what we did to solve these problems.
Let’s discuss each of these topics in detail one by one.
The core concept of computer networking & multiplayer game development is that two or more computers are connected together to establish communication. This concept enables us to connect multiple players in a game. In essence, what we want is to share the game state with all the players who are connected to each other.
There are different network architectures that are used to achieve this behavior, such as:
- Client-Server architecture
- Peer to Peer architecture
- Hybrid architecture
1. Client-Server Architecture
Client-server architecture and its characteristics:
In a client-server architecture, all of the clients (nodes) are connected to a main centralized server. The server is responsible for providing all of the updates related to the game state to the clients & also for connecting the clients with each other. Generally, in the client-server architecture, the server is authoritative i.e. if we abstractly define the role of clients, then the clients simply forward the user inputs to the server & receive the updated game state from the server.
Some of the main client-server advantages are as follows:
- It is much easier to code, manage communications & handle problems like cheating in a centralized environment.
- The implementation of the client is much simpler as it has less work to do. This is particularly useful in mobile gaming where clients have limited resources.
And some of the client-server disadvantages are:
- As the server is the most integral part of this setup, deploying & maintaining these servers is a very crucial task & also not an easy one.
- Communication time is increased as every message needs to go through the server to reach the other end.
- As all of the information flow happens through the server, this results in a single point of failure & can lead to network congestion.
2. Peer to Peer Architecture
Characteristics of peer to peer architecture:
In this topology, two or more peers are connected directly to each other without the need of any centralized server. All of the peers in this setup have the same set of responsibilities that is receive user inputs, update their state according to the game logic & broadcast this new state to all of the other peers connected to the game.
Some of the benefits of peer to peer architecture based games are as follows:
- Data transmission is faster as the data goes directly to its intended target instead of going to the server first.
- Setup is simpler as you only need to think about one instance of your game.
- This architecture is more reliable in the sense that if one of the peers gets disconnected the overall system won’t be affected.
- Since there is no centralized server you do not need any hosting services.
On the other hand, some of the more obvious disadvantages of peer to peer architecture are as follows:
- Since peers have complete control over what data is sent over the network. It is very hard to control if any players try to cheat.
- Fault tolerance is very low. If one or more players crash during the game it is very hard to recover the state as opposed to client-server setup where it’s much easier to recover.
- Synchronization can be hard as all of the peers are communicating with each & every other peer in the game.
3. Hybrid Architecture
Hybrid architecture tries to incorporate some of the benefits of client-server in p2p architecture. In hybrid approach instead of having a dedicated authoritative server, one of the peers is selected to be the master client. The master client is then given the responsibility of a server. Therefore the actions that should be done in an authoritative manner are performed by the master client instead. Also, a facilitator server also known as relay server might be introduced in the system which usually stores meta-data related to game sessions such as a number of players in the session, etc.
Which architecture should you use?
Now that we have developed a basic understanding of the different architectures available, the next important question to answer is which architecture a developer should use in their game. There is no single architecture that can give the best output for all types of scenarios. Therefore in order to assess which architecture is the most suitable for your game, you should answer the following questions:
What type of game am I developing?
The kind of game you are developing & the number of concurrent players in a game session is one of the main factors that drive which architecture you should use for your game. If you are developing a turn-based game, an RTS game or any other game which can be abstracted into a series of turns and a set of command messages when processed at the beginning of each turn direct the evolution of the game state then p2p is the better option. You might use p2p for other types of games too if the number of concurrent players is small but if the number of concurrent players increases p2p fails to provide the required performance & switching over to client-server is necessary.
What level of security do I need in the game?
As we mentioned earlier in the disadvantages of p2p architecture that it's very hard to control problems like cheating & access control in p2p since all the peers have complete control over their game logic & also on what data they send to other clients. Therefore if security is a major concern in your game then you would want to use client-server or hybrid architecture.
Do I want just an easy solution that works?
If you do not have the resources to host your own servers or if you do not want to build everything from scratch and you are looking for a solution that gets you up & running as soon as possible then a framework which uses the hybrid approach such as Photon Unity Networking (PUN) is the best option for you.
Our experience with PUN
The multiplayer demo we made is 3v3 capture the flag version of Unity’s Survival Shooter sample. Since our game has six concurrent players in a game session so using p2p was a viable option for us, but there were some parts of the game that needed to be handled in an authoritative manner thus we needed a master client which controlled these parts and most importantly we were looking for a pre-built solution that helped us prototype faster. So using PUN was the obvious choice for us. Also, PUN has many other features such as authentication, matchmaking, cross-platform support which makes the development much easier.
Photon automatically handles the basic functionalities such as connecting the players to the game session; the next part is to sync the game state. There are different methods available for sending game state related updates:
- Continuous Updates
- RPC’s & Events
For data like position, animation flags, etc continuous updates are used as we need this data to be in the latest state to keep all elements of the game flowing smoothly. But since there is always some network lag, to solve this problem interpolation is used to calculate the possible values between two received updates. The number of continuous updates should be kept as small as possible. And always consider options for optimizing the data that is sent, e.g. in first iteration we synced both position & rotation vectors, but after some careful consideration we found that our characters only move along X, Z-axis & rotation is only changed in Y. We can fit all of this information in one vector instead & reduce the data being sent to half of its original size.
For data which only need to be synced when a particular event happens we use RPCs & RaiseEvents. Both are used to call functions at remote instances. Since these are also network calls, we have to consider for the lag between the time the call is sent from the sender & received at the other end. We learned this the hard way while developing the shooting system for our game we started by simply sending RPCs for each fire. For cases when latency got high, this approach failed. Due to lag, the positions of characters at sender might be different from the one at the receiving end. Thus the player might hit the other player on the local instance but on the remote instance the same shot could show up as a missed hit. To solve this problem, instead of just syncing the fire event we also started sending the hit data as a parameter in the RPC and then used this data at the remote instance to keep the fire hit/miss states in sync.
The most important point that needs to be carefully considered is which method to use for syncing a particular state element & how to further optimize it so that it has the least possible impact on the network.