Unity :: The Last Train to Salvation

Salvation is a city management survival game set in a world overrun with undead. It currently exists as a work-in-progress prototype.

The player controls a train full of survivors as they make the perilous journey north to the city of Salvation, where the bitter cold freezes the dead in their tracks and offers the only sanctuary from the dreadful hordes.

Each stop on the journey is an opportunity to search for supplies, rescue survivors, and expand the train. But each stop is also a risk as the sound of the arriving train draws ever-increasing hordes into the city. How long can the bedraggled band stay before they have to move on? Can they find enough food and fuel to make it to the next stop? Will the train be able to leave in an ordered fashion, or will the ravenous horde force a departure before all the survivors are aboard?

Key Features

  • Tile-based gameplay: The main gameplay features a tile based city map. The survivors must fight the horde for control of each tile, then expand their defensive perimeter to grow their safe zone.
  • City building: Everything is temporary and everything can be left behind. Captured buildings can be cleared and equipment can be unpacked from the train to convert them into workshops, barracks, and hospitals. When the time comes they must be packed away if they are to be used again at the next stop.
  • Hordes: Arriving in ever increasing numbers, they crash against the players defences until they no longer hold, forcing the survivors to flee the city. Can enough resources be gathered in time? Can every survivor make it back to the train as the hordes become overwhelming? Who will the player have to sacrifice?
  • Sprawling Europe: Ride the train network that crisscrosses Europe searching for a route north. Choose from multiple paths through different cities.
  • 21 Unique Cities: Each with its own story to tell and unique challenges to face. There are human threats from competing bands of survivors, cults of religious fanatics, and cannibals who will do anything to survive. There are physical challenges with collapsed bridges that can’t be crossed, failed nuclear reactors irradiating vast areas, and flooded cities where tidal barriers are unmanned.
  • Heart Wrenching Choices: Over the course of a level the player will accumulate survivors, supplies, and equipment, but not all will fit on the train. What will they pack when they depart, who will they leave behind? With limited space there are tough choices ahead, do you take the soldier that can defend the train, or the child that can’t defend itself?
  • Waylay Event Mini Levels: Not every journey between cities is uneventful, sometimes there are unexpected challenges to overcome. These are presented as tight challenges on mini levels, where the player has a short amount of time to get there train moving again before they are overrun by the horde.

Unity3D Construction


Image 1 of 3

The prototype for Salvation is constructed in the Unity3D engine, which I have been working with for 4 years.

Each city has its own game board constructed from a set of tiles, with each tile representing a city block. These tiles utilises the power of the prefab system to create city maps that are rich in variety.

The player assigns characters from the ‘person pool’ to perform ‘jobs’ on the tile. The pool is a managed database of characters and jobs are processed against them. The nature of these jobs is determined by context of the tile, who owns the tile and what buildings the tile has.

The player manages available resources to ensure the survival of all their characters. Food, water, and other resources are gathered in a pool and then assigned to city tiles to be consumed by its occupants. Uneven distribution can be used to favour tiles that are completing important tasks, but this can lead to dissent within the survivors. Further problems arise with events occurring, generic or city-specific, that force the player to adapt.

The objective of each level is to clear the train’s path and exit the city with as many survivors and supplies as possible. Once the game board has a clear path of track tiles from the train to an exit tile the player can exit the level.

Custom Tile Editor

Salvation uses a custom tile editor to rapidly create content and ensure each map has a unique look and feel.


Image 1 of 5

The Tile Editor gives the designer a simple and intuitive interface that allows them to quickly create content for their levels. The editor handles all the hook-ups that are required to make a tile function in the game, freeing up the designers time to focus on the purpose of the tile and the narrative touches that make it feel unique.

The editor allows the designer to draw from a palette of prefabs created by artists. Each prefab on the palette has been created from a collection of art models that have been blended together to create a kind of brush. The designer can then put these together to form a tile and export it as a game-ready asset.

The final tile is future-proofed by drawing from a base tile prefab as a parent. All common functionality is placed in this prefab, allowing

Code Highlight – IMouseInteractable

When learning Unity I followed various tutorials, each used a mouse interface that relied on using tags and a switch statement. Whilst this is a simple system to implement and works well for small projects, it doesn’t scale well. I have a better way.

Declaring a simple interface

Image 1 of 5

A simple mouse interactable interface is declared and can then be implemented by any script assigned to any object that needs to interact. The mouse handler has no concept of the object it is interacting with, it simply Raycasts for any object with an IMouseInteractable interface and then calls the required method from the interface. This allows the mouse to interact with unlimited objects, as long as they implement the interface.

Once created, the mouse interaction system does not need to be changed and any number of people can code interactions simultaneously without creating errors across the project.

There are drawbacks to this system. It uses GetComponent() in every update step as the components can’t be cached off, but this is a small overhead cost to pay. It also can’t be used with Unity DOTS, which doesn’t allow the use of object-oriented polymorphism.