Building a Turn-Based Multiplayer Game with GameSparks and Unity - Part 1


In this tutorial, we’ll introduce GameSparks platform and we’ll teach you how to build a simple turn-based multiplayer game inspired by a classic Gomoku, under a working title ‘Hearts and Skulls’.

Instructions will be mostly focus on integrating GameSparks and Unity. We’ll explain some GameSparks basics, but previous Unity knowledge is required (on an intermediate level).

In this tutorial we’ve been using the 2017.1.1f1 version of Unity, but any of Unity 5 or 2017 (previous or future releases) versions should work.

Before we get started, you can check out the final result and play our live demo (run it in two separate browser tabs if you can’t find a multiplayer match). After you have an idea about what the finished application looks like, download all Unity assets (sprites and fonts) we’ll be using. If you need more details about how everything is set up in Unity, download the complete project.

Important! The demo site and downloadable assets available using the links in the preceding paragraph are solely and exclusively maintained and provided by The Knights of Unity. If you have any questions about any of this material, please contact The Knights of Unity directly.

Rules of Gomoku

Gomoku, also known as Five in a Row, is a strategy board game for two players. Gomoku boards come in various sizes, but we’ll use one that is 15x15. Players take turns in which they place one of their pieces on one of the empty fields on the board. The goal is to form a consecutive chain of five pieces (no less, no more) either horizontally, vertically, or diagonally.

Additional tournament rules can be added to the game to minimize the first-move advantage but we’ll start out with the simplest variant.

You can find more information about Gomoku and some strategy tips at GomokuWorld.


Introduction to GameSparks

GameSparks is a cloud service which offers almost everything you might need for your game when it comes to backend solutions. Among its many features are:

…and many more. For a more complete list of features see GameSparks features description page.

GameSparks and the client app (in our case Unity) can communicate in a couple of ways.

GameSparks uses interceptors to execute your custom server code (called Cloud Code) at interception points. There are four key interception points:

You can use any of these interception points to implement your custom logic. To learn more, see the diagrams at the official documentation page.

All communication with the service is done in the context of a user. Therefore, before your app can make any requests or receive messages you have to use one of the available authentication methods.

You can customize the matchmaking process in any way you want. Skill-based matchmaking is also very easy to implement. GameSparks uses Matches to find groups of players that meet given criteria. After a Match is found, a game or a room has to be created.

In GameSparks, this can be achieved by using Challenges. Challenges, however, have a much broader application. You can use them for any activity that is performed by one or more players. They are fully customizable (this is outside of scope of this tutorial, though).

An important feature of GameSparks is the Test Harness. You can use it to fully test your game before launching it with the use of a GUI to send Requests, inspect the platform Responses, and debug your Cloud Code.

We’ll further explore all of these concepts. To learn more you can always use the official documentation.

Account Setup

To create a GameSparks account, head to the registration page. After a successful login you will be able to create a new game configuration.

The Creating a Game page in the official documentation explains how to create a new game. Follow the instructions. We won’t need any currencies set up at this moment. Enable the following platform features: Events, Multiplayer, Cloud Code:

Fig. 1: Platform features which we need enabled for this tutorial


GameSparks offers several authentication methods. We’ll use the simplest one which is username and password. Users have to register an account before being able to use it. We don’t have to configure anything on the GameSparks side to make it work.

Match and Challenge Setup

To be able to match our players we have to configure a Match first. Go to Configuration/Multiplayer. Select Matches tab and click the ‘Add’ button. Fill in the form as shown in the image below.

Each Match has to have at least one Threshold configured. Thresholds are used to fine-tune the search algorithm. You can set narrower or broader player-skill requirements. You can also specify a period of time after which (if no match is found) the next Threshold will be used. If there are no more Thresholds, matchmaking will end with MatchNotFoundMessage.

To learn more about Thresholds visit the official documentation page. We won’t be using skill-based matchmaking yet, so we’ll just add one Threshold that matches players at any skill level.

Fig. 2: Match and its Thresholds configuration.

Click ‘Save and Close’.

After two players are matched we need to create a Challenge for them (which in this case could be also called a room). To configure a Challenge, switch to Challenges tab and click the ‘Add’ button. Fill in the form as shown in the image below:

Fig. 3: Challenge configuration.

Click ‘Save and Close’.

GameSparks doesn’t automatically create a Challenge instance when players are matched. We have to write our own Cloud Code to create and automatically accept a Challenge. Go to Configurator/CloudCode, select UserMessages/MatchFoundMessage and open it.

Fig. 4: MatchFoundMessage script in the Cloud Code Configurator.

This script will execute before MatchFoundMessage is sent to all of the interested players. Paste in the following code:

// First player in a match will be the challenger.
if (Spark.getPlayer().getPlayerId() === Spark.getData().participants[0].id) {
    var tomorrow = new Date();
    tomorrow.setDate(tomorrow.getDate() + 1);
    var request = new SparkRequests.CreateChallengeRequest();
    request.challengeShortCode = "DefaultChallenge";
    request.endTime = tomorrow.toISOString();
    request.usersToChallenge = Spark.getData().participants[1].id;

We can obtain a lot of information about the match and the message context from the Spark object. Now go to UserMessages/ChallengeIssuedMessage and open it.

Fig. 5: ChallengeIssuedMessage script in the Cloud Code Configurator.

This script will execute before ChallengeIssuedMessage is sent to the challenged player. Paste in the following code:

var request = new SparkRequests.AcceptChallengeRequest();
request.challengeInstanceId = Spark.getData().challenge.challengeId;

We can test our matchmaking process using the Test Harness. Open the Test Harness in two separate web browser windows. Send two RegistrationRequests to create two user accounts and then send an AuthenticationRequest from each browser window.

Fig. 6: Test Harness - player one has sent a RegistrationRequest and has received a RegistrationResponse (in the Inspector, on the right).

Fig. 7: Test Harness - player has sent an AuthenticationRequest and has received an AuthenticationResponse.

Now send a MatchmakingRequest from each browser window.

Fig. 8: Test Harness - player has sent a MatchmakingRequest and has received a ChallengeStartedMessage which was dispatched from our script.

You should receive ChallengeStartedMessages in both browser windows.


So far we've learned how to create a new game configuration, match players, and create a Challenge. In the next part of this tutorial, we’ll start with implementing the game logic (using Cloud Code) and finish GameSparks configuration, so we can then focus on building the Unity app in parts 2, 3, and 4.

// End of Part 1.

Go to Part 2

IMPORTANT! This tutorial is solely and exclusively the product of a 3rd-party. Though we have agreed to make the tutorial accessible to the wider GameSparks user community in this section of our Learn site, GameSparks accepts no liability for any errors or omissions it might contain.

Did this page help you? Please enter your feedback below. For questions about using this part of the platform, please contact support here