Category Archives: entity systems

ECS in Unity: Integration and Execution 1

Background

(originally published for Patreon backers November 2016)

General background for all these articles… I’m writing about major areas I’ve ignored in the past, using Unity as a convenient demo-environment for the ideas and tests:

  1. Multi-threading
  2. Querying / filtering
  3. Networking
  4. Unity integration:
    • As easy-to-use as the Unity Inspector (direct editing of components in 3D editor)
    • Easy use of Unity MonoBehaviours/Components on ECS Entities

I don’t want to be too language-centric. I ran a survey to see which languages people are using for ECS’s, and which they wanted more info on – wow, big spread! But talking to people over the past year, Unity kept coming up time and again as a particularly popular one where people want more info.

Screen Shot 2016-11-11 at 16.25.00

Overview: ECS Integration and Execution

Goal

We’re going to build a simple, effective ECS in the same way as you would inside any non-ECS game-engine. At the end of this article, we’ll have an ECS in Unity that interacts with legacy (non-ECS) code cleanly, and demonstrates simple isolation (runs on its own thread). The approach, the test-data, and the problems, should generalize well to other engines.

Steps

  • Make a simple scene in pure Unity
  • Add collision-detection and avoidance
  • Add visualizations so we can see what’s happening
  • Re-create the scene using our ECS
  • Add collision-detection in the ECS

It’s very long, so I’m splitting it into two articles (although Patreon backers will get both at once). The first article has most of the planning, demo-scene creation, and Unity testing. If you know Unity well already, skim-read that. The second article has all of the ECS-specific parts and covers most of the porting from Unity (or: random game-engine) into ECS.

Let’s get started…

Make a simple scene in pure Unity

Creating a new code-architecture inside an existing system is risky and time-consuming (wasting). To make this as smooth and manageable as possible, we’ll create a baseline project in legacy code, port it to ECS, and use that to check assumptions and planning around the ECS design. MVP FTW.

The demo scene

We’ll make thousands of squares move around in 2D on a plane (or, since Unity is a 3D engine: cubes moving on a flat surface, viewed from above).

Screen Shot 2016-11-11 at 17.17.42

Any demo scene will do, but I chose one so that:

  • It uses more than one type of Component on each Entity
  • Different types of Component will ideally be updated by different Processors
  • It’s easy to visualise whether the code is working at all
  • It’s easy to visualise bugs in the code (it’s working, but it’s wrong)
  • An excuse to do some CPU-intensive calculations that benefit from an ECS

In Unity…

Because this is our baseline, needed for lots of testing and ongoing development, we’re going to build most of the scene procedurally. This makes it easy for us to tweak parameters later on (how many cubes? how big? how much room can they move around in? where is the camera? … etc).

Class: CreateScene

This class will run even before the Start() methods, and guarantee we have a flat surface to work upon.

We use Unity’s CreatePrimitive command, that automatically creates not only a mesh (something that gets rendered), but also attaches a physical collider to it, so that any physics objects dropped on the mesh will sit on top of it.

Finally, we grab the scene camera (or create one if there isn’t one already) and move it to sit above the plane, looking downwards.

using UnityEngine;
using System.Collections;

public class CreateScene : MonoBehaviour
{
	public int _planeWidth = 50; // user can edit this in-editor
	public static int planeWidth; // when app starts, this copies the user-chosen value and exposes it to other classes

	public void Awake()
	{
		planeWidth = _planeWidth;
		GameObject plane = GameObject.CreatePrimitive( PrimitiveType.Cube );
		plane.name = "plane";
		plane.transform.localScale = new Vector3( planeWidth + 20f, 1f, planeWidth + 20f );
		plane.transform.position = new Vector3( 0f, -1f, 0f );

		Camera cam = Camera.main;
		if( cam == null )
		{
			GameObject _goCam = new GameObject( "Camera" );
			cam = _goCam.AddComponent<Camera>();
		}
		cam.transform.position = new Vector3( 0f, 50f, 0f );
		cam.transform.LookAt( Vector3.zero );
	}
}

Create an empty GameObject, attach that script, and run it. You should get a camera correctly auto-positioned looking down on the plane.

Screen Shot 2016-11-11 at 17.18.56

Class: PostSceneCreateCubes

This class runs once the game has started, and generates a random number of cubes that are dropped somewhere on the plane. It conveniently re-parents them into a GameObject so they don’t clutter the scene-hierarchy window. The positions are automatically set using the static variable that tells us how big the plane was to start with.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class PostSceneCreateCubes : MonoBehaviour
{
	public int targetNumCubes = 1000;

	private List<GameObject> _internalCubes = new List<GameObject>();
	private GameObject _cubeHolder;

	void Start()
	{
		if( _cubeHolder == null )
			_cubeHolder = new GameObject( "Auto-created cubes" );

		for( int i = 0; i < targetNumCubes; i++ )
		{
			GameObject cubeN = GameObject.CreatePrimitive( PrimitiveType.Cube );
			cubeN.name = "Cube-" + i;
			cubeN.transform.position = new Vector3( Random.Range( -CreateScene.planeWidth / 2f, CreateScene.planeWidth / 2f ), 0.1f, Random.Range( -CreateScene.planeWidth / 2f, CreateScene.planeWidth / 2f ) );
	
			_internalCubes.Add( cubeN );
			cubeN.transform.SetParent( _cubeHolder.transform, true );
		}
	}	
}

Make a new GameObject for this, attach it, and run – you should get a random scattering of cubes. Great! Exciting! Easy (that’s the point ;)).

Screen Shot 2016-11-11 at 17.21.18

Class: UnityCubeMover

And the core: something that will move the cubes.

In a Unity game, traditionally this code would be placed in a “Cube” component attached to the cubes themselves. This isn’t a good way to write games/apps, and is a primary reason for adding an ECS to Unity. Even in Unity we often ignore it and place the code into a single shared class, like we do here. So we’re cheating a little: we know that eventually we want the code in a single class (that will be ported to become an ECS Processor).

First we need a way of knowing how fast we want each cube to move, and in which direction. I could try pre-rotating each cube to a random direction, and moving it “forwards” … but I chose to store an X,Y pair for the direction + speed instead.

using UnityEngine;
using System.Collections;

public class UnityCubeVelocity : MonoBehaviour
{
	public Vector3 velocity;
}

…if that class looks suspiciously like it’ll become a Component during the porting later on, then good.

Now we can make the main class which once per frame looks at all the cubes, and moves each one by random amounts.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class UnityCubeMover : MonoBehaviour
{
	public float maxXYSpeedPerSecond = 10f;

	protected List<GameObject> _internalCubes;

	public void Update()
	{
		if( _internalCubes == null )
			return;
		
			int i = -1;
			foreach( GameObject cube in _internalCubes )
			{
				i++;
				UnityCubeVelocity v = cube.GetComponent<UnityCubeVelocity>();
				if( v == null )
				{
					v = cube.AddComponent<UnityCubeVelocit>();
					v.velocity = new Vector3( Random.Range( -maxXYSpeedPerSecond, maxXYSpeedPerSecond ), 0f, Random.Range( -maxXYSpeedPerSecond, maxXYSpeedPerSecond ) );
				}
	
				Vector3 _translationThisFrame = v.velocity * Time.deltaTime;
				
				cube.transform.position += _translationThisFrame;		
			}
		}
	}	
}

This class needs to find the cubes we created, and since they’re created procedurally, we can’t use Unity’s normal mechanism for sharing this data (don’t use Unity’s Find; never use Unity’s Find unless you are absolutely desperate)

So, we’ll add a method to assign the cubes, and move the “AddComponent” call into it:

public class UnityCubeMover : MonoBehaviour
{
...
	public void SetInternalCubes(List<GameObject> cs)
	{
		_internalCubes = cs;

		foreach( GameObject cube in _internalCubes )
		{
			cube.AddComponent<UnityCubeVelocity>();
		}
	}
...
}

…and we’ll call that method from our PostSceneCreateCubes class:

public class PostSceneCreateCubes : MonoBehaviour
{
...
	public UnityCubeMover cubeMover;
...
	void Start()
	{

... original contents of this method go here ...

		if( cubeMover == null )
		{
			GameObject go_cubemover = new GameObject( "AUTO-CREATED CUBE MOVER" );
			cubeMover = go_cubemover.AddComponent<UnityCubeMover>();
		}
		cubeMover.SetInternalCubes( _internalCubes );
		_internalCubes = null;
	}
}

Add a new GameObject for the mover, and add UnityCubeMover. Run this, and … your cubes will jiggle like tiny ants.

Sadly, they’re not moving around smoothly – because we keep changing them. Every. Single. Frame. Forever. Without. Giving. Any. Time. To. Breathe.

Improving the scene

Smoother movement

It’s too quick for us to know if things are working. For a quick hack, let’s only change the direction/velocity once every N frames

I’m not happy with this hack: I’m sure there’s cleaner/clearer code ways of achieving this. I was looking for something engine-agnostic, it was quick to hack together, worked first time, hasn’t caused any problems yet. But it’s ugly/hard to read.

public class UnityCubeMover : MonoBehaviour
{
...
	protected static int _frameSkip = 60;
	protected int _framesSkippedSoFar = _frameSkip;
	
...
	public void Update()
	{
		if( _framesSkippedSoFar >= _frameSkip )
		{
			_framesSkippedSoFar = 0;

			foreach( GameObject cube in _internalCubes )
			{
				UnityCubeVelocity v = cube.GetComponent<UnityCubeVelocity>();
	
				v.velocity = new Vector3( Random.Range( -maxXYSpeedPerSecond, maxXYSpeedPerSecond ), 0f, Random.Range( -maxXYSpeedPerSecond, maxXYSpeedPerSecond ) );
			}
		}
		else
		{
			_framesSkippedSoFar++;
		
			... original code from the Update method goes here ...
		}
	}
}

Run again, and you should get smooth movement, with them all changing direction suddenly every 60 frames (every 2 seconds, if you’ve set Unity to a 30 FPS cap).

Colouring-in the cubes

White cubes on a white background are annoyingly hard to see. We’ll make a Unity Component that handles all the visual and animation on each individual cube, and attach it per-cube.

class: WanderingCube

using UnityEngine;
using System.Collections;

public class WanderingCube : MonoBehaviour
{
	public Vector3 maxAbsOfPositions;

	public static Color[] availableColors = new Color[] { Color.blue, Color.grey, Color.blue, Color.cyan, Color.yellow };
	public static Material[] availableMaterials;

	public void Awake()
	{
		if( availableMaterials == null )
		{
			availableMaterials = new Material[ availableColors.Length ];
			for( int i = 0; i < availableColors.Length; i++ )
			{
				availableMaterials[ i ] = new Material( Shader.Find( "Standard" ) );
				availableMaterials[ i ].color = availableColors[ i ];
			}
		}
		GetComponent<MeshRenderer>().sharedMaterial = availableMaterials[ Random.Range( 0, availableMaterials.Length - 1 ) ];
	}
}

…and attach it when we create our initial cubes:

public class PostSceneCreateCubes : MonoBehaviour
{
...
	public UnityCubeMover cubeMover;
...
	void Start()
	{
...
		for( int i = 0; i < targetNumCubes; i++ )
		{
			GameObject cubeN = GameObject.CreatePrimitive( PrimitiveType.Cube );
			cubeN.name = "Cube-" + i;
			cubeN.transform.position = new Vector3( Random.Range( -CreateScene.planeWidth / 2f, CreateScene.planeWidth / 2f ), 0.1f, Random.Range( -CreateScene.planeWidth / 2f, CreateScene.planeWidth / 2f ) );
			WanderingCube wcube = cubeN.AddComponent<WanderingCube>();
			wcube.maxAbsOfPositions = CreateScene.planeWidth / 2f * Vector3.one;
		}
...
	}
}

Run this, and you get multiple colours. Lovely.

Screen Shot 2016-11-11 at 17.22.29

Stopping them leaving the play-area

With these random procedural simulations we’ll often want to leave the code running for a while, looking out for problems. At the moment, the cubes eventually wander off the playing area. The simplest old-school solution is to teleport them back onto the other side whenever they fly off.

I’m putting this into Unity’s LateUpdate() so that it happens AFTER all of our other game-logic, and we don’t have to worry about it interfering with collision detection (much).

using UnityEngine;
using System.Collections;

public class WanderingCube : MonoBehaviour
{
...
	public void LateUpdate()
	{
		Vector3 pos = transform.position;
		
		if( pos.x > CreateScene.planeWidth / 2f )
			pos.x -= 2f * CreateScene.planeWidth / 2f;
		else if( pos.x < -1f * CreateScene.planeWidth / 2f )
			pos.x += 2f * CreateScene.planeWidth / 2f;
	
		if( pos.z > CreateScene.planeWidth / 2f )
			pos.z -= 2f * CreateScene.planeWidth / 2f;
		else if( pos.z < -1f * CreateScene.planeWidth / 2f )
			pos.z += 2f * CreateScene.planeWidth / 2f;

		transform.position = pos;
	}
}

Collision Detection 1: using Unity’s in-game CD for debugging

We’re going to use two parallel forms of collision detection. The first one is for visualisation and is purely observational: all collisions are allowed, interpenetration happens all the time, no effect on gameply. This will use Unity’s built in “Physics Trigger” concept.

The second form is for gameplay, and we’ll put more effort into it. It will be a full collision detection-and-prevention system that actually blocks things from moving, makes them bounce off each other, etc.

Visual debugging: cubes that detect collisions

We could set a single colour to every cube – or randomize the colours – but we’re going to go one better. Each cube will have a colour that indicates what’s happening to that cube.

Visual debugging is infinitely faster and more efficient than console-debugging or using the debugger (if you like this idea, go read @redblobgames’ articles on game programming; Amit likes to use visual interactive diagrams in his articles. Very time-consuming to make, but wonderful to play with).

To do this, we:

  1. Make all cubes blue to start with
  2. Create a “collided” material, and colour it red
  3. Add the necessary physics things in Unity to detect collisions
  4. When a cube collides, we change it material to the collided one
using UnityEngine;
using System.Collections;

public class WanderingCube : MonoBehaviour
{
...
	public static Color[] availableColors = new Color[] { Color.blue };
	public static Material[] availableMaterials;
	public static Material errorMaterial;
...
	public void Awake()
	{

... original contents of this method goes here ...

		BoxCollider col = gameObject.GetComponent<BoxCollider>(); // needed to receive OnTrigger callbacks
		if( col == null )
			col = gameObject.AddComponent<BoxCollider>();
		col.isTrigger = true;

		Rigidbody rb = gameObject.AddComponent<Rigidbody>(); // needed to receive OnTrigger callbacks
		rb.useGravity = false;
	}
...
/** This is a piece of GUI/UX: we use this to make cubes intelligently warn us whenever they
    inter-penetrate; our code should prevent this from happening .... "should" ... muahahahahaha!
    
    (if you've ever had the pain of race conditions in multi-threaded code, you may see where I'm
    going with this...)
    */
	public void OnTriggerEnter(Collider other)
	{
			GetComponent<MeshRenderer>().sharedMaterial = errorMaterial;
	}

}

This will work, but … the cubes go red and never go back to blue.

And there’s another problem – depending upon your version of Unity, the cubes MIGHT detect the plane itself as “colliding” – NB: due to Unity’s generally weird physics, it’s not guaranteed whether this will or won’t happen on your install.

So we do two changes:

  1. Use a co-routine to automatically animate a change: switch back to the original material after a few seconds
  2. Place a Unity “tag” on each cube and tell the physics to ignore collisions unless they are “tagged” as cubes

Pre-tag objects

First, because Unity’s editor is old-fashioned about this, manually pre-create the tag in your editor:

Menu: Edit – Project Settings – Tags and Layers – … and select “Tags” at the top, then hit the plus button to create a new one

Call your tag WanderingCube, and then add code to the WanderingCube class so that new cubes automatically tag themselves:

public class WanderingCube : MonoBehaviour
{
...
	public void Awake()
	{
		tag = "WanderingCube";
		...
	}
...
}

Flash the collision indicator – but only for cube/cube collisions

using UnityEngine;
using System.Collections;

public class WanderingCube : MonoBehaviour
{
...
	private Material _originalMaterial;
	private Coroutine _coro_ResetMaterial;
...
	public void OnTriggerEnter(Collider other)
	{
		if( other.gameObject.tag == tag )
		{
			if( _coro_ResetMaterial != null )
			{
				StopCoroutine( _coro_ResetMaterial );
				GetComponent<MeshRenderer>().sharedMaterial = _originalMaterial;
			}

			_originalMaterial = GetComponent<MeshRenderer>().sharedMaterial;

			GetComponent<MeshRenderer>().sharedMaterial = errorMaterial;

			_coro_ResetMaterial = StartCoroutine( "ResetMaterialToOriginal" );
		}
	}

    /** Using a co-routine allows us to display it for more than a single frame, ie human-friendly
    but fire-and-forget in the original method that triggers it
    */
	public IEnumerator ResetMaterialToOriginal()
	{
		yield return new WaitForSeconds( 0.4f );
		GetComponent<MeshRenderer>().sharedMaterial = _originalMaterial;
	}
}

Run that.

Now you should have cubes merrily running around, flashing red when they collide, but otherwise happily passing through each other. This is ideal – it sets the stage for us to add our own collision-detection in the next stage.

Screen Shot 2016-11-11 at 17.23.38

Collision Detection 2: using Unity’s in-game CD for Gameplay

We’ll use Unity at first, to test the code, then later switch to our own implementation (which can execute entirely inside the ECS). However, there’s another reason not to rely upon Unity’s CD…

Unity3D has no collision detection system. Instead, it re-uses the 3rd-party physics engine built-in to Unity, and uses an approximation of CD from that.

If you move a transform.position in Unity, there is no direct way to find out if it will collide, where it will collide, or what it collides with.

Most of the time, no-one cares about the difference between “collision detection” and “approximate collision detection by asking the physics engine”. You use the physics methods outside the physics loop (which you should never do – it’s inaccurate) and Unity doesn’t complain. Occasionally it’ll give you noticeably wrong results.

In particular:

  • RayCast
  • BoxCast
  • RayCastAll
  • …etc

…all run instantly, using approximated data from the most-recent physics tick – which is usually (always?) out of synch with rendering. I’ve got some interesting physics-heavy projects that demo this and some of the odd side-effects. IMHO the engine should throw an exception when any of these are used outside the physics loop – you need to be aware that the data is wrong.§

Making Collision Detection easy: the rise of the AABB

Writing CD is well-documented in computer games for more than 30 years. However, doing it correctly is a bit of a pain, and lots of code (that I can’t be bothered to write). We’re going to use a cheap hack to the scene/game design that allows us to write a much simpler (but 100% correct) CD later on.

Google it for more info, but the absolute minimum is that you have to “sweep” your objects through space, and compare the overlapping swept shapes. Rather than asking “do the squares overlap?” you have to ask “do the swept squares overlap?”.

No collision detected MISSING collision!
2dsweep-0 2dsweep-1

…using swept shapes instead, you detect the collisions because your new shapes overlap:

2dsweep-2

We can massively simplify this: if we only use cubes (oooh! What a coincidence!) and we only allow AA (axis-aligned) movement, we can trivially calculate the swept-cube as a rectangular, stretched cube. Or, in 2D, we move from comparing squares to comparing rectangles – and all programming languages have built-in methods for comparing if pairs of rectangles overlap (i.e. collide).

2dsweep-3

This requires a tweak:

public class UnityCubeMover : MonoBehaviour
{
...
	public void Update()
	{
...
			foreach( GameObject cube in _internalCubes )
			{
				UnityCubeVelocity v = cube.GetComponent<UnityCubeVelocity>();

				if( Random.Range(0,2) < 1 )
				{
					v.velocity = new Vector3( Random.Range( -maxXYSpeedPerSecond, maxXYSpeedPerSecond ), 0f, 0f );
				}
				else
				{
					v.velocity = new Vector3( 0f, 0f, Random.Range( -maxXYSpeedPerSecond, maxXYSpeedPerSecond ) );
				}
			}
...
	}
...
}

…now the cubes should only move up-down or left-right.

Preventing collisions

We need to do three things: detect collisions, prevent them, and … show that we’ve prevented them.

To detect collisions, we’ll create a “will moving this cube cause a collision?” method, and if the answer is “yes”, we’ll simply block it.

public class UnityCubeMover : MonoBehaviour
{
...
	public bool blockCollisions = true;
...
	public void Update()
	{
...
				Vector3 _translationThisFrame = v.velocity * Time.deltaTime;
				
				GameObject collidee;
				bool _willCollide = wouldMovingCubeCollide( cube, _translationThisFrame, out collidee );
				
				if( _willCollide && blockCollisions )
				{
					//Debug.Log( "Cube " + cube + " (bounds.extends = " + cube.GetComponent<BoxCollider>().bounds.extents + ") WOULD HAVE hit (but I prevented it) " + collidee + " alng translation = " + _translationThisFrame );
					Debug.DrawRay( cube.transform.position + Vector3.up, _translationThisFrame );
				}
				else
					cube.transform.position += _translationThisFrame;
...
	}
}

…to fulfil that, we use the simplest possible collide-check: we ask Unity physics to do all the hard work (although we know this will be slightly inaccurate):

public class UnityCubeMover : MonoBehaviour
{
...
	/**
	Uses Unity physics to do arbitrary collision.	
	In testing, it ends up being wrong about 1% of the time, due to the frame rate diff of physic vs rendering.
	*/
	protected bool wouldMovingCubeCollide( GameObject movingCube, Vector3 translation, out GameObject objectCollidedWith )
	{
		UnityCubeVelocity v = movingCube.GetComponent<UnityCubeVelocity>();
	
		RaycastHit hit;
		if( blockCollisions && Physics.BoxCast( movingCube.transform.position, /* Unity's docs for this method are bad */ movingCube.GetComponent<BoxCollider>().bounds.extents,  translation, out hit, Quaternion.identity, /** check 10% ahead because Unity floats are rather inaccurate; feel free to use 1.0 instead */ 1.1f * translation.magnitude ) )
		{
			objectCollidedWith = hit.collider.gameObject;
			return true;
		}
				
		objectCollidedWith = null;
		return false;
	}
}

You can test it by clicking the “blockCollisions” method on and off while it’s running – but that’s not really clear enough for me.

If you run this code, the cubes will move around, and gradually come to a halt as they avoid collisions. Then, when the directions re-randomize, they’ll (mostly) all start moving again. Since we’re preventing potential collisions by stopping dead, even cubes that look like they might not collide get stopped – instead of going “as far as I could and stopping at the last moment”. Use the Rays that I’m drawing in the Scene view to confirm this in cases where it’s unclear why individual (pairs of) cubes have stopped.

Screen Shot 2016-11-05 at 20.43.14

Displaying prevented-collisions

Let’s make this easier to see. We’ll allow cubes to go an extra colour: yellow, for when they are frozen to avoid a collision.

public class UnityCubeMover : MonoBehaviour
{
...
	public void Update()
	{
...
		if( _framesSkippedSoFar >= _frameSkip )
		{
...
		}
		else
		{
			_framesSkippedSoFar++;
...

...original method contents here...

			foreach( GameObject cube in _internalCubes )
			{
				if( _willCollide && blockCollisions )
				{
					cube.GetComponent<WanderingCube>().OnCollisionWasPrevented();
				}
			}
		}
	}
...
}

…and upgrade the WanderingCube to support that:

using UnityEngine;
using System.Collections;

public class WanderingCube : MonoBehaviour
{
...
	public static Material errorMaterial, almostCollidedMaterial;
...
	public void Awake()
	{
...
		if( availableMaterials == null )
		{
			errorMaterial = new Material( Shader.Find( "Standard" ) );
			errorMaterial.color = Color.red;

			almostCollidedMaterial = new Material( Shader.Find( "Standard" ) );
			almostCollidedMaterial.color = new Color( 0.5f, 0.5f, 0 );
			...
		}
	}
...
/** This is a piece of GUI/UX: we use this to make cubes intelligently tell us when
they've been FORCED to stop moving by the collision-detection system
*/
	public void OnCollisionWasPrevented()
	{
		if( _coro_ResetMaterial != null )
		{
			StopCoroutine( _coro_ResetMaterial );
			GetComponent<MeshRenderer>().sharedMaterial = _originalMaterial;
		}

		_originalMaterial = GetComponent<MeshRenderer>().sharedMaterial;

		GetComponent<MeshRenderer>().sharedMaterial = almostCollidedMaterial;

		_coro_ResetMaterial = StartCoroutine( "ResetMaterialToOriginal" );
	}
}

Now you should find that cubes are blue when moving, flash red briefly when they collided, and stop and turn yellow when they MIGHT collide:

Screen Shot 2016-11-11 at 17.40.28

Wait – why are we seeing red? We should never see red!

Correct. There are three things that allow collisions to happen despite our precautions.

At the end of each frame we’re teleporting cubes who’ve gone off the edge of the playing field back on to the other side. Since we ignore this in the CD code, we expect to see a few random red flashes around the edges of the playing area. We could fix that, but … it’s useful. It’s a known error, and it proves that our “VISUALLY detect collision, even if the CD code has failed” code is actually running and working correctly. If we ever get a version of the demo where nothig is ever going red, we know we accidentally broke something.

Secondly, there’s the problem of Unity physics approximating the CD. Each case where you get a flash of red is where there was a near-miss that wasn’t going to happen during the last physics step (which is where Unity’s CD approximation gets its data from), but did happen during the next physics step (which happens out of sync with our game-logic).

Finally … there’s a bug. I said at the start:

“I’m putting this into Unity’s LateUpdate() so that it happens AFTER all of our other game-logic, and we don’t have to worry about it interfering with collision detection (much).”

…that LateUpdate that’s doing the teleport is also overriding the on-screen position of cubes, but NOT changing the ECS’s version of the data. Over time, this gets more and more corrupt. We’ll delete that code from WanderingCube.LateUpdate(), and re-create it inside the (new, ECS version of) CubeMover.

When we port this identical code to an ECS, and stop using Unity physics, you expect to see all the red flashes in the middle of playing area go away…

Converting this demo into an ECS demo

With all the setup out of the way, onto the ECS stuff. There’s some obvious parts to this, and some non-obvious ones. We’re NOT going to throw everything away – we’ll be keeping some of the legacy code (things that are specific to the game-engine, and work well living outside the ECS). In particular: the animation of cube collisions (blue, red for collided, yellow for blocked) is useful to keep outside the ECS – it lets us debug our ECS without worrying that the debugging code is broken.

Next…

Patreon backers can access part 2 and later articles immediately – link here: requires password.

In part 1, we created a test scene for doing collision detection and rendering in Unity, in a way that we can then port to an ECS. In part 2, we’ll do the actual conversion, and create a simple ECS that exists (and runs) independently inside Unity, but is managed by Unity classes.

Which languages need Entity Systems libraries right now?

A few months ago I ran a survey to find out which programming-languages people were using with Entity Systems:

https://docs.google.com/forms/d/18JF6uCHI0nZ1-Yel76uZzL1UfFMI21QvDlcnXSGXSHo/viewform

I’m about to publish a Patreon article on Entity Systems (here if you want to support me), but I wanted to put something up on my blog at the same time, so here’s a quick look at the stats.
Continue reading

Survey: which language(s) do you use along with an #entitysystem in #gamedev?

A lot of us have been looking at alternative engines recently, and for me the biggest challenge is that the intersection between “game engine I can use easily” and “programming language I am willing to use” is quite small.

That got me thinking: if you started a new commercial ES today, what language does your audience want?

Short Google form

FYI: I picked the top 10 global languages by popularity, and then cherrypicked from the next 50 or so on http://sogrady-media.redmonk.com/sogrady/files/2015/07/lang-rank-615-wm.png – favouring ones where I have met people that I know are using them in gamedev today.

Support me on Patreon for early access to new Entity Systems articles

I love researching and writing about Entity Systems, but it takes me days or weeks to make a single article. I’ve written almost nothing for the past 18 months because on my current salary I can’t afford the time off work.

So … now I’m crowdfunding the long, detailed, in-depth ES articles. This gives me a way to spend the time I need to write each one while still paying rent, food, etc.

You don’t have to sign-up – I know there’s lots of people like myself who are in bad financial situations, and I hope all the articles will be made free eventually. But if you’ve found my ES articles useful, and you want more of them, and you can spare $5 once every couple of months, please do.

You can sign up here: https://www.patreon.com/tmachine

Simple #unity3d bugs and flaws fixed by Entity Systems – number 1

I periodically write massive long documents detailing all the bugs in Unity that I know, have memorized, and have to workaround on a day-to-day / hour-to-hour basis. But it makes me so angry and frustrated – so much terrible coding, so little technology-leadership at the company – that I end up deleting it. Life is too short to be daily reminded how crappy (and yet easy to fix) our tools are.

Then, every 6 months or so, when people ask me for simple examples of how ECS’s fix Unity, I have to wrack my brains for something simple.

So I’m going to start blogging simple examples as I run into them, with only enough context for me to understand them. Here’s the first…
Continue reading

Entity ID’s: how big, using UUIDs or not, why, etc?

This has come up a few times, and I ended up replying on Twitter:

But that’s a crappy way to find things later, so I made a quick-and-dirty infographic with a few key points:

Docs-entityID

I’m working on my own Entity System; want to follow it?

Support me on Patreon, writing about Entity Systems and sharing tech demos and code examples

2015 talk: Progress on An Entity System for #Unity3d

Slides from my talk last night at Unity Brighton.

Three parts:

  1. First: introduction / overview of Entity Systems, and why you care (as a “person who makes games”)
  2. Second: Progress so far: screenshots of the Unity Editor with explanation of the new features I’ve added
  3. Third: Challenges and solutions I’ve encountered so far

Aliqua-progress-2015-BUUG-v3

WordPress, HTML, the web etc – don’t support “presentations” yet. No, I’m not creating a fake Slideshare account just so you can wait ages for a non-bookmarkable slide viewer to (slowly) load. Until then … we have PDF. Enjoy!

Data Structures for Entity Systems: Multi-threading and Networking

(One of a series of posts about converting Unity3D into a 1st-class Entity Component System. Read others here)

It’s a year and a half since I wrote about choosing Data Structures for high-performance Entity Systems in A-AAA games. I always had a followup post in mind, but never wrote it down (thanks largely to the demise of #AltDevBlog). These days I’m too busy to write such big articles, but it’s long overdue … This post is a shorter version of what I had planned, but should have enough to get you going in the right directions.

Continue reading

Replacing Unity3d’s core architecture: Structs

(One of a series of posts about converting Unity3D into a 1st-class Entity Component System. Read others here)

How to store game data: GameObject? MonoBehaviour? ScriptableObject?

Those three pillars of Unity’s architecture are the curse of game implementation and performance. Architecturally, they’re great: they’re a big part of what makes Unity easy for newcomers to pick up and understand within hours, instead of taking weeks.

On large Unity game projects, they’re hated for being slow and hard to work with when you get to hundreds of thousands (or millions, tens of millions, …) in a single scene. Unity provides zero tools and support for this situation – it just gets harder and harder to work with, and slower and slower to run.

In Entity Systems world, we hate them because they are inherently slow and buggy – no matter how great Unity’s coders, they’ll never make them work as well as our preferred approach (See below).

But … replacing them forces you to replace most of the Unity Editor!

Most of the features of our Entity System need new Editor GUI anyway. If we’re going to be adding big chunks to the editor, replacing GO/MB/SO is going to be much cheaper than normal. And it potentially has huge benefits that are independent of the Entity System.

If we’re going to replace them, what will we replace them with? Custom versions that have almost the same name and work the same way? Or something very different?

What is Unity’s ‘GameObject’ anyway?

As far as I can tell, the real meaning of GameObject is:

def. GameObject: Something that exists inside a Scene, and has a Position, Rotation, and Scale. It can be “embedded” inside any other GameObject, meaning that any change to the other object’s Position, Rotation, or Scale gets merged onto this one. It’s the ONLY thing that can have Unity “Components” (MonoBehaviours) attached to it. Anything that is not a GameObject, and is not attached to a GO, gets deleted every time you load/reload/play/resume a Scene.

From a code perspective, looking at the backend systems, there’s a lot more to it. The GameObject (GO) has a slightly weird name, when you think about it. You use it so much during Unity dev that you stop noticing it. “Game … Object” … wha?

Other purposes GameObject serves

Here’s a few obvious ones (I’ll edit later if I think of more):

  1. Guarantees everything has the GetInstanceID() method
    1. Needed for Unity’s Serialization system to work (because of how it’s been designed, not because serializing requires this – C# has built-ins that would have done the same job)
    2. Enables the Editor to “select” anything in any tab/window, and that thing is ALSO selected in all other tabs/windows (e.g. click in Scene, and the Inspector updates to show the components on that thing)
    3. …probably loads of other things. It’s so commonly used I hardly notice it
  2. When doing in-Editor things, Unity can often “ignore” classes that are “not part of the game, because they don’t extend GameObject”
    1. Reading between the lines of official docs, and simplifying vastly, this is what happens behind the scenes. Especially with Serialization, I suspect.
    2. This can be a huge pain. It’s hard to debug code when “GameObject subclasses” magically behave differently to “all other classes” with no indication of why
  3. Since every GO has a Transform … you can do automatic, general-purpose, high-quality, Occlusion Culling
    1. NB: for this to work perfectly, you’d also want every GameObject to have a .bounds variable. Why did Unity’s original architects leave that out? Dunno, sorry.

How to store game-data: the Entity Systems ideal way

We know this, it’s been discussed to death: if your programming language supports it, use structs.

By definition, structs are the most memory-efficient, CPU-efficient, multi-thread-safe, typesafe way of storing data, bar none. There is no better way to do this in mainstream languages. C# and C++ both support structs; I think we have a winner!

There are probably some awesomely clever advanced Math ways of doing things better, or by using raw assembler and code optimized for each individual CPU on the market. Or, or … but: in terms of what’s ‘normal’, and commonly used, this is the best you’re going to get

But how will this work in practice? What about all the “other” roles of GO etc in Unity?

Structs in … Identity (GetInstanceID)

Simple ECS implementations often hand-around raw pointers to their Components; that gets messy with Identity.

But most (all?) advanced implementations have some kind of indirection – a smart pointer, or an integer “index” that the Component Storage / Manager maps internally to the actual point in memory where that lives.

If we turn that “advanced” feature into a requirement, we should be fine.

Structs in … Serialization

  1. Start writing your own version of the Unity Serialization system that only uses structs
  2. Finish it the same day
  3. Discover it runs 10 times faster than Unity’s built-in one
  4. …with fewer bugs
  5. PROFIT!

Structs are the easiest thing you could possibly try to serialize and deserialize. Unity coders probably wish that they could restrict us all to structs – it would make their live much easier in some ways.

User-written structs: special rules?

Do we need to add special “rules” to user-written structs that appear in the game?

Nope! It turns out that C#’s built-in Reflection system is able to inspect every struct, shows us every field/property/etc, and lets us easily read and write to them. Both private and public.

CAVEAT: structs break C# .SetValue()

Yeah, this sucks – and it’s nothing to do with Unity, it’s core C#.

A little care is needed when we implement the Entity System internals. But it has no effect on user code / game code.

Structs in … SceneView (Transforms)

No! Just … NO!

This is one of the architectural mistakes of Unity we’re going to fix in passing: we won’t require everything to have a Transform.

However, it foreshadows a more subtle problem that we’ll eventually have to deal with:

Entity Systems are a table-based/Relational/RDBMS way to store and access data; such systems are very inefficient at storing and retrieving tree-structured data (e.g. OOP classes + objects)

The transform hierarchy in a Unity scene is a massive tree. As it turns out, it’s bigger than it needs to be (because of that law of Unity that everything must have a Transform) – but we uses trees all the damn time in game-development. So it’s a problem we’ll have to come back to.

Bigger storage: where do the structs live?

Fine; at the lowest level, the individual ECS Components, we’ll use structs.

But how do we store those?

Choosing the right aggregate data-structures for your ECS is a major topic in itself. C# gives us (almost) total control of how we’d like to do it – plenty of rope to hang ourselves with.

At this point: I’m not sure.

As a temporary solution, I’m going to focus on making the storage-system swappable, so that I can implement a crappy version quickly, and then easily swap-it-out with something much better – without having to rewrite anything else.

Does it work?

Yes. I tried it – I wrote a complete replacement for the Unity Inspector tab that only works on Entities-with-Components, where “Component” is any struct. Ugly, but it works:

Screen Shot 2015-04-29 at 14.41.23

Everything there is auto-generated (including the colour; every struct gets a globally unique background colour, which I find makes it much easier when you have hundreds or thousands of Component types).

The only tricky bit was the problem with C# FieldInfo.SetValue(…), as mentioned above.

Further Reading

…some things I might want to pick up on in future posts:

Kickstarting Entity Systems in Unity3d – What to include?

A first-class Entity System for Unity3D

Unity is a great 3D engine and a good editor – but the programming environment is 10-15 years behind the curve. Entity Systems are a much better way of writing games, but they are surprisingly difficult to add to Unity.

I’ll bring the latest in modern ES techniques to Unity, turning parts of it from a “weak” programming environment into “one of the best”. In game-engine terms, this will put it far ahead of the pack.

This blog post is testing the waters:

  1. You can give me direct feedback on the proposed contents/scope
  2. I can start to see how much interest there is in making this

First round of feedback

A lot of people read this and got the impression I was going to charge them extra for the final product, and provide a library with no tutorials. Big confusion and misunderstanding! So, I’ve reworded those bits to be clearer.

Kickstarter: planning the campaign

Target Audiences (Expected)

I think I have four target audiences:

  1. Newbie devs, and non-programmers (artists, designers), who find the “coding” parts of Unity overwhelmingly difficult today
  2. Unity devs who’ve never used an Entity System on a real game project, and don’t know what they’re missing. They may have a lot of experience (shipped multiple games), or none (University/College students).
  3. Small Indie teams / sole coders who’ve used Entity Systems elsewhere, and feel that coding in Unity is slow, error-prone, boring, frustrating, and time-wasting by comparison
  4. Large Indie teams whose games won’t work in Unity because Unity is so bad at scaling to large projects. They’ve already re-written or replaced substantial chunks of Unity’s core so that it’ll work fast enough / reliably enough.

Types of Reward

Reward type 1: Discounted License

Everyone who backs the KS gets a copy of the library / license to use it. By backing the KS (at any level) you’re getting a substantially cheaper purchase compared to the final launch pricing on the Asset Store.

There might be some options here for different team sizes, different levels of support, etc.

Reward type 2: Expert Knowledge

When you have non-trivial questions about ES design and usage, it’s hard to get the attention of experts. They’re usually experienced, older, programmers with young families, or working in senior jobs. They have little free time.

Big developers fix this by hiring experts for a few days at a time. But small teams/individuals can’t afford the “entry” cost – as a Consultant, you need to charge at least $5,000 per engagement to cover all the admin overhead and hidden costs.

So, we have some options here to give everyone this kind of access.

Reward type 3: Source Code

In mainstream IT, when you purchase a library you rarely (if ever) get the source code. If you find bugs, or missing features, the vendor works hard and fast to fix them for you.

In the games industry, it’s the other way around: vendors take no responsibility for the code they’ve sold you, and in return … they give you full source access. “Fix it yourself, dude!”

If I let everyone have source, it raises my support costs. With each change, it won’t work for some people – because they’ve modified their copy – and I’ll have to help them update it.

On the flip side: Source code is your “Plan B” in case I get sick, or sell-out, or lose interest in the project, etc. It also gives you an easy way to add features of your own and send them back to me (which I then take on responsibility for maintaining).

I’m offering this, but it’ll be a high-cost. The teams that really need it should have no problem justifying the cost.

Types of Stretch Goal

To clear up confusion: these are things that would be present in the core product (e.g. the GUI is going to be a major part of the library!), but stretch goals would allow me to add extras to each of them.

Goal type 1: Editor GUI

In my experience the biggest effect on programming speed – once you get past your innate ability + level of experience – is the quality and “friction” of your tools.

As soon as you go beyond the simple stuff it’s damn hard to extend the Unity editor. But I’ve been hacking the Editor for a few years now, and I’m willing to do pretty much anything. Especially if it makes it easier to make games with!

Goal type 2: Example Games

The core will have some form of tutorials, but it probably won’t have a complete demo game.

Writing a game just to demonstrate an API is extremely time-consuming, and it’s not what you’re paying for when you buy the library.

But … it’s also a great idea: it improves the quality of the API, by giving me a reference product to check everything is as easy-to-use as intended. So I’d like to write one (or several), but I can’t do that on the base funding.

(Aside: If I ran the technology division at Unity corp, they’d be writing and publishing games every quarter)

Goal type 3: Tutorials

There will be tutorials with the core library. They’ll cover the basics of how to use it.

But … I’d like to go further, and do tutorials for every aspect. I’d like to do a written tutorial for everything, and I’d like to ALSO do a video tutorial for everything (some people only use written tutorials, other people only use videos. I’d like to make it great for both groups).

With a new library, tutorials are extremely expensive to write. Minor changes to the API – bug fixes, refactorings, feature additions – invalidate whole pages of tutorial at one stroke.

Pricing and Funding levels

Tier costs

These are approximate based on extrapolations of cost and expected “version 1.0” feature-set.

  • License: $50-$150 (after launch, general public can buy at $200-$400 in Asset Store)
  • Source code: $300-$1000 (various amounts of support)
  • Access to experts: $150-$750 (various levels of privacy + interaction)

UPDATE: One person has stated they would “never pay these prices”. That’s fine – they’re way outside my target audience. I’m more likely to increase these prices than decrease them. If you know what an ECS is, and understand the value, this is probably too cheap already.

Funding targets

This is what it’s going to cost to build:

  1. Minimal version that’s usable in most game-dev: approx. $15,000
  2. My preferred v1.0: approx. $75,000
  3. High-quality version for large games: approx. $200,000

I can write-off about 50% of the cost as this is a project that I need and will use myself – and it’s a labour of love. I can also add a %age in expected additional sales that happen naturally after the campaign has ended (from the Asset Store, etc).

But Kickstarter takes a cut, and the government takes a cut, and Amazon takes a cut. In the end, I need a KS campaign to raise something like:

  1. Minimal funding: $5,000
  2. Preferred funding: $30,000
  3. High-quality funding: $75,000

My situation

Who are you, anyway?

In case you don’t know … I’ve run Technology/Development for a couple of game companies (e.g. Mindcandy, NCsoft Europe). My StackOverflow score is somewhere north of 20,000. I’ve contributed to a few open-source projects, but the one I’m most active on is the SVG rendering library for iOS and Mac, where I’m the project lead and one of the top 3 contributors.

I started writing about Entity Systems back in 2007, mostly because I was frustrated that so many game studios were “doing it wrong”.

What I’m doing now

I teach non-technical people how to program. I work with schools, teachers, and directly with children/adults. I invented a new system of programming using physical objects and toys.

Working with a local school, I’m making a new course where I’ll be teaching children “how to make games with Unity3D”. I’m particularly interested in what I can do to the Unity Editor to make it more user-friendly and better for use in the classroom.

Depending on how this goes, I have a few people in mind I’ll hire to share the burden of writing this library. It’s something I need both in my day-job and in all my personal game projects. Doing it as a Kickstarter gives me the excuse to spend 100x as much time and effort on it as I would otherwise, and gives me a much better library than I’d get on my own.

Why Kickstarter?

I suck at Marketing. The biggest risk factor to this project is that I fail to make enough noise, and hence there’s too little money coming in to pay for the ongoing development and support. As a result, dev gets sidelined while I pay the bills.

A Kickstarter is my way of testing “can I find a critical mass of people who need this project, and get them to put their money where their mouth is?”.

It’s going to be hard – I suck at marketing – but to be honest I’m leaning heavily on the idea that this is something people want badly enough they’ll help me market and promote it. With KS, there’s no risk to you for helping here … if the campaign fails, you pay nothing. If it succeeds, I get enough cash (and enough users!) to guarantee development through to a production-ready version.

Are you in?

Support me on Patreon, writing about Entity Systems and sharing tech demos and code examples

ECS for Unity: design notes + next prototype

Recently I’ve been thinking a lot about how a high-quality ECS would appear / present itself within Unity, how it would interact with standard Unity3d game-code at the API level, how it would appear in the Unity Editor, etc. This evening, I had a go at making some of that within Unity itself.

NB: a few weeks ago I made a small Editor Plugin that used Reflection to upgrade and fix some of the core Unity Editor code/GUI. That was practice for what I’m doing here. It’ll hopefully appear on the Asset Store at some point (pending review right now!) – it has the full source unobfuscated, so you can see for yourself both what and how I got it to do its clever bits.

Continue reading

Unity’s failure as an Entity System, example 1: Selecting things

Entity Systems in Unity… some examples of the problems

This is a new series of blog posts, where I’m going to document specific ways + concrete examples in which Unity fails (sometimes spectacularly) as an “ECS” game engine.

I like Unity; but the core architecture (which is very old) is a half-assed ECS, and if we’re to upgrade it into a really good, modern, architecture … we first need to understand exactly where it’s failing, and why.

So, let’s start with Selecting Things…

Background

Game

A 2-player card game where each player normally draws a card each turn, and then plays one or more cards. Sometimes (e.g. when discarding because “too many cards in hand”) they have to select more than one card at once.

Initial version of game will be 1-player versus computer. Very soon: want to upgrade to OPTIONAL 2-players on-screen, with one using the mouse, other using gamepad. Ultimately, want to also add over-the-internet multiplayer (which ends up interfacing with the codebase in a very similar way to the original 1-player-vs-computer, so we can ignore for now).

Code Situation

Player taps card. Now … we must inform many other scripts and independent systems, so they can choose to eg.

  • ignore (if invalid for current state of game)
  • react (e.g. zoom to display the card more clearly)
  • “select” internally (side-effects include: deselect other things)
  • advance the game (if it was waiting-for-input)
  • ..etc

Problem

What/where do you send the “player clicked on a card; can some piece(s) of code PLEASE deal with this??!!?” ?

Addendum

In Unity, only the low-level “card” object can sensibly detect it has been clicked on.

Both Unity’s Physics (old) and EventSystem (new) effectively force this via their core design. Both require you to attach scripts to the physical objects that will be clicked.

In practice, this is bad for OOP (and bad for ECS too). When there’s e.g. 100 cards all of which must be separately clickable, your code is really in the wrong place. You don’t want cards (which sometimes are in a deck, sometimes on the table, sometimes “virtual” (perhaps in a virtual, unopened booster pack etc)) … to be containing all the GAME logic required to know what to do when they’re touched!

Classic Entity System / ECS solution

  1. Create a SelectedByPlayer component
  2. Add it to the card
  3. Sit back, and relax. Code that cares about input will scan “get me all SelectedByPlayer components” on each frame, and react accordingly

Everything works automatically; any System/Processor that’s “waiting for a selection”, or “making render changes when selections add/remove”, etc … will pick up what it needs, with no work.

You can add new input-handling routines simply by adding them. That’s all. No other changes needed.

Attempting to solve this in Unity

UNITY 4.6/5.0

Maybe … NB: I’ve only just started using the new GUI/EventSystem in Unity 4.6+ .. create a custom Input event, and a custom InputModule that can understand that, and then put all the code for ALL affected systems/processors into one monolithic ugly, hard-to-maintain script from Hell.

I suspect that this code will be quite maintainable w.r.t. adding new Input hardware in future – e.g. allowing mouse vs gamepad. But it’s going to suck at the rest, all the business-logic and handling. Which is going to be > 95% of the maintenance cost.

You get one small benefit: you can separate-out different inputs (click versus drag). Sadly, in reality: 95% of game actions will be simple clicks. This is one of those “the code architecture sounded great in academic situation, but reality is so unbalanced, it works out less well in practice” situations.

This is a classic OOP solution, and has the downsides. The only significant benefit I can think of is that it’s a “known” Hell: if you’ve done a lot of OOP game coding, you’ll be familiar with the pain you’re going to run into.

UNITY CLASSIC

Make a new class “CardClickManager” whose sole purpose is to reference all the possible bits of OOP code that “might” need to react, and which has to be updated by hand EVERY TIME you modify, add, or remove some input-handling code ANYWHERE else in the codebase.

Pretty much the same as above, except it:

  • … is even more simplistic (no event-dispatch systems)
  • … making it even harder to maintain + debug
  • … is slightly more proprietary

Conclusions / Improving Unity

So far, I cannot think of any sane, maintainable solution here other than “suck it down and use OOP, and suffer forever”, or “throw away Unity GameObject/Component, and implement a proper ECS”.

That’s fine, though. That’s the point of these posts – to hilight situations where there’s no good middle-ground, where we must create the data-centric, cleanly-separated architecture of a modern ECS.

Counter-ideas very welcome! Comment away, guys…

Towards a Unity3D ECS: what GUI? What features?

This year, one of my goals was to build a sane, powerful, viable Entity System / Entity-Component System within Unity3D. Something I could build current and future games on, and save a lot of dev-time (both in ease-of-use and in easily adding missing features that I wish Unity had).

So, progress?
Continue reading

Unconference on Entity Systems – Pre-Signup

Entity Systems are widely used in gamedev and starting to appear in mainstream IT / software development. But we want MORE developers and designers to benefit from this…

So, Richard Lord and I are going to do a mini conference on ES ideas/designs/uses/implementation/etc.

I’ll arrange venue, agenda (e.g. a Keynote) – but this will be an Unconference, so most/all sessions will be interactive, freeform, with no fixed Speakers.

To book a venue, I need an idea of numbers. So, if you’d like to come, please fill out this google form. Note: I’m planning to do this in Brighton, (UK) – less than 30 minutes from an International Airport (Gatwick).

https://docs.google.com/forms/d/156Sb9Qhx4RIX1d0BZg_22MVlUSoUb-gRqwrOq0zeT-w/viewform

Key info:

  • Date: Summer/Autumn 2014
  • Location: Brighton, UK
  • Cost: minimal (depends on demand + venue)

Your best links and articles on Entity Systems / Component Systems

The Entity Systems wiki is pretty good – simple source-code examples in 5 different languages, and links to 10 x richer, more complex “frameworks”.

But it’s got little (almost nothing) in links to articles, introductions, tutorials on the topic. I know there’s a lot that’s been written – just look at all the trackbacks on my old ES blog posts.

Let’s fill out a page on the wiki with tutorials, techniques, etc. What are your favourites (and can you give a 1-sentence summary of what each one does well?)

Data Structures for Entity Systems: Contiguous memory

This year I’m working on two different projects that need an Entity System (ES). One of them is a non-game app written natively on iOS + Android. The other is an FPS in Unity3D.

There are good, basic Open-Source ES’s out there today (and c.f. the sidebar there). I tried porting a few, but none of them were optimized for performance, and most of them were too tightly coupled to a single programming language or platform. I’ve started a new ES of my own – Aliqua.org – to fix these problems, and I’m already using it in an app that’s in alpha-testing.

I’ll be blogging experiences, challenges, and ideas as I go.

2016 Update: Support me on Patreon, writing about Entity Systems and sharing tech demos and code examples

Background: focus on ES theory, or ES practice?

If you’re new to ES’s, you should read my old blog posts (2007 onwards), or some of the source code + articles from the ES wiki.

My posts focussed on theory: I wanted to inspire developers, and get people using an ES effectively. I was fighting institutionalised mistakes – e.g. the over-use of OOP in ES development – and I wrote provocatively to try and shock people out of their habits.

But I avoided telling people “how” to implement their ES. At the extreme, I feared it would end up specifying a complete Game Engine:

…OK. Fine. 7 years later, ES’s are widely understood and used well. It’s time to look at the practice: how do you make a “good” ES?

NB: I’ve always assumed that well-resourced teams – e.g. AAA studios – need no help writing a good ES. That’s why I focussed on theory: once you grok it, implementation concerns are no different from writing any game-engine code. These posts are aimed at non-AAA teams: those who lack the money (or expertise) to make an optimized ES first time around.

For my new ES library, I’m starting with the basics: Data Structures, and how you store your ES data in memory.

Where you see something that can be done better – please comment!

Aside on Terminology: “Processors, née Systems”

ES “Systems” should be batch-processing algorithms: you give them an array/stream of homogeneous data, and they repeat one algorithm on each row/item. Calling them “Processors” instead of “Systems” reduces confusion.

Why care about Data Structures?

There is a tension at the heart of Entity Systems:

  • In an ES game, we design our code to be Functional: independent, data-oriented, highly efficient for streaming, batching, and multi-threaded execution. Individual Processors should be largely independent, and easy to split out onto different CPU cores.
  • With the “Entity” (ID) itself, we tie those Functional chunks together into big, messy, inter-dependent, cross-functional … well, pretty much: BLOBs. And we expect everything to Just Work.

If our code/data were purely independent, we’d have many options for writing high-performance code in easy ways.

If our data were purely chunked, fixed at compile-time, we’d have tools that could auto-generate great code.

But combining the two, and muddling it around at runtime, poses tricky problems. For instance:

  1. Debugging: we’ve gone from clean, separable code you can hold in your head … to amorphous chunks that keep swelling and contracting from frame-to-frame. Ugh.
  2. Performance: we pretend that ES’s are fast, cache-efficient, streamable … but at runtime they’re the opposite: re-assembled every frame from their constituent parts, scattered all over memory
  3. Determinism: BLOBs are infamously difficult to reason about. How big? What’s in them? What’s the access cost? … we probably don’t know.

With a little care, ES’s handle these challenges well. Today I’m focussing on performance. Let’s look at the core need here:

  • Each frame, we must:
    1. Iterate over all the Processors
    2. For each Processor:
      1. Establish what subset of Entity/Component blobs it needs (e.g. “everything that has both a Position and a Velocity”)
      2. Select that from the global Entity/Component pool
      3. Send the data to the CPU, along with the code for the Processor itself

The easiest way to implement selection is to use Maps (aka Associative Arrays, aka Dictionaries). Each Processor asks for “all Components that meet [some criteria]”, and you jump around in memory, looking them up and putting them into a List, which you hand to the Processor.

But Maps scatter their data randomly across RAM, by design. And the words “jump around in memory” should have every game-developer whimpering: performance will be bad, very bad.

NB: my original ES articles not only use Maps, but give complete source implementations using them. To recap: even in 2011, Android phones could run realtime 30 FPS games using this. It’s slow – but fast enough for simple games

Volume of data in an ES game

We need some figures as a reference point. There’s not enough detailed analysis of ES’s in particular, so a while back I wrote an analysis of Components needed to make a Bomberman clone.

…that’s effectively a high-end mobile game / mid-tier desktop game.

Reaching back to 2003, we also have the slides from Scott’s GDC talk on Dungeon Siege.

…that’s effectively a (slightly old) AAA desktop game.

From that, we can predict:

  • Number of Component-types: 50 for AA, 150 for AAA
  • Number of unique assemblages (sets of Component-types on an Entity): 1k for AA, 10k for AAA
  • Number of Entities at runtime: 20k for AA, 100k for AAA
  • Size of each Component in bytes: 64bits * 10-50 primitives = 100-500 bytes

How do OS’s process data, fast?

In a modern game the sheer volume of data slows a modern computer to a crawl – unless you co-operate with the OS and Hardware. This is true of all games. CPU and RAM both run at a multiple of the bus-speed – the read/write part is massively slow compared to the CPU’s execution speed.

OS’s reduce this problem by pre-emptively reading chunks of memory and caching them on-board the CPU (or near enough). If the CPU is processing M1, it probably wants M2 next. You transfer M2 … Mn in parallel, and if the CPU asks for them next, it doesn’t have to wait.

Similarly, RAM hardware reads whole rows of data at once, and can transfer it faster than if you asked for each individual byte.

Net effect: Contiguous memory is King

If you store your data contiguously in RAM, it’ll be fast onto the Bus, the CPU will pre-fetch it, and it’ll remain in cache long enough for the CPU(s) to use it with no extra delays.

NB: this is independent of the programming-language you’re using. In C/C++ you can directly control the data flow, and manually optimize CPU-caching – but whatever language you use, it’ll be compiled down to something similar. Careful selection and use of data-structures will improve CPU/cache performance in almost all languages

But this requires that your CPU reads and writes that data in increasing order: M1, M2, M3, …, M(n).

With Data Structures, we’ll prioritize meeting these targets:

  1. All data will be as contiguous in RAM as possible; it might not be tightly-packed, but it will always be “in order”
  2. All EntitySystem Processors will process their data – every frame (tick) – in the order it sits in RAM
    • NOTE: a huge advantage of ES’s (when used correctly) is that they don’t care what order you process your gameobjects. This simplifies our performance problems
  3. Keep the structures simple and easy to use/debug
  4. Type-safety, compile-time checks, and auto-complete FTW.

The problem in detail: What goes wrong?

When talking about ES’s we often say that they allow or support contiguous data-access. What’s the problem? Isn’t that what we want?

NB: I’ll focus on C as the reference language because it’s the closest to raw hardware. This makes it easier to describe what’s happening, and to understand the nuances. However, these techniques should also be possible directly in your language of choice. e.g. Java’s ByteBuffer, Objective-C’s built-in C, etc.

Usually you see examples like a simple “Renderer” Processor:

  • Reads all Position components
    • (Position: { float: x, float y })
  • Each tick, draws a 10px x 10px black square at the Position of each Component

We can store all Position components in a tightly-packed Array:

compressed-simple-array

This is the most efficient way a computer can store / process them – everything contiguous, no wasted space. It also gives us the smallest possible memory footprint, and lets the RAM + Bus + CPU perform at top speed. It probably runs as fast or faster than any other engine architecture.

But … in reality, that’s uncommon or rare.

The hard case: One Processor reads/writes multiple Component-types

To see why, think about how we’d update the Positions. Perhaps a simple “Movement” Processor:

  • Reads all Position components and all Velocity components
    • (Position: { float: x, float y })
    • (Velocity: { float: dx, float dy })
  • Each tick, scales Velocity.dx by frame-time, and adds it to Position.x (and repeats for .dy / .y)
  • Writes the results directly to the Position components

“Houston, we have a problem”

This is no longer possible with a single, purely homogeneous array. There are many ways we can go from here, but none of them are as trivial or efficient as the tight-packed array we had before.

Depending on our Data Structure, we may be able to make a semi-homogeneous array: one that alternates “Position, Velocity, Position, Velocity, …” – or even an array-of-structs, with a struct that wraps: “{ Position, Velocity }”.

…or maybe not. This is where most of our effort will go.

The third scenario: Cross-referencing

There’s one more case we need to consider. Some games (for instance) let you pick up items and store them in an inventory. ARGH!

…this gives us an association not between Components (which we could handle by putting them on the same Entity), but between Entities.

To act on this, one of our Processors will be iterating across contiguous memory and will suddenly (unpredictably) need to read/write the data for a different Entity (and probably a different ComponentType) elsewhere.

This is slow and problematic, but it only happens thousands of times per second … while the other cases happen millions of times (they have to read EVERYTHING, multiple times – once per Processor). We’ll optimize the main cases first, and I’ll leave this one for a later post.

Iterating towards a solution…

So … our common-but-difficult case is: Processors reading multiple Components in parallel. We need a good DS to handle this.

Iteration 1: a BigArray per ComponentType

The most obvious way forwards is to store the EntityID of each row into our Arrays, so that you can match rows from different Arrays.

If we have a lot of spare memory, instead of “tightly-packing” our data into Arrays, we can use the array-index itself as the EntityID. This works because our EntityID’s are defined as integers – the same as an array-index.

rect3859

Usage algorithm:

  • For iterating, we send the whole Array at once
  • When a Processor needs to access N Components, we send it N * big-arrays
  • For random access, we can directly jump to the memory location
    • The Memory location is: (base address of Array) + (Component-size * EntityID)
    • The base-address can easily be kept/cached with the CPU while iterating
    • Bonus: Random access isn’t especially random; with some work, we could optimize it further

Problem 1: Blows the cache

This approach works for our “simple” scenario (1 Component / Processor). It seems to work for our “complex” case (multiple Components / Processor) – but in practice it fails.

We iterate through the Position array, and at each line we now have enough info to fetch the related row from the Velocity array. If both arrays are small enough to fit inside the CPU’s L1 cache (or at least the L2), then we’ll be OK.

Each instance is 500 bytes
Each BigArray has 20k entries

Total: 10 MegaBytes per BigArray

This quickly overwhelms the caches (even an L3 Cache would struggle to hold a single BigArray, let alone multiple). What happens net depends a lot on both the algorithm (does it read both arrays on every row? every 10th row?), and the platform (how does the OS handle RAM reads when the CPU cache is overloaded?).

We can optimize this per-platform, but I’d prefer to avoid the situation.

Problem 2: memory usage

Our typeArray’s will need to be approimately 10 megabytes each:

For 1 Component type: 20,000 Entities * 50 variables * 8 bytes each = 8 MB

…and that’s not so bad. Smaller components will give smaller typeArrays, helping a bit. And with a maximum of 50 unique ComponentTypes, we’ve got an upper bound of 500 MB for our entire ES. On a modern desktop, that’s bearable.

But if we’re doing mobile (Apple devices in 2014 still ship with 512 MB RAM), we’re way too big. Or if we’re doing dynamic textures and/or geometry, we’ll lose a lot of RAM to them, and be in trouble even on desktop.

Problem 3: streaming cost

This is tied to RAM usage, but sometimes it presents a bottleneck before you run out of memory.

The data has to be streamed from RAM to the CPU. If the data is purely contiguous (for each component-type, it is!), this will be “fast”, but … 500 MB data / frame? DDR3 peaks around 10 Gigabytes / second, i.e.:

Peak frame rate: 20 FPS … divided by the number of Processors

1 FPS sound good? No? Oh.

Summary: works for small games

If you can reduce your entity count by a factor of 10 (or even better: 100), this approach works fine.

  • Memory usage was only slightly too big; a factor of 10 reduction and we’re fine
  • CPU caching algorithms are often “good enough” to handle this for small datasets

The current build of Aliqua is using this approach. Not because I like it, but because it’s extremely quick and easy to implement. You can get surprisingly far with this approach – MyEarth runs at 60 FPS on an iPad, with almost no detectable overhead from the ES.

Iteration 2: the Mega-Array of Doom

Even on a small game, we often want to burst up to 100,000+ Entities. There are many things we could do to reduce RAM usage, but our biggest problem is the de-contiguous data (multiple independent Arrays). We shot ourselves in the foot. If we can fix that, our code will scale better.

es-datastructures-structured-bigarray

In an ideal world, the CPU wants us to interleave the components for each Entity. i.e. all the Components for a single Entity are adjacent in memory. When a Processor needs to “read from the Velocity and write to the Position”, it has both of them immediately to hand.

Problem 1: Interleaving only works for one set at a time

If we interleave “all Position’s with all Velocity’s”, we can’t interleave either of them with anything else. The Velocity’s are probably being generated by a different Processor – e.g. a Physics Engine – from yet another ComponentType.

mega-array

So, ultimately, the mega-array only lets us optimize one Processor – all the rest will find their data scattered semi-randomly across the mega-array.

NB: this may be acceptable for your game; I’ve seen cases where one or two Processors accounted for most of the CPU time. The authors optimized the DS for one Processor (and/or had a duplicate copy for the other Processor), and got enough speed boost not to worry about the rest

Summary: didn’t really help?

The Mega Array is too big, and it’s too interconnected. In a lot of ways, our “lots of smaller arrays – one per ComponentType” was a closer fit. Our Processors are mostly independent of one another, so our ideal Data Structure will probably consist of multiple independent structures.

Perhaps there’s a halfway-house?

Iteration 3: Add internal structure to our MegaArray

When you use an Entity System in a real game, and start debugging, you notice something interesting. Most people start with an EntityID counter that increases by 1 each time a new Entity is created. A side-effect is that the layout of components on entities becomes a “map” of your source code, showing how it executed, and in what order.

e.g. With the Iteration-1 BigArrays, my Position’s array might look like this:

rect3859

  1. First entity was an on-screen “loading” message, that needed a position
  2. BLANK (next entity holds info to say if loading is finished yet, which never renders, so has no position)
  3. BLANK (next entity is the metadata for the texture I’m loading in background; again: no position)
  4. Fourth entity is a 3d object which I’ll apply the texture to. I create this once the texture has finished loading, so that I can remove the “loading” message and display the object instead
  5. …etc

If the EntityID’s were generated randomly, I couldn’t say which Component was which simply by looking at the Array like this. Most ES’s generate ID’s sequentially because it’s fast, it’s easy to debug (and because “lastID++;” is quick to type ;)). But do they need to? Nope.

If we generate ID’s intelligently, we could impose some structure on our MegaArray, and simplify the problems…

  1. Whenever a new Entity is created, the caller gives a “hint” of the Component Types that entity is likely to acquire at some time during this run of the app
  2. Each time a new unique hint is presented, the EntitySystem pre-reserves a block of EntityID’s for “this and all future entities using the same hint”
  3. If a range runs out, no problem: we add a new range to the end of the MegaArray, with the same spec, and duplicate the range in the mini-table.
  4. Per frame, per Processor: we send a set of ranges within the MegaArray that are needed. The gaps will slow-down the RAM-to-CPU transfer a little – but not much

es-datastructures-structured-megaarray

Problem 1: Heterogeneity

Problem 1 from the MegaArray approach has been improved, but not completely solved.

When a new Entity is created that intends to have Position, Velocity, and Physics … do we include it as “Pos, Vel”, “Pos, Phys” … or create a new template, and append it at end of our MegaArray?

If we include it as a new template, and insist that templates are authoritative (i.e. the range for “Pos, Vel” templates only includes Entities with those Components, and no others) … we’ll rapidly fragment our mini-table. Every time an Entity gains or loses a Component, it will cause a split in the mini-table range.

Alternatively, if we define templates as indicative (i.e. the range for “Pos, Vel” contains things that are usually, but not always Pos + Vel combos), we’ll need some additional info to remember precisely which entities in that range really do have Pos + Vel.

Problem 2: Heterogeneity and Fragmentation from gaining/losing Components

When an Entity loses a Component, or gains one, it will mess-up our mini-table of ranges. The approach suggested above will work … the mini-table will tend to get more and more fragmented over time. Eventually every range is only one item long. At that point, we’ll be wasting a lot of bus-time and CPU-cache simply tracking which Entity is where.

NB: As far as I remember, it’s impossible to escape Fragmentation when working with dynamic data-structures – it’s a fundamental side effect of mutable data. So long as our fragmentating problems are “small” I’ll be happy.

Problem 3: Heterogeneity and Finding the Components within the Array

If we know that “Entity 4” starts at byte-offset “2048”, and might have a Position and Velocity, that’s great.

But where do we find the Position? And the Velocity?

They’re at “some” offset from 2048 … but unless we know all the Components stored for Entity 4 … and what order they were appended / replaced … we have no idea which. Raw array-data is typeless by nature…

Iteration 4: More explicit structure; more indexing tables

We add a table holding “where does each Entity start”, and tables for each Component stating “offset for that Component within each Entity”. Conveniently, this also gives us a small, efficient index of “which Entities have Component (whatever)”:

es-datastructures-structured-megaarray-by-component

Problem 1: non-contiguous data!

To iterate over our gameobjects, we now need:

  • One big mega-array (contiguous)
  • N x mini arrays (probably scattered around memory)

Back to square one? Not quite – the mini-arrays are tiny. If we assume a limit of 128,000 entities, and at most 8kb of data for all Components on an Entity, our tables will be:

[ID: 17bits][Offset: 13 bits] = 30 bits per Component

…so that each mini-array is 1-40 kB in size. That’s small enough that several could fit in the cache at once.

Good enough? Maybe…

At this point, our iterations are quite good, but we’re seeing some recurring problems:

  • Re-allocation of arrays when Components are added/removed (I’ve not covered this above – if you’re not familiar with the problem, google “C dynamic array”)
  • Fragmentation (affects every iteration after Iteration 1, which doesn’t get any worse simple because it’s already as bad as it could be)
  • Cross-referencing (which I skipped)

I’ve also omitted history-tracking – none of the DS’s above facilitate snapshots or deltas of game state. This doesn’t matter for e.g. rendering – but for e.g. network code it becomes extremely important.

There’s also an elephant in the room: multi-threaded access to the ES. Some ES’s, and ES-related engines (*cough*Unity*cough*), simply give-up on MT. But the basis of an ES – independent, stateless, batch-oriented programming – is perfect for multi threading. So there must be a good way of getting there…

…which gives me a whole bunch of things to look at in future posts :).

PS … thanks to:

Writing these things takes ages. So much to say, so hard to keep it concise. I inflicted early drafts of this on a lot of people, and I wanted to say “thanks, guys” :). In no particular order (and sorry in advance if final version cut bits you thought should be in there, or vice versa): TCE’ers (especially Dog, Simon Cooke, doihaveto, archangelmorph, Hypercube, et al), ADB’ers (Amir Ebrahimi, Yggy King, Joseph Simons, Alex Darby, Thomas Young, etc). Final edit – and any stupid mistakes – are mine, but those people helped a lot with improving, simplifying, and explaining what I was trying to say.

Artemis Entity System in ObjectiveC

I wanted to try the latest version of Artemis, and I had an old game project that was quickly written in OOP style. So I went looking for an ObjC port…

Existing port: outdated

There was a port linked on the Artemis site that was OK – but had no documentation or updates, and Artemis has moved on since then.

There were also no unit tests etc – and the current Artemis getting-started wouldn’t work with this port (because so much has changed). So I started a new port…

New port: ObjC Artemis 100%

Primary aim:

  • make it identical to the core Artemis.

Continue reading

2014 Entity Systems: what are your Unity3D questions and problems?

In 2014, I’ll be making a new game in Unity that makes intensive use of an Entity System.

This will give me lots of ammo for a new post exploring the pros and cons of Unity’s “partial” Entity System architecture. I’ve been thinking about this a lot for the last couple of years, but I’ve been unhappy with the draft posts, and didn’t publish them.

Over the next couple of months, I’d love to hear from all of you the challenges, confusions, problems, and questions you have about this. I’m not promising quick answers – but it will help shape the blog posts I write, and as soon as I have a good enough set of answers, I’ll start posting them :).
Continue reading