Improbable sent a team of developers to the Nordic Game Jam; this is a description of their game, and highlights from their source code.
"whatever you make with SpatialOS is multiplayer by default, we did have a good shot at creating some sort of online game"
This year saw Nordic Game Jam enter its 10th year, with the 2016 edition promising to be bigger than ever at an amazing 900 attendees. A team from Improbable jumped across to Copenhagen to participate, and tried to build a game in 48 hours.
In a completely unsurprising move, we decided to use SpatialOS and Unity. Nobody in their sane mind would try to create an MMO in a 48 hour game jam, but since whatever you make with SpatialOS is multiplayer by default, we did have a good shot at creating some sort of online game. Nevertheless, we quickly became known as “those guys trying to build the MMO”.
Making online games is difficult for several reasons, which is why you don’t see more of them in game jams. Perhaps the greatest one is the need to write netcode, a thankless and error-prone task that few people enjoy, and that can easily consume your 48 hours by itself. Fortunately this issue didn’t apply to us at all, due to our choice of platform.
Another problem is creating enough content to keep the game interesting for several players over an extended period of time. We decided to attack this problem in two different ways.
First, instead of relying on tons of scripted content and events, we’d build a world that worked by itself; we’d give the entities of the world interesting behaviours, add a lot of them, and let them loose. This would let us create something with a big scope without unnecessary effort, and which would feel organic and be different every time you played.
Second, we ditched the idea of a long-running game. In the context of a game jam, we knew the other participants would try our game for just a few minutes before moving on to the next one, so we created round-based gameplay mechanics. Even though SpatialOS game worlds are persistent by default, this doesn’t mean they have to be.
Having solved these technical issues, we got building, and Toxic Justice Squad was born. The full source code is available on our GitHub here.
The theme of Nordic Game Jam was “leak”. We took that theme and built a city under siege from deadly toxic waste leaks. Civilians wander about the city and become contaminated after contact with the toxic slime. Not only are civilians able to pass on contamination through contact with each other, but they will eventually be overcome by the contamination.
Representing the theme, the slime was of utmost importance. This had to be Nickelodeon game show quality slime. The team had watched a talk by Unity’s Andy Touch earlier in the day, on building custom shaders, and used this to make some authentic slime:
We went through various iterations of the shader, which initially took the appearance of a violent, noisy green sea before being tweaked to look more like thick jelly that wobbled slightly. Learning how to write a shader (albeit a simple one) was an unexpected, but enjoyably demystifying experience.
With slime spreading through the city, all hope seems lost. But Toxic Justice Squad to the rescue! Players join the Toxic Justice Squad, gathering civilians together and herding them to safety. Players can call civilians to them, and scare them away, in order to guide them to safety, a trusty burger stall! As well as being able to guide the civilians, the players can utilise their handy bubble gun to clean off the contamination, and halt the spread of the slime. Bodies of the contaminated are still infectious, requiring cleaning with the bubble gun.
In building Toxic Justice Squad, we discovered another hurdle in online game design: it requires large amounts of time to be fun. In a setting where players would only be briefly exposed to our game before moving on to see the next project built during the jam, we had a couple of minutes at most to expose the players to everything we had to offer.
Because of this, gameplay takes place over frantic, fast paced rounds. This is reminiscent of typical multiplayer shooters. This is a really interesting idea; with fast interaction cycles and a player base increasingly composed of casual gamers with limited time to devote to the game, what new experiences can be built from easily achievable massive scale, using familiar gameplay modes?
Marcus speaks about how this round-based gameplay model was achieved in SpatialOS:
Toxic Justice Squad is round-based, so we needed a way to reset the whole world so that after everyone is infected and the city is covered in slime (or you happened to successfully evacuate everyone), the game starts afresh and you can take another shot.
"If GTA has taught us anything, it’s that games are always made more fun by tanks."
To do this, we stored the global information including current time, score and remaining citizens in a GameNature entity which is synchronised to all of the player clients. A WorldApp then forwards messages from other entities in the world about events such as a citizen being evacuated to this GameNature entity to keep the properties up-to-date. The GameNature entity ticks every second to update the time and is responsible for resetting the world once the time reaches zero. Actually resetting the world is as simple as removing the remaining citizens, spawning new ones around the city and teleporting the players back to the starting points, as seen here.
If GTA has taught us anything, it’s that games are always made more fun by tanks. Game jam projects are very susceptible to feature creep, and sure enough, the allure of vehicular mayhem proved too much to resist, so Callum implemented a tank that could hold multiple occupants. With time against him, Callum explains how he managed to implement the tank:
The tank in Toxic Justice Squad can take multiple passengers at once – one of which is the driver. To add this feature in the time available I made heavy use of the Core Library Transforms feature. If you add the Transform nature to your entity then position, rotation and parenting are taken care of for you.
When a player enters the tank, the tank is made the parent of the player. When the tank moves the player moves with it. The player’s entity is sent a message when it becomes a child. In this case we disable player movement and hide the player model when the player’s entity is a child of the tank.
Another advantage of using Transforms is that child entities do not have their position or rotation synchronised unless those things change relative to the parent, saving bandwidth. This didn’t have a large performance impact in Toxic Justice Squad, but can be a large performance saving on games like Worlds Adrift, where ships have many parts attached to them.
With short rounds, multiplayer tanks, and crowd herding, unexpected gameplay emerged. We expected players to work together to save the city, but of course they had different ideas. We very quickly saw players pulling crowds away from would-be do-gooders, and driving the poor civilians into pools of slime. We saw tanks ploughing through crowds, frustrating the rescue efforts. With players from the game jam being joined online remotely in the same world by Improbablers back in London, what was a fight between players and slime, became a hilarious free-for-all.
The full source code of Toxic Justice Squad is available here.
Building a large multiplayer game in such a short time frame taught us a lot about our own platform, and gameplay mechanics that make multiplayer experiences fun. We enjoyed experimenting with more traditional multiplayer gameplay modes in a massive scale experience, and can’t wait to try it again.