Building a real-time online multiplayer game with Unity and Go lang.

Aarthik Rao
4 min readJan 15, 2020

--

I have built server-side apps using Go. I wanted to learn how to build cool games using Unity. This is my first attempt at building a game in Unity and building a game server. Ever. In this blog, we will go through the steps to build a real-time online multiplayer game.

An image of an arcade game centre.
Photo by Carl Raw on Unsplash

The game is simple. Jump and shoot. Tapping on the left side of the screen will make the character jump, and tapping on the right side will make the character shoot bullets. Our character has physics and gravity. That means, if we don’t tap fast enough, the character will fall down 😶.

We will be using Unity for building the client UI, and Go-Lang for building the game server. The server will validate every move the client has made. Game state and scores are exchanged between the client and the server using JSON messages over a web-socket connection.

Game Client

All the assets for building the game are available in the Unity Asset store. You can choose different backgrounds, characters, images and audio from there. To connect the unity app to the server, we use Websocket-Sharp.

The game contains two parts, the actual game (where users play) and the lobby (where users enter their names and wait for an opponent match from the server). On successful connection and matchmaking, we enable the game and disable the Lobby.

public GameObject game;
game.SetActive(true);
public GameObject lobby;
lobby.SetActive(false);

Our characters and bullets need to have the RigidBody2D component in their game objects so that they can collide in-game. This will allow us to notify the server that a collision has taken place and take necessary action. We create a fire point right in front of the character so that we can instantiate a bullet prefab when the player wants to shoot.

// To initiate the bullet
Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
// To add velocity to the bullet
public Rigidbody2D bullet;
bullet.velocity = transform.right * 10f;
// When the bullet collides with anything
void OnTriggerEnter2D(Collider2D other){
Destroy(gameObject);
}

Unity does not allow directly manipulating the UI objects, hence we will need a wrapper to en-queue actions on to the main thread.

Game Server

The game server is built in Go. It uses web-sockets to synchronize the objects in the game. The client waits for a positive response from the server and then moves the object in the UI. This is because we want to maintain the synchronization between the two clients.

The client sends JSON messages to the server every time the player jumps or shoots in the game. These messages must be routed to the correct game, validated and sent to the opponent and player with least latency. To make this possible we use multiple goroutines to manage a game.

The message is handled in case of ping, player position updates (including shooting) and collision as follows:

  • Ping: The message is routed back to the same player.
  • Position update: The validity of the message is checked, and routed to the opponent. When the player shoots, a flag fire:true is set to true. You can also keep a tab of the players’ previous location so that client messages can be verified.
  • Collision: In the event of a collision, after verifying the message, the player score/ lives left is reduced and the score is updated to both the players.

When the exit conditions are met for any player, the winner message is sent to both the clients and ExitChan is closed so that all the routines related to this game are closed.

sync.Mutex is used to protect resources shared among multiple goroutines and synchronize the game.

To learn and TODO :

  • When one client is located farther away from the server than the other, it may experience a lag which will cause the game objects in both the clients to lose sync.
  • The server has to take into consideration the physics experienced by the game objects for better validation.
  • Matching players based on ping, skill score and other algorithms.

--

--

Aarthik Rao

Backend, Game developer. Interested in technology, philosophy and politics. Twitter: @aarthikrao