Battle Simulation Logic in ECS

The overview

Maxim Zaks
3 min readJun 2, 2019

In 2013 I worked on a mobile game, which genre I would like to call competitive farming. A game where player can build up a city, an army and attack each other.

We build the game in ObjC using Cocos2D, UIKit and Entitas. Entitas is a simple implementation of Entity Component System pattern, or ECS for short.

In this article I will go through one particular aspect of the game implementation, the battle simulation. This battle simulation powered the actual game play, replays and BackEnd validations. Without further ado, I present the list of systems:

In the list above we can see 27 systems which make up the battle simulation.

The syntax I will be using is a made up language, which incorporates ECS concepts. At some point I might build an actual programming language out of it, but for now lets see it just as a pseudo code.

A loop is list of system which is executed repeatedly with a defined frequency.

In next articles I will walk through implementation of every of those 27 systems, to show how one can implement such complex logic with pure ECS concepts. But first let me explain the bits and pieces which are not directly visible from the BattleSimulation loop definition.

The Data

Data in a game can be split up into 3 categories:

  1. Configuration
  2. Player State
  3. Runtime state

If you want to know more, you can pick at my old article:

In the game I am basing this article on, things are no different.

Configuration

We have a config, which defines the characteristics of buildings and units:

  • building size
  • health points
  • strike delay, damage, range and time
  • unit movement speed

Player State

In case of a battle, we have two player states. The player state of attacker contains the information about units they brought to the battle. The player state of defender, contains the town layout (which building is on which position) and how much resources can be looted.

Runtime State

During the game play user interaction will create new data, in our case mainly which unit needs to be deployed on which position. In case of a replay or BackEnd validation, this data is also stored and added to the simulation based on the discrete execution step. Say we want our battle / simulation run for 2 minutes with a frequency of 60. Than there are 60 * 60 * 2 = 7200 discrete simulation execution steps. We need to store user interaction event together with the step number and than replay the event at the given step. This way we have deterministic replay.

There are other things we need to take care of, if we would like to have a deterministic and replay-able simulation. Here are my 5 cents about it:

I will try to keep this series as brief as possible. So for now this is it. Stay tuned for the next article which will dive into the first system in our BattleSimulation loop.

The UpdateGroupObstaclesAndTargetOnDestructionSystem. 😱

--

--

Maxim Zaks
Maxim Zaks

Written by Maxim Zaks

Tells computers how to waste electricity. Hopefully in efficient, or at least useful way.

No responses yet