Multiplayer FPS Project

The game idea

The idea of the game was to create a multiplayer arena first-person shooter game, based on games like Counter-Strike and Borderlands.

Early gun and map testing

The staples of the genre are guns, fast-paced action, shooting and teamwork!

We planned multiple classes, and an upgrade system, and was advised to implement a Tax system, which would add an interesting twist on the gaining money to spend it on upgrades “story”.

As a programmer, I had a plethora of task and this is just a recap of some of what I was involved with.

Multiplayer Synchronization

For a multiplayer game to be a real-time multiplayer, we need to synchronize certain data so that all of the connected players can see the same thing. These include player positions, movements, and in a game like ours, the place where other players aiming and if they are shooting or not is important. Not to mention the fact that there are deployable items, grenades, mines, etc.

We used Photon’s PUN2 library for most of the synchronization problem.

While Photon “automatically” deals with the position and the rotation of an object and the collisions within the scene other data needs to be synchronized manually.

Synchronizing data – Writing on the client, reading on the remotes

We use the OnPhotonSerializeView to handle these data. We send data from a player’s GameObject to the same player’s remote GameObject on another player’s client. We only send data that is essential for another player’s to know, like where the player is looking, is the character shooting or not, and even how much health does the player have.

Remote Procedure Calls – To deploy throwable items like grenades

While OnPhotonSerializeView runs frequently, there are processes that we don’t need to share too often. With remote the Remote Procedure Calls, we can call a function of the MonoBehaviour on all the instances of the GameObject on the network. These are called rarely, for example, when a player throws a grenade, to minimalize the data we need to share on the network.

Statistics and Database

We need to save the players’ data to be able to review how the game is being played. We set up a database and a statistics system to be able to monitor certain events in the game.

The online part of the system is a PHP CRUD, which receives data from the clients, validates it and store it in the database.

Sample from the database

For both on the PHP and Unity side, we needed a simple pattern that can be repeated for multitudes of statistical data packages, the different pieces of information we wanted to save.

Example of the data-package creation that will be sent to the PHP CRUD

On both side we created the main CRUD functions (Create, Read, Update, Delete), to be able to communicate data efficiently. The sent data is validated on both Unity and PHP side for safety reasons.

UI – Scalable Lobby options

We wanted the game to be customizable so the players could create a more tailored experience. These options needed to be simple to create and not needing too much extra coding to implement.

What we ended up with is the following system:
First, you create an Enum with the possible options. This list is easy to read for anyone wanting to implement a new option. The names need to be clear and represent the value they are meant to be associated with.

Possible Lobby Options created as an Enum list

We created the “LobbyOptionHandler” that is connected to the UI object that is displaying the specific Lobby option. It also handles the displayed labels, so we don’t need to set them up for every option individually.

Setting up a Lobby Option in the editor

We also have a Lobby Options List, which is a static class, that stores all de possible values the specific options can hold. These items are also designed to clearly indicate what values they hold, which Option type they are referring to, and are easily expendable.

Lobby Options data lists in code

There are other parts to this system, that handles sharing and communication, but this is the main body for creating possible options for the game.


As a first dive into the world of multiplayer games, this project was more than an efficient introduction. It improved my understanding of game systems and the importance of modularity.

Even from a coding point of view, creating a multiplayer game has a vastly different philosophy than a single-player game.

Play testing the finished game