Part 2 – What is an Entity System?
Sadly, there’s some disagreement about what exactly an Entity System (ES) is. For some people, it’s the same as a Component System (CS) and even Component-Oriented Programming (COP). For others, it means something substantially different. To keep things clear, I’m only going to talk about Entity Systems, which IMHO are a particular subset of COP. Personally, I think Component System is probably a more accurate name given the term COP, but then COP is improperly named and is so confusing that I find if you call these things Component Systems they miss the point entirely. The best would be Aspect Systems, but then AOP has already taken ownership of the Aspect word.
An entity system is simply a part of your program that uses a particular way of breaking up the logic and variables of your program into source code.
For the most part, it does this using the Component Oriented Programming paradigm instead of the OOP paradigm – but there’s subtleties that we’ll go into later.
We refer to an entity “system” instead of entity “programming” because ES’s are usually found embedded in a larger, OOP, program. They are used to solve a subset of problems that OOP is poor at dealing with.
So, it is generally a replacement for Object Oriented Programming. The two are mutually exclusive: you have to choose one or the other (although any complex program may have multiple levels of abstraction, and you could mix and match OOP and COP/ES at different layers, any given layer is going to be one or the other (or, of course, any other alternative way of structuring your program).
Common misconception #1 – Entity Systems are part of OOP
Common misconception #2 – Entity == Class, Component == Object
Where OOP has Classes and Objects, an ES has Entities and Components – but it is very important to note that an Entity is NOT equivalent to a class, and a Component is NOT equivalent to an Object, although superficially they seem to share some characteristics. If you think of Entities/Component’s in OOP terms, you will never understand the ES, and you will screw up any attempt to program with it.
The whole point of ES’s using a different programming *paradigm* is that this means there CAN NEVER BE a direct equivalent between Classes and anything, or between Objects and anything – if there were, it would actually be the same paradigm, and just be a variant of OOP. It’s not. It’s fundamentally different and incompatible.
What’s an Entity?
An Entity System is so named because Entities are the fundamental conceptual building block of your system, with each entity representing a different concrete in-game object. For every discernible “thing” in your game-world, you have one Entity. Entities have no data and no methods.
In terms of number of instances at runtime, they are like Objects from OOP (if you have 100 identical tanks, you have 100 Entities, not 1).
However, in terms of behaviour, they are like classes (Entities indirectly define all the behaviour of the in-game object – we’ll see how in a second).
So, entities on their own are pretty much entirely useless – they are coarse-grained, and they serve to do little more than to tag every coarse gameobject as a separate item. This is where Components come in.
What’s a Component?
Every in-game item has multiple facets, or aspects, that explain what it is and how it interacts with the world. A bicycle, for instance, is:
- Made of metal
- Can be used by a human
- A means of transportation
- Something that can be bought and sold
- A popular birthday present
At this point, please note: OOP does not have this concept of multiple aspects; it hard-codes all the aspects into one glob, and declares that the set of behaviours and values of data to be the single-aspected Class of an Object. C++’s Multiple inheritance and Java’s Interfaces can get you a small part of the way towards the aspects of an ES, but they quickly collapse under the strain in fundamental ways that cannot be fixed within OOP.
The way that an Entity for an item represents the different aspects of the item is to have one Component for each aspect. The Component does one really important thing:
- Labels the Entity as possessing this particular aspect
It may do several other things, depending upon your implementation and the design of your ES. However, with an ES, this is the most important, because this is the basis of all method execution and processing.
What’s a System? (or subsystem)
An ES goes further than OOP in how it splits up the universe of code and data. In OOP, you make everything into Objects. With an ES, you have two different things that you split code and data into: the first is “Entity + Components”, and the second is “Systems”.
This is the source of a lot of the value of an ES. OOP is very good at implementing the part of any program that has lots of data floating around and lots of methods floating around which need to be executed only on a small, instanced, subset of the data in the program. OOP is very poor at implementing the “global” parts of a program, which have to operate “on everything”, or have to be invoked “from everywhere”. An Es solves this by explicitly dealing with all the global stuff using Systems, which are outside the realm of Entity/Component.
Each System runs continuously (as though each System had it’s own private thread) and performs global actions on every Entity that possesses a Component of the same aspect as that System.
There is a one to one relationship between Systems and AVAILABLE aspects (i.e. types of Component). A System essentially provides the method-implementation for Components of a given aspect, but it does it back-to-front compared to OOP. OOP style would be for each Component to have zero or more methods, that some external thing has to invoke at some point. ES style is for each Component to have no methods but instead for the continuously running system to run it’s own internal methods against different Components one at a time.
Typical Systems in a game would be: Rendering System, Animation System, Input System, etc.
The Rendering system wakes up every 16 milliseconds, renders every Entity that has the Renderable Component, and then goes back to sleep.
The Animation system constantly looks out for anything that would trigger a new animation, or cause an existing animation to change (e.g. player changes direction mid-step), and updates the data of each affected Entity (of course, only those that actually have the Animatable Component, i.e. are animations).
The Input system polls the gamepad, mouse, etc, and changes the state of whichever Entities with the Inputable Component are currently marked as being controlled by the player.
In tradtional OOP, if you have 100 units on a battlefield, and each is represented by an object, then you theoretically have 100 copies of each method that can be invoked on a unit. In practice, most OOP languages use runtime and compiler optimizations to share those methods behind the scenes and avoid wasting memory – although scripting languages for instance often don’t do any sharing, allowing all the methods to be independently changed on each and every instance.
By contrast, in an ES, if you have 100 units on a battlefield, each represented by an Entity, then you have zero copies of each method that can be invoked on a unit – because Entities do not contain methods. Nor do Components contain methods. Instead, you have an external system for each aspect, and that external system contains all the methods that can be invoked on any Entity that possess the Component that marks it as being compatible with this system.
That’s not an Entity System!
Well … at least, that’s what *most* people I’ve worked with consider to be an Entity System. But even within a single project, I’ve found multiple different ideas of what an ES is, some of which are compatible, others of which are incompatible. Here are some of the other ideas I’ve come across that people thought were ES’s.
Alternative definitions of entity systems:
1. An ES provides a different model of class-inheritance to OOP, especially w.r.t inheritance of fields. For any given entity-class you declare which aspects that class possesses, and the actual class is looked-up at runtime by piecing together all the different aspects.
2. The same as 1., but taken literally for methods as well as fields, i.e. this provides an interesting way to mix-n-match inheritance of functions/methods. So long as methods are attached to the fields upon which they operate, and/or a “pre-requisite” system is implemented such that “having aspect X automatically causes you to also have aspect Y”, then this works quite smoothly. NB: this is implementing “modular objects”: the “aspects” are complete objects from the standard theory of OOP.
3. A variant on 1. or 2. where the aspect data is pre-compiled into a large number of OOP classes at compile time, so that at runtime you are just running “normal” classes, without any lookup cost of the dynamic “I’ve got an entity E which claims to have aspect X; just hold on a sec while I build a function table to find out what the heck to do now someone just tried to invoke function Z…”
4. A way of compiling standard OOP classes into runtime-data (note: disassociating them from their OOP-ness) specifically so that you can treat them as streamed data instead of chunked binary + data. The main value of this is to play nicely with hardware that has tiny tiny amounts of memory available in the code cache and/or very very slow access to fetch extra code, but has vast bandwidth to stream SEQUENTIAL data through the CPU. PlayStation consoles especially like this approach, as opposed to the typical PC approaches. Note that in this case, the idea is that the game-programmers and game-designers are UNAWARE that there’s an entity system – it’s a runtime/compile time performance optimization, not a design-feature.
5. A system design that revolves around excessive use of the Observer pattern, but does so using standard OOP techniques. I mention this because it’s a common (ab)use of the concepts of ES’s, but lacks much of the advantages. For what it’s worth … that’s the situation I was in when I first discovered ES’s. So, personally, I really don’t count these as ES’s. These are not an ES, but an: “OMG, I need an ES!”, but many people persist in thinking (and claiming) they’re a true ES.
NB: IMHO this is one of those “you really shouldn’t do this” classes of Entity System usage. Why? Because you end up just creating MASSIVE OOP classes with tonnes of independent implemented Observer methods tacked onto them. That’s fine as a general approach, it buys you something whilst remaining ENTIRELY OOP, but it also loses most of what ES’s have to offer, especially in the realm of flexibility and compound inheritance.
Who cares about ES’s and why? (where did they invent these from?)
1. Coders who are used to writing a graphics/rendering engine and trying to keep it isolated / separate from the rest of the computer game. They learnt that they can write the entire graphics engine using only PARTIAL information (a couple of aspects – no more than 2 or 3) of every OOP object that exists in the game-universe. They need to use: Renderable (do I have to paint it to the screen every frame? [it will have all the methods necessary to do that painting generically]), Updateable (does it potentially change in response to one or more game-loop-ticks? [animations are a great example of this – their internal state changes independently of how many times they’re rendered]),
2. Multi-threaded coders who are looking at the concept of aspects per se (i.e. Renderable as opposed to Updateable) to allow for coarse-grained multi-threading: you are allowed one thread per aspect, and this is guaranteed safe simply because the aspects are – by definition! – independent from one another. Since a typical ES will have a dozen or more aspects, you’ve just bought yourself reasonably effective performance scaling of up to 12 separate CPU cores, for free.
Also … going to the next level of difficulty and performance improvement, they’re looking for the largest possible individual (literally: things that “cannot be divided”) things that can be made the atomic level of multi-threading. The default position is that only manually-hard-coded atomic operations count, and OOP objects certainly are full of all sorts of multi-threading individual pieces so are far too coarse, but maybe components within entities are small enough to be the unit of atomicity.
3. Game designers who want to enable “everything to become anything”.
Do Cameras shoot people?
Do Bullets accept input from the player?
Well … have you played Unreal Tournament? If you have but didn’t answer yes to the earlier questions then you need to find someone to show you a Redeemer being used in Alternate Fire mode (hint: you get to manually “fly by wire” the rocket from a first-person view inside the warhead itself).
ES’s allow everything and anything to be used as anything and everything, interchangeably, with no re-coding. That’s the beauty for designers – all the artifical constraints on design that were previously enforced by coders having to, you know, place SOME constraints just to write their own damn code and have it be reasonably performant and bug-free are suddenly lifted.
It’s true – you really CAN have strongly-typed safe code and yet have total freedom to pass any object to any method; at least, you can with Entity Systems.
4. Coders who go a bit overboard with the Observer pattern.
If you’re unsure about this one, and have used Observers a lot, ask yourself this: have you ever had that problem with Observers where you found that “just one base class isn’t enough”? i.e. one base class that implemented a handful of different Observers worked great, but as your system / game / application expanded you found you needed more variety in that base class, you needed multiple different versions, and you needed *every possible combination* of those different versions, because base-classes cannot/will not “stack” nicely on top of each other.
Thought for the day
Programming *well* with Entity Systems is very close to programming with a Relational Database. It would not be unreasonable to call ES’s a form of “Relation Oriented Programming”.
This needs a followup post, but you might want to think about that :) both in terms of how the above statement could be true (hint: think about what most of the code you write for each System is going to look like, and what exactly it is doing), and also in terms of what the knock-on effects of this are if it is true.
Bear in mind that no-one’s yet managed to do OOP fast with Relations; the excessively high conversion cost between RDBMS and OOP – both at coding-time and at runtime – is still one of the biggest single development problems with writing an MMO.
NEXT: Part 3
75 replies on “Entity Systems are the future of MMOG development – Part 2”
[…] least according to the T=Machine definition. (See “What’s a System” in part 2 of his […]
after reading tons of info about games/software architectures and approaches your article is most interesting and promising, thank you adam
This post is great! I have been trying to design my entity/game object system before implementing it, and this post really clarified a lot of my thinking and put it into words. Thanks!
I’m trying to implement an ES, but I’m wondering about things that go a little higher. Say I’m trying to create quite complex cars; would I create a CarSystem that handles all objects with a Transform and a single CarComponent? Or would I rather implement the car as a combination of components…
It seems to create bigger complex structures with this component idea you start to loose track. For example, my car has a separate gearbox class, separate wheels, engine etc. If I turned these into components, there would be a lot of interaction going on.
Making a blob-like component where a car is 1 component seems not clean as well. Any ideas?
Also, what about adding 2 components of the same type? I thought of a Mesh component, which accepts a filename. But if the mesh is more complex, for example I have a car body and a ‘wing’ 3D mesh added, would I add 2 components of the Mesh type, or do a GroupComponent or such?
Two meshes suggests you have two entities.
Otherwise, why did you export them as separate meshes?
Ok, two entities then. Suppose I have an engine (with mesh) plus a propeller (also with mesh) attached to it (a very simple plane ;-) ). Two entities.
The engine has an InputComp and MeshComp and an EngineComp. The Propeller only a MeshComp. With the mouse I input ‘throttle on’ and the engine’s EngineComp (through EngineSystem) rpm increases.
How would the engine entity get its new rpm communicated to the propeller entity? Through a PropellerSystem? And if so, this requires the EngineSystem to ‘know about’ a PropellerSystem, which doesn’t seem clean.
The only communication seemingly should be between systems, I fail to currently see how two entities could influence eachother in this way (I’ve read chunks of articles by now over the last 2 days).
How do you normally ‘link up’ 2 related entities?
PlanesSystem, which deals with all the mechanics of a plane.
It knows that a semantic plane is composed of multiple entities, and it EITHER tracks which set of entities comprises a whole plane, OR those entities have name references to each other.
Since an entity is formally just “a name”, a component can refer to other entities easily.
Personally, I’d be tempted to have a separate “plane” entity that had a “PlaneParts” component that was just a list of the names of the other entities on the plane.
NB: when you use referneces to other entities (by name) you want to limit it to cases where it wont happen most of the time. e.g if the only time you’d need to know that the Prop and Engine were related is when starting/stopping the prop animation, that’s fine – it only happens infrequently.
But if you needed to know that relationship every frame, you’d perhaps say “I’d better make them into a single entity, since they’re ALWAYS used together”.
Short answer: tehre’s no “right” answer. And you can chop and change as you go, with VERY little code rewriting, so dont be afraid to change things around
Excellent blog! I’ve been familiar with game programming for quite a while, but am starting to do more of it in my freetime. Currently I’m researching different game engine design patterns. Right now I’m leaning towards entity systems for my engine rewrite (when I learn something new, I enjoy reinventing the wheel at least a handful of times) Your blog posts have been very enlightening. Thanks for sharing!
ps- I’m surprised that you still respond to any new comments
[…] you keep following this avenue of design, you eventually end up with an entity system architecture. Entity system architectures are quite elegant, in my opinion, and I might do an […]
One of the best articles on Component-based development. Thank you for clarifying this interesting approach.
I’m having a little trouble understanding how the logic being in the system instead of the components is better. Consider chess. Each piece would have a movement and position component, but each piece moves very differently.
How would you have the different movement systems determine which entities belonged to them in order to move them correctly?
Yes: if you stick to simple, passive board games, with no AI, then this technique is overkill. But in that situation, it only takes you a few hours to write your game anyway, so you’re fine using any technique you like – none will particularly help.
But the vast majority of game development is orders of magnitude more complex than Chess. If you try – for instance – to write a computer game of Chess, that has AI … you certainly don’t have “a movement and position component”.
Instead, you have: movement, position, potential positions this turn, potential positions on future turns, threat radius, threatened squares, tactical options, strategic options, available “plays” (famous chess strategies), enemy-histories-per-piece (what does your opponent tend to do with pawns?) … etc.
A computer game of chess is exactly what I was talking about. It was also just an example. Most video games have enemies that move differently. I just don’t understand how a system (a particular movement system in this example) determines that it is the controller of movement for 1 entity and not another, given the commonality of movement related components all enemies are likely to share.
I suggest you comment on the individual articles with the paragraph / concept you want more help with. Your last comment suggests you haven’t grokked most of them.
If I had “grokked” the article then, by definition, I wouldn’t have any questions about it ;)
I can quote the paragraphs inline if you like, but that will probably make this post messier to read.
Earlier, you also say
But I think we all know that this is practically unlikely. Look at all the components you listed that have to do with the movement of a chess piece. Are you really saying there would be a system for each one of those components listed that could execute in any order while always getting the same result? Or would you have a AI/movement/whatever_you_want_to_call_it system that operates on all those at once? My thought is the 2nd makes more sense since what you do to several of those components depends on the state of others.
But lets say you DO have a system for each one. When you get to the potential positions component, how would the knight movement system stop itself from overwriting what the pawn movement system did to pawn components which also have a potential positions component? Do you scrap the potential positions component all together and have potential knight positions, potential pawn positions, potential queen positions, etc components instead? This should work to stop systems from operating on the wrong entities, but also looks like it would overcomplicate things.
Or have I gone down a completely wrong path and entities are explicitly added to systems instead of systems figuring out what entities they should operate on (which is what I gathered from the 1st paragraph I quoted)?
Systems operate on components. They don’t care about anything else (unless they have to work with external data, e.g. a mouse, or a network).
Why on earth would you NOT have a system-per-component I listed? I might have some of those components be used by more than one system, and some of them would have no particular system – but I’d have as many systems as fit well.
[…] Over the course of development, I refactored the codebase I was working on a few times to continually clean things up. Eventually I settled on creating a basic Entity-Component framework inspired by Artemis and posts by Adam Martin. Just about everything in the game is an Entity; every data attribute is packaged in a Component; and everything that happens to update or react to those Components happens in a System. For a basic overview of the theory behind this, check out this post. […]
Hi Adam, interesting post! I (by coincidence) stumbled upon a similar component system for a game I was writing when I realised that I have all these types of entities (players, towers, monsters, trees…) and each one has different abilities, maybe some trees can fire, maybe some of them can move, maybe some towers have an inventory.. etc.
However, I’m wondering if the ES is really so far removed from OOP. For me, the detail is that objects cannot interact on their own, and it is the collection of objects which forms the appropriate encapsulation method rather than single entities. It’s perfectly fine to have an object to represent a collection of objects (see: Jeff Bay – object calesthenics, First Class Collections) which has methods to optimise and deal with the set of objects / components rather than assuming that each one individually should know what to do with itself. After all, if you have 2 objects that collide, neither of them knows enough on their own to resolve the final position and velocity – there needs to be an object to deal with the _collection_ of objects and their interactions. I think some people mistakenly call these “Managers” and are then chased by the OOP police :)
Also, it sounds like the crucial ability is to be able to add / remove components from entities at will, and registering / deregistering their components from the relevant systems – this is the hard part to design properly, at least thats what I’ve found – if the MovementSystem resolves a collision which causes an enemy to die, who calls the LootSystem to tell it to drop some loot for that enemy? Does the MovementSystem keep a reference to the LootSystem? Does the enemy have an OnDeath function (and keep a reference to the lootsystem?) Does the Enemy simply set a “dead” flag and wait for the DeathSystem to clean it up?
The challenges you list partly come from an OOP background; dump OOP thinking, and you should find they evaporate.
In OOP terms, using “an object to represent a collection of objects” is probably only fine if you’re in academia; it’s usually (in my experience: “always”) very much “not fine” in game development. In development (not theory), the dire performance loss from that is a serious problem – you destroy the core, lowest-level, built-in, optimizations of some (most?) full-bore OOP languages (anything originally based on C, for starters). That’s a huge problem.
Use OOP as much as you like (I use it every day), but … in 10+ years of doing this, I’ve found that most people find it considerably easier and faster to grok ES’s once they deliberately stop trying to apply OOP principles. Pace the ones that find OOP entirely congruent with ES’s (you’re lucky, but you’re a minority).
Awesome article! Very thorough description. Grokked it.
[…] going into too much detail myself, I used an ECS, or Entity Component System. For the most part, this doesn’t change the loop, and the majority of the change happens to […]
Thanks for sharing! I’m building an ECS, but i confuse how interact between two component or two system.
Can you send me an example game code?
There are many examples in thus category if you click the tag at top / bottom of page, also on the entity systems wiki.
There are many examples in thus category if you click the tag at top / bottom of page, also on the entity systems wiki.