Entity Component Systems from an Inheritance Fanboy – An Englishman in New York

Note: Quick observers will see that there’s actually nothing stopping you from using inheritance with an entity component system, and that’s perfectly true (in fact an entity component system would be hard to create without some inheritance) but this is merely a beginner’s guide and those versed in inheritance will hopefully know how to get the best out of both worlds after reading this.

Unity, as those of you who have worked with it before will know, is an Entity Component System. The best way to illustrate the differences between a system like unity and an inheritance hierarchy is with an example. Most people like to use cars as examples when explaining inheritance, and I’m highly unoriginal, so let’s follow that. Bear in mind that if your project has been well-planned from the start, you won’t encounter this problem when creating your classes, but it may arise when it comes to refactoring, performance optimisation or balancing.

Say you want to create a car. If you were using an inheritance architecture you’d create something like this:

That’s great, but what if we also want boats? Well, we’d move a lot of the code from Car into Vehicle, perhaps, and then we’d add float instead of drive, obviously, and maybe we’d add a function for calculating buoyancy and floating. The result looks like this:

The codebase has grown substantially already. Let’s add guns and let’s say that guns share nothing in common with a vehicle except that they also have a colour. We’ll pretend we decided boats were so big they needed textures instead of solid colours. What have you got?

Now it’s getting messy. We’ve broken the principles of DRY just to give guns colours. Now if we change how colours work (perhaps to add transparency) we’ll have to change it in two different places. It’s also worth noting that actually modifying the fact that boats no longer have a solid colour took a lot of work. We had to remove color from the Vehicle class, we had to add it manually to Car. We had to change the constructor for Vehicle, and all the inherited constructors. All this for a car, a boat and a gun. You can imagine that Grand Theft Auto must be a lot harder.

Depending on your language, the solution here might be multiple inheritance. Simply make  Car inherit from Vehicle and ColouredItem and make Gun inherit from ColouredItem. Multiple Inheritance has its own problems though, but I won’t go into them.

Unity’s solution is to use components. Each game object is the same class (handily called  GameObject) that handles some base functions and manages the component system. Each GameObject holds an array of Component instances which all dictate the various behaviours of the object. Here’s our example using the Entity Component System:

Admittedly this has led to the code being a little longer, but in the long run – with fewer non-DRY code segments and wonky inherits it’ll be a lot smaller and a lot easier to maintain. Want to change how colours work? Just change the Colour component. Anything with a solid colour will immediately be updated. Also, how code is executed has changed. In order to execute Accelerate() on the Driver component on your GameObject you must first find the Driver component (or use a pre-created reference to it) and then call the Accelerate function on it. In Unity, the code to do this looks like this:

In Unity, however, each Component comes with a set of functions ( Start() , Update(), etc) which allow components to be fairly autonomous. In this example, the Driver could listen for input in the Update() function, which is called once per frame, and call its own Accelerate() without external interference. It is important to note that this is not the case with all Entity Component Systems.

Another great feature is that functionality can be modified on the fly. Say you’re James Bond and you have an amphibious car. I’m not sure how I’d model that with inheritance, but I’m certain it would be wonky at best and have stronger code smells than a Fish class. If pressed for time, I’d probably create two classes, one for when the car was in the water and one for when the car was on land and swap between the two. With an Entity Component System however, all you have to do is remove the Driver component and add the Floater component. In fact with Unity, you can simply add both components simultaneously and enable or disable the Floater or Driver behaviour on the fly. Much easier.

However, It’s not without its drawbacks. With complex scenes, an Entity Component System can be much slower, because typically the list of all entities is enumerated for any given system, such as collision detection. In Unity, acquiring a component from an entity (for example when one component needs to talk to another) can be slow, and the Unity docs recommend that you do this once at the start of the level, and a reference kept for the rest of it.

If you’re interested in this topic and want more information, check out these pages:

The Entity Systems Project’s Wiki

Wikipedia’s page on Entity Component Systems

Boreal Games’ guide to Understanding Entity Component Systems on GameDev.net

One thought on “Entity Component Systems from an Inheritance Fanboy – An Englishman in New York

Leave a Reply

Your email address will not be published. Required fields are marked *