How to quickly build a 200-person FPS with Unity and SpatialOS


SpatialOS GDK for Unity launch

Dan Griliopoulos is Lead Content Editor at Improbable. This tutorial was last updated 7/11/2018 – for the the most up-to-date tutorial, please visit our onboarding documents.

Traditionally, building a scalable multiplayer game was beyond the scope of a small dev team – the need for hosting, network engineers and the like tended to put people off. SpatialOS’ special sauce is that it takes away a lot of that complexity, but also increases your game’s potential. That’s best shown off by our new Game Development Kits (GDK) – we’ve just released one for Unity and we’ll be releasing the one for Unreal on October 30th, 2018. And included in the GDK for Unity is a 200-person FPS that you can test out today.

For those who don’t already know what SpatialOS does: it’s a platform for creating games that go beyond the limits of a single server, enabling you to implement new kinds of gameplay that would be impossible with the traditional single-server approach. As a fully managed service, it does all of the work required to host, run and scale your game globally while you focus on finding the fun.

This FPS Starter Project is a module (a bundle of code and assets) that adds solid FPS functionality to a Unity SpatialOS game. If you run this code with the SpatialOS GDK for Unity on our servers, you can have as many as 200 players (real or simulated) playing stably at once without paying any hosting fees while you’re developing. In fact, we’ve included all the assets, maps, animations and so on – and you officially have our permission to reuse all of this for your own SpatialOS games, commercial or otherwise.

Today, I’m going to show you how to set the project up, get friends into it (or a bunch of bots) and get a glimpse into the back end, so you can see the tools that will help you manage your virtual world.

SpatialOS FPS Starter Project

Setting Up

To get started, you first need to sign up for a SpatialOS account. Again, every step of this is free. Then you need to set up your machine with the right prerequisites. (I’m assuming you’re using a PC – there are instructions on our docs for Mac.)

  • First, you need to install Unity 2018.2.8. Make sure you download the Installer version and select the ‘Linux Build Support’ and ‘Mac Build Support’ components during installation.
  • Then you need to install the .NET Core SDK (x64), verified with versions 2.1.3xx and 2.1.4xx.
  • After this installation completes, you should restart any Unity and Unity Hub processes. This will prevent errors where Unity cannot find the dotnet executable.

Now you can install SpatialOS. The installer includes the Command Line Interface, the Launcher (for launching game clients), and Visual C++ Redistributables. Next, install a code editor – we prefer Visual Studio or Rider. For Visual Studio, you’ll need to go to the Workloads tab and select ‘.NET Core cross-platform development’, then ‘Game development with Unity’, then deselect any options in the Summary on the right that mention a Unity Editor. Make sure Visual Studio Tools for Unity is included (there should be a tick next to it). For Rider, you just need to install the Unity Support plugin.

Bring on the Clones

Now you need to clone two repositories from our Github: the FPS Starter Project and the GDK for Unity.

Clone the FPS starter project using one of the following commands:

Either this command for SSH

git clone

Or this one for HTTPS

git clone

Then clone the GDK for Unity and checkout the latest release. From the root of the gdk-for-unity-fps-starter-project repository, run:

powershell scripts/powershell/setup.ps1

You should now be ready to open the project.

SpatialOS unity GDK header

Open Sesame

Launch the Unity Editor. It should automatically detect the project; if it doesn’t, select ‘Open’ and then select gdk-for-unity-fps-starter-project/workers/unity.

The next step is to apply two quick Unity bug fixes. First, you need to fix a bug with shader compiling:

  1. Open the FPS Starter Project in the Unity Editor located in workers/unity.
  2. In the Project panel, navigate to Assets > Fps > Art > Materials.
  3. Right-click on SourceShaders and press _Reimport.

Next, you need to fix a Navmesh import bug. To rebake the navmesh:

  1. Open the FPS-SimulatedPlayerCoordinator scene located at Assets/Fps/Scenes.
  2. Click on the FPS-Start_Large object in the Unity Hierarchy window, and enable the object.
  3. Open the Navigation pane by clicking on Windows > AI > Navigation.
  4. Navigate to the Bake tab and click on the Bake button.

You can verify that the NavMesh has been baked correctly by navigating to Assets > Fps > Scenes > FPS-SimulatedPlayerCoordinator, and checking that Unity displays the correct icon (a figure walking along a dotted line).

The next stage is to build out the code executables which will be run by SpatialOS servers on the cloud deployment – these are called workers. In the Unity Editor, you first need to make sure Burst compilation is disabled from Jobs > Enable Burst Compilation. Then you can build your workers from the SpatialOS menu by clicking Build for cloud > All workers.

SpatialOS menu, Build for cloud > All workers

This can take some time – so don’t click away. When the Unity Editor’s Console window says  Completed build for Cloud target you’re ready. After the build has successfully finished, the gdk-for-unity-fps-starter-project/build/assembly folder should contain:


Getting your game online

Now you need to set your project name, upload your worker assemblies and launch a cloud deployment.

To set your name, you need the generated name that was automatically associated with an organisation and a project when you signed up. To find this name enter the Console. It should look like:


SpatialOS project page screenshot

Using a text editor of your choice, open gdk-for-unity-fps-starter-project/spatialos.json and replace the name field with the project name you were assigned in the Console. For example, you might replace ‘”name”: “unity_gdk”‘ with ‘”name”: “beta_yankee_hawaii_621″‘.

Now we need to upload the worker assemblies – the bundles of code, art, and other files that run the game in the cloud. We can only do this in a terminal, via the spatial CLI. You must also give the worker assemblies a name so that you can reference them when launching a deployment.

Using a terminal of your choice – for example, PowerShell on Windows – navigate to gdk-for-unity-fps-starter-project/ and run spatial cloud upload <assembly_name>, where <assembly_name> is a name of your choice (for example fps-assembly). A valid upload command would look like this:

spatial cloud upload myassembly

It’s finished uploading when you see an upload report printed in your terminal output. Based on your network speed, this may take a little while (1-10 minutes) to complete. For example:

Upload report: - 5 artifacts uploaded (4 successful, 1 skipped, 0 failed)

The next step is to launch a cloud deployment using the assembly that you just uploaded. This can only be done through the spatial CLI.

When launching a cloud deployment you must provide three parameters:

  • the assembly name, which identifies the worker assemblies to use. The name needs to conform to the following regex: [a-zA-Z0-9_.-]{5,64}.
  • a launch configuration, which declares the world and load balancing configuration.
  • a name for your deployment, which is used to label the deployment in the SpatialOS web Console. The name needs to conform to the following regex: [a-z0-9_]{2,32}.

Using a terminal of your choice, navigate to the root directory of your SpatialOS project and run

spatial cloud launch --snapshot=snapshots/default.snapshot <assembly_name> cloud_launch_large.json <deployment_name>

where assembly_name is the name you gave the assembly in the previous step and deployment_name is a name of your choice (for example, shootyshooty). A valid launch command would look like this:

spatial cloud launch --snapshot=snapshots/default.snapshot myassembly cloud_launch_large.json shootyshooty

This command defaults to deploying to clusters located in the US. If you’re in Europe, add the –cluster_region=eu flag for lower latency. It’s finished when you see ‘Deployment launched successfully’ printed in your terminal output.

Play the game!

Back in your SpatialOS web Console, you should now see the deployment that you just created appear under your project. Select it to get to the Overview page. Hit the Play button on the left, and then launch. We already have the launcher, so ignore the installation prompt, and just click Launch.

Once the client has launched… you’re playing in your own cloud game! But it’s a bit lonely, so let’s invite some friends. From the Console, head back to the Deployment Overview page and select Share. This generates a short link that anyone can access for the duration of the deployment.

If human players aren’t enough for your purposes, then you can add simulated players to the world. These bots are fairly primitive, but they’re useful for mimicking player behaviour in scale and functionality testing. Each one is a Unity Client running in the cloud

To get the legion of enemies started, we will use Worker Flags, which you can find from your web Console’s Deployment Overview page:

Worker flags page, SpatialOS

Modify the fps_simulated_players_per_coordinator flag value from 0 to 10 and hit save:

worker-flags-modification, SpatialOS

What this will do is start up 10 simulated player-clients per Simulated Player Coordinator worker (of which there are 20 running in the deployment), and they will connect-in every 2 seconds (dictated by the fps_simulated_players_creation_interval flag). Be warned: if you exceed 10 fps_simulated_players_per_coordinator you may experience deployment instability. Go back into your game, and you’ll see the simulated player-clients running.

The World in Action

Head back to the Deployment Overview page of the SpatialOS web Console (shown below) and click the Inspect button. This brings up the World Inspector, which is a real-time view of what’s happening in your deployment, from a top-down strategy game analytics perspective. (I totally want someone to make a Dwarf Fortress style game that uses just the World Inspector…)


The World Inspector shows where all the entities are, what their components are, which workers ) provides a real-time view of what’s happening in a deployment, from the perspective of SpatialOS: where all the entities are, what their components are, which workers are running and which entities they are reading from and writing to.

We can use it, for instance, to highlight where all the simulated player-clients and player-entities are in the world (note: not cool to identify where your friends are hiding).

logs-app SpatialOS

One tab further on is the Logs app which displays all your deployment’s logs (whether they come from the SpatialOS Runtime or the Worker code you have written) with useful filters. And another tab to the right are the Metrics dashboards, which show a selection of useful metrics with annotations to identify the health of your deployment.

 Metrics dashboards SpatialOS

What’s next?

The next step is to build your game! We’re trying to help out with that a little bit, though, by providing Feature Modules – optional features that you can choose to add to your game (player lifecycle, for example). There’s also a tutorial that takes you through the workflow of writing your own feature, health pick-ups – that’s a good next step to get deeper into the guts of SpatialOS.

Other developers are also working on their own projects, building and sharing features – our own Paul Balaji has created a Battle Royale ‘shrinking circle of death’ add-on, whilst Trond Fasteraune (Beyond The Sleep) is working on something to get his Mini-MMO Project Nobody up and running. And Cookie Dragon Games has a working prototype stamina/ammo add-on as well.

For more information about the SpatialOS GDK for Unity, you can go to our launch blog; for more help getting on-board, visit our docs, pop into our forums, or hop onto Discord.

More solutions. More possibilities.

Explore all IMS solutions