Please note: the design described in this blog post has been much improved and updated and put up – with full source – on http://entity-systems.wikidot.com/.
On the wiki linked above, there is now a wholly new Entity System design, based on this one, but much improved. There’s a brief post about it here, recommended instead of this ES design: http://t-machine.org/index.php/2011/08/22/entity-system-rdbms-beta-a-new-example-with-source/.
I’ve been writing about Entity Systems sporadically for the last few years. Recently, I finally had the time and the excuse to build one of my own (i.e. not owned by an employer). If you haven’t read the main series of ES posts, you should do that first. There are many things in the world masquerading under the Entity/Component banner – and even more that just coincidentally share the name, but describe something else completely. It’s worth understanding which variant I’m talking about before you read about what I’ve done :).
Why build an Entity System?
At a generic level, this is covered in the other posts. But it’s taken years for me to have the time/inclination to write a new one from scratch outside of my day-job. What happened?
- I left my iPhone in America, and it took 2 months to get it back
- Google gave me a free Nexus One, in the hope I’d write something for it (ha! Their cunning plan worked…)
- The Android marketplace is such a miserable morasss of third-rate crap that eventually I was compelled to write my own Android game … just so that I would have something to play (there are very few games on the Android store that are even worth the time it takes to download them)
I’ve been making games for a long time. I know how much effort will go into it, how much time, and how much slog there is before it becomes worth it. Writing a game on your own often means putting in 90% of the effort to get 10% of the reward.
Enter … the Entity System. If I were to pick a game-design that mostly used data-driven game features, I could implement it around an ES, and massively reduce the amount of planning needed to get the game running. I could maybe have a working game after a mere 20% of the effort. Hmm…
Building the ES for Android
Android runs something that’s *almost* Java (although more on that later – Android’s version of Java is very slow at some of the core libraries, and it really shouldn’t be). Technically, Android supports all the core data structures from Java (Collections), and the templating system (Generics).
If I were writing an ES in C++, I’d do it using templates without pausing to think; I wondered how well the same might work with Generics, given that Generics is *not* a complete templating system, although it provides quite a lot.
Getting started: early ES decisions
How to design/implement this thing? Well, we know one thing for sure:
Entities have a single name/label/global-ID. Entities MUST NOT contain ANY DATA: these are NOT objects, this is NOT OOP!
There you go, the Entity class wrote itself:
[java]
public class Entity
{
public int id;
}
[/java]
This immediately raised some concerns for me, being the seasoned coder I am (ha!). How the heck was I going to write any code that dealt with these things if I didn’t have references to them? Obviously, sometimes you do have references, but other times you expect to follow refs from within the objects you have, to get to the objects you need. That wouldn’t be happening here, since there are no inter-object refs.
[java]
public class BaseEntitySystem implements EntitySystem
{
/** I’m too lazy to write a "safe" method to get a globally-unique ID; for now,
I just return 1 the first time I’m called, 2 the second time, etc… */
protected int getNextAvailableID();
/** Whenever you create an entity, you’d better invoke this method too!*/
public void registerEntity( Entity e );
/** The method to solve my fears above */
public Entity getEntity( int id )
/**
* Merely removes the entity from the store. It becomes a GC candidate
* almost immediately (since all other refs are transient)
*/
public void killEntity( Entity e )
}
[/java]
…but, again, being a Veteran coder, the survivor of many painful battles on the field of programming … I didn’t trust myself in the slightest to “always remember” to invoke registerEntity. Quick trick: give the Entity class a static reference to a default EntitySystem, and have each EntitySystem check if that reference is null when starting; if so, set itself as the “default”.
[java]
public class Entity
{
…
public static EntitySystem defaultEntitySystem;
…
public Entity( int i )
{
id = i;
if( defaultEntitySystem == null )
throw new IllegalArgumentException( "There is no global EntitySystem; create a new EntitySystem before creating Entity’s" );
defaultEntitySystem.registerEntity( this );
}
…
}
public class BaseEntitySystem implements EntitySystem
{
…
public BaseEntitySystem()
{
if( Entity.defaultEntitySystem == null )
{
slog( "Setting myself as default entity system (Entity.default… is currently null) self = " + this );
Entity.defaultEntitySystem = this;
}
}
…
}
[/java]
W00t! I can create Entity’s, and I can find them later on. Awesome. What about those Components, then?
Getting started: Components in Java
I’ve done ES in C++ before, with real templates, so I wasn’t really thinking at this point … I just ran with what seemed natural based on prior experience. The thought process (had there been one) would have been something like this:
- This is java, I use Eclipse: I absolutely *must* have the IDE know what data/fields exist in each component so that Content-Assist/Autocomplete works 100%. Otherwise I will gouge my own eyes out having to remember, and doubly so each time the app compiles but dies at runtime because of a typo in a field-name.
- Requirement: each unique Component must be defined as a java Class, with each of the fields being a public member of that class
- Requirement: to access a Component of a given Entity, you must invoke a method which returns something that is typed (as in language typing) to the correct Class
I made a Component class, and had all Components extend it; there is a particular reason for this, but it doesn’t matter right now – essentially, it lets you define shared behaviour for all Component subclasses, and just saves you time on typing.
My first real Component:
(NB: I defined this *inside* another class, because I couldn’t be bothered having N source files for the (large number of) N Components I was bound to create. Hence the “static”):
[java]
public class MyEntitySystemExperiment
{
…
static class Position extends Component
{
float x, y;
int width, height;
float rotationDegrees;
@Override public String toString()
{
return "("+super.toString()+" @ ("+x+","+y+") * rot."+rotationDegrees+")";
}
}
…
}
[/java]
Great. I have a component. Now comes the largest single piece of work in the entire implementation of the ES: writing the methods to:
- Add a component to an Entity
- Fetch a component from an Entity
- Remove a component from an Entity
Fetching a Component from an Entity
This is the win/lose point: if this works well, our ES will be nice and easy to use. The other two methods (add and remove) are simply twiddling bits of data. This one is the challenge: can you make it *easy* to write code that uses the ES, and for that code to be clearly *understandable*?
[java]
public class EntitySystemSimple extends BaseEntitySystem
{
HashMap<Class, HashMap<Entity, ? extends Component>> componentStores;
public <T> T getComponent( Entity e, Class<T> exampleClass )
{
HashMap<Entity, ? extends Component> store = componentStores.get( exampleClass );
T result = (T) store.get( e );
if( result == null )
throw new IllegalArgumentException( "GET FAIL: "+e+" does not
possess Component of class\n missing: "+exampleClass );
return result;
}
…
}
[/java]
Boom! It works.
Let’s just stop briefly and I’ll explain why. Reading Java generics code from cold (just like reading C++ templates) often takes a lot of hard thinking.
Looking at the “result” of this method, we want it to be (enforced by the compiler):
- “an instance of a class that extends Component”
- “an instance of the particular class/Component that we requested – not just any old subclass”
[java]
/** based on comments at end of blog post, think this is correct,
but not checked */
public <T extends Component> T getComponent( Entity e, Class<T> exampleClass )
[/java]
It causes you to write application code that looks something like this:
[java]
public void doSomethingWithAnEntity( int globalId )
{
// remember, we NEVER hold refs to Entity objects for long
Entity e = entitySystem.get( globalId );
Position position = entitySystem.getComponent( e, Position.class );
position.x = 5;
}
[/java]
…and what’s important is that the “type” of the “Position position = …” line is already hard-typed to “Position”. So, the content-assist will *auto-complete* anything put after a dot on the end of that line, e.g.:
[java]
entitySystem.getComponent( e, Position.class ).AUTO_COMPLETE
[/java]
…so you can instead write your method much quicker, and yet very clearly, as:
[java]
public void doSomethingWithAnEntity( int globalId )
{
// remember, we NEVER hold refs to Entity objects for long
Entity e = entitySystem.get( globalId );
entitySystem.getComponent( e, Position.class ).x = 5;
entitySystem.getComponent( e, Damage.class ).hitpoints = 145;
entitySystem.getComponent( e, Renderable.class ).foregroundColour = Color.red;
}
[/java]
Time-out: HashMap
HashMap is the “correct” class to use in Java for this setup: it’s the exact equivalent of Hashtable / Dictionary / etc in other languages. We need to map (somewhere, somehow) from one thing (an entity) to another thing (a component).
NB: this does not mean that you have to use HashMap as your data-store for the ES; I positively encourage you to consider other options. I used it here as the most obvious, simplest possible structure that would do the job. If you think back to my posts on Entity Systems for MMO development, I’ve often suggested that the data store could *and should* be any of many different things. In particular, SQL databases make for an excellent data-store (and remember you can get in-memory SQL implementations that do away with all the expensive write-to-disk stuff).
Unfortunately … Android seems to only partially support HashMap. You can use the class, but it runs an order of magnitude slower than you expect for a normal JVM (compared to the speed with which it runs other methods). It seems to have problems with the hashcode methods, but also even with basic iteration over the Map contents. Odd. Later on, I had to do some tricks to speed up the ES, just because of this problem.
Fetching a Component from an Entity: Redux
The examples I gave above for accessing components were lean and clear on the right hand side (thanks to autocomplete and strong typing), but terrible on the left-hand-side. By the magic of OOP, I’m going to clean up the LHS. BUT (and this is a big “but”) … make sure you fully understand what I’m doing here. With what I’m about to do, it would be very easy to fall into one of the traps of ES development: slipping back into OOP techniques.
Looking at the example:
[java]
entitySystem.getComponent( e, Position.class ).x = 5;
entitySystem.getComponent( e, Damage.class ).hitpoints = 145;
entitySystem.getComponent( e, Renderable.class ).foregroundColour = Color.red;
[/java]
… applying OOP mindset, we see that the first argument is redundant; the Entity already knows about the EntitySystem to which it’s registered.
Also, we know that the Entity class will never have any methods or data other than the ID. If that’s the case, the only thing we’d ever “get” from an Entity is a Component. So, we can add this to Entity:
[java]
public class Entity
{
…
/** Gets a filtered view of the entity’s data, only returning the subset that
* corresponds to a particular one of its components */
public <T extends Component> T getAs( Class<T> type )
{
return source.getComponent( this, type );
}
…
}
[/java]
…which converts our usage example to:
[java]
e.getAs( Position.class ).x = 5;
e.getAs( Damage.class ).hitpoints = 145;
e.getAs( Renderable.class ).foregroundColour = Color.red;
[/java]
Using the ES with Systems
Recap: right now, we can:
- Create entities
- Add components to entities
- Read/Write the data inside each component, on a per-entity basis
- Fetch entities by globally unique ID
One last thing is needed before the ES can work: we need a way to fetch Entities “by component”.
e.g.:
[java]
public class MyEntitySystemExperiment
{
…
public void runLoop()
{
while( true )
{
// move all the entities
positionSystem.move( MOVEABLE_ENTITIES );
// check for collisions
collisionDetectionSystem.process( MOVEABLE_ENTITIES );
// render all the visible entities
renderingSystem.render( RENDERABLE_ENTITIES );
}
}
…
}
[/java]
We need a way to provide the arguments that are capitalized above. We know that these should be plain-old lists of entities. We know they have to come from the EntitySystem. Finally, we know that the only defining characteristic of these lists is that everything in the list has *at least* a particular Component.
(respectively, in the example above, the lists contain: “all entities that are moveable”, “all entities that are moveable AND all entities that are barriers to movement (e.g. solid walls)”, and “all entities that should be displayed on-screen”)
So, one more method for the EntitySystem interface:
[java]
public interface EntitySystem
{
…
public List<Entity> getAllEntitiesPossessing( Class… requiredComponents );
…
}
[/java]
“Class…” is just a convenience; in many cases, you’ll be insisting on a single Component. In many other cases, you’ll be insisting on a set of components. Java varargs provide the minor convenience of doing both of those in one method, while retaining type-safety.
The implementation of this method is obvious: it iterates over every entity that’s been registered, and checks it against ALL the required components. If it possesses all of them, it goes into the output list.
Finis
That’s it. So easy! Obviously, there’s more to it – the other methods you need to create should be mostly self-evident – but this should be enough to get you started.
Now, I’m not sure where to go from here. I’ve got a working Java ES. I’ve got some performance improvements and feature improvements. But … in practice, hardly anyone writes games in Java (except Android programmers, and there aren’t many of those), so … is it worth it?
Alternatively, I might just run through some of the practical pros and cons I encountered when actually using the ES in writing the game-logic. There’s some interesting things that came up which most people encounter sooner or later when doing their first ES, and which might be worth looking at in more detail.
One last thought…
Did it work? Did this ES allow me to write a decent Android game?
Yep. I wrote a space-invaders / bullet-hell game with it. It worked fine on Android phones for a hundred-odd enemies and bullets on screen. On Android, thanks to the crappy JVM, it started to chug after that (dropped below 30 FPS), so I had to make some substantial performance improvements, and now it’s happily rendering 300 things all flying around at 20-30 FPS. The game is far from finished, but it’s playable and fun for a minute or so – a definite achievement considering how little of it I’ve written so far.
NB: it’s got some way to go before I’ll be happy releasing it. But, given a few more spare evenings, I hope to get this up on the Android Market as a free download in the near future.
I’m pleasantly surprised that the Android phones can handle something as high-level as an ES, in a pure, unoptimized “simplest possible” implementation.
Did this post help you?
You can say “thank you” by giving me your email address, and letting me contact you next time I make a game of my own:
177 replies on “Entity System 1: Java/Android”
@Adam
In the example a Physics component store velocity, acceleration and a pointer to the position member on a Draw component. The goal is to have component-wiring allowing greater flexibility with fewer components.
More specific / complex components can be coded as needed. I can also see wiring being useful in assembling smaller components for prototyping and implementing simple logic, for example a conditional component for simple behavior.
This was our solution to: How do components communicate with each other?
Thanks…
I don’t think you mean “communicate” – components *never* communicate with each other. I say this over and over and over again in the articles – if you haven’t read them, read the series linked at the top of the post.
Components are data. Data cannot “do” anything, there’s no code … so it can’t communicate :).
In your example, I still can’t see the reason why the physics component needs to have any kind of “wiring” to the location component. What would be the point?
What’s the point of “having fewer components”?
I’m not sure, but I think what you’re trying to describe is:
a. Location component: x, y, z
b. Physics component: x-accel, y-accel, z-accel
…and you’re going to write a system that takes – say – an array of entities:
(void) doPhysics( Array a )
{
for( ComponentHash entity in a )
{
entity.get( “location”).x += entity.get( “physics” ).xvelocity;
entity.get( “physics” ).xvelocity += entity.get( “physics” ).xacceleration;
}
}
@Adam
I really appreciate the replies, and the discussion, I read all 5 articles twice, plus this one… Let me clarify because I think we are on the same page, after looking at your code.
Our system does what you have above, it just does it a little differently. The physics component is wired to the location component’s position(x,y) this is done when both components are created. We do this because it’s now possible to add a physics component and wire it to a component that controls the rotation, this would be something like a Physics1D component. The same Physics1D component could also be wired to location.x when an object only needs to move left/right. We have a Physics2D and Physics3D component as well.
The goal is to have fewer more flexible components, at the core both implementations are very similar, components dont have any methods, however at some point code has to “act” on the component, example, your doPhysics method is the code that acts on the component.
The only difference is, instead of hard wiring the relationship between the physics and the location, the physics component has a data member called “position” which is a pointer to the location object’s “position” data member. Using C this is trivial to implement.
When doing the physics or update phase as we call it, we walk all “update” components and use a simple switch statement to fire the “doPhysics” or whatever code is acting on the component data, end result is the same, just an implementation detail.
Again, I really appreciate the time you have put into writing these articles and answering the comments.
Thanks
You’re burying logic inside these relationships. Bad move. Keep the logic outside your components.
I might have misunderstood, but … It sounds like you’re trying to solve an unrelated problem, something about re-use of physics code, and the way you’re going about it is poisoning your ES.
?
Just want to clarify and make sure I am with you…
You are saying that linking two components as a configuration/data is the poison?
Physics2D // component data id = 1
vec2* pos; // database value 2->pos // links the physics component to the location component
vec2 vel; // database value 1,1
vec2 acc; // database value 0.5,0.5
Location: // component data id = 2
vec2 pos; // database value 100,100
Although this is a very simple example, I see flexibility here. You have more options without changing working engine code. Similar to how you talk about expanding or fixing the world by simply updating the component data, and having the ability to do so after shipping the game. You would of course still create specialized components when needed.
BTW I do understand that “vec2* pos; // database value 2->pos” has to be handled when the data is delivered to the engine (lookup the other components data location etc..) several ways to do it without breaking the ES concepts, but I see this as a “configuration” no different that vel, acc and not “logic”
Great discussion, Thanks…
This is why you have “entities” in an ES – to link instances of components together.
…otherwise there’s not much point in having the concept of an “entity”. Or even an ES. Instead, just have a sea of random components that are internally connected to each other in opaque manner.
But if you do that, you lose lots and lots of things you could otherwise have done.
questor, a few months late, but your source posted here has a problem.
In the getEntities() function you don’t return a list of entities containing the ID of the component, but rather return the entities which their OWN ID is the one of the component.
This means that if you want a component with ID=3, it will return the 3rd created entity.
I believe you meant to do this:
[php]
template void getEntities (set& result)
{
map m = mComponentStore[T::mId];
map::const_iterator it = m.begin();
map::const_iterator end = m.end();
for( ; it != end; it++)
result.insert(it->first);
}
[/php]
No tags here? :(
ok i have made an attempt at implementing this in c++. here is the src on google code http://code.google.com/p/metalheavensurvivor2/source/browse/#svn/trunk/fallen-engine
some of the src includes the windowing with sdl/opengl and image handling but i have a question. right now i only have a rendering component and would love to have stull like collision system and animation system but how do you allow the components to communicate with eachother like if i have an animiation component and i want to update the rendering component to render the correct image… just a thought should i just inherit from the rendering component for the animation ………. WAIT dose this pull me back into the hierarchy oops well what do you think
Components have no code.
Therefore, they cannot “communicate” with each other.
A system that is operating on a component – say, an animation system – can operate on as many components as it needs to. It might take data from the animation components, use them to do some calculations,and write that data back into the rednering components.
(for instance)
thanks! that makes more sence ill work on it
[…] the same time I (once again) wanted to try to implement a component system, something like this one here. For this purpose I needed a unique ID for my classes derived from a generic Component class. These […]
Earlier you commented that you might release the source code. Have you given that any more thought?
@Nathan
Right now, I’m too busy – I got a new desktop recently, and the source is on my old desktop (which is now packed away ready for move to a new home).
I’ve got a new project I want to release before Xmas, which will use this ES, so I’ll have to dig it all out then anyway. But it won’t be for weeks / 1-2 months yet.
Hi adam,
I’ve read your posts and this article’s comments and I’ve got one question left:
You said that you pass a bunch of components to a system and the system then does its processing on them. Some systems (I guess many) might require more than one kind of components to do their work. So let’s say I’ve got a pretty simple rendering system. It just draws sprites at postions x,y.
So to do its work this system needs a bunch of Position components and Renderable components. So I pass those components over. But how does the system know which position to use for which sprite.
How do you solve this problem? Do you pass entities to the system so the system can take the components it needs to do its work or do your components have some sort of “belonging to entity”-reference?
Forgive me this stupid question but I’m rather new to the ES thinking and don’t want to bring over my OOP habits – so I rather ask :)
This comes down to whats avialable in your language, and what performance bounds youre working within
Lowest performance you can send a list of dictionaries: each dict has an entity id, and a key+value for each component.
By contrast, say if youre aiming for cache-efficient, in C derived languages, you can send an array of structs, wheere the method thatll do the processing knows how many structs to expect per entity, and theres no delimeters: it relies upon knowing that the stream is, eg, “8 bytes: entity id … Then struct1, then struct2, then repeat”
(thats a very network-programmer peerspective on it, for obvious reasons :))
[…] platform until we know the platform well ourselves. So, as well as writing some Android apps (e.g. the shoot-em-up I blogged about earlier this year), I switched from my iPhone to a new Nexus One as my personal phone. The plan was to use it daily […]
How would you handle a parent child relationship between entities?
for instance:
1) I have a ship and torpedos. when the ship dies I want the torpedos to die also.
2) I have one entity attached to another so when the physics run I want the parent to set the child’s properties.
There may be a better way, but … I usually just add an extra field that contains the numerical entity-ID of the parent (I always use an integer for my entity-ids – it makes data interchange simpler, although in theory you could use any struct/object/whatever).
One advantage is that it makes it transparently clear (when looking at an entire entity) where the dependencies are upon other entities.
NB: because you’ll be adding a field to a component, it also avoids namespace clashes. E.g. you can have a “torpedo.parententity” and a “physics.parententity”, and all is fine. No clashes, even though they’re serving similar purposes. NB: the purposes are similar but not identical – so, keeping them as separate namespaced vars is safer in the long run than trying to share them in e.g. a single reference.
Thanks for posting all these articles. I rewrote the bulk of my game using the entity pattern and i have to say once the entity manager was written it all went together ridiculously fast. The entity pattern works particularly well in javascript. I noticed that in some places my code was already headed in this direction but my ideas were nowhere near as coherent as yours ;)
I messed around early with trying to get the getEntities(component) function to return an ANDed array of entities based on a list components. That got kind of messy so I changed it to accept an array of entities to search through. I then realized that in all the cases I’ve fiddled with so far I didn’t need to get an ANDed array of entities. So for instance in the physics function I use the following pseudo code
entities = EM.getEntities(‘acceleration’);
for(entity in entities) {
acc = EM.getComponent(entity, ‘acceleration’);
vcc = EM.getComponent(entity, ‘velocity’);
if( vcc == null )
EM.addComponent(entitiy, ‘velocity’, {x:0, y:0});
}
I’m terrible at explaining myself so I hope that makes sense ;)
[…] T=Machine’s Entity System 1: Java/Android […]
alex, on your “not needing ANDed component queries”:
yeah, you could use that but your approach adds IMHO unnecessary logic to the straight forward data processor a system should be. all the filtering logic should have went into the query where you specify a subset of data you want to process.
on the topic of entity systems: I must confess that this design is really awesome. I’ve built a subset of components in the last few days and now I’m able to prototype games really, really fast. With the addition of lua it’s really a walk in the park to try out new game ideas.
[…] come to the conclusion that we want the engine to be component-based but do not want a full-fledged Entity System. Our main influence was Terrence Cohen’s Paper “A Dynamic Component Architecture for […]
I’m not a real game programmer so this might be just me being naive, but I still like an entity system that is based on type hierarchy (or rather: mix-ins / cake pattern).
Granted, I’m thinking about this in the context of Scala, which has mix-ins. I implemented the entity system for my last game project as explicitly based on subtyping so every Entity type (player, ball, paddle etc.) had it’s own class and mixed in any components that it needed (position, Box2D body support, state support, rendering etc.)
This system has some drawbacks, namely the update(delta: Int) method which is overriden in many different entity traits… you must not forget to call the super.update method when you override it and it may become hard to understand the call hierarchy when there are several supertypes for an entitiy and if the entity has multiple states.
That aside, I like my system so far, but I’ve read enough about component-oriented systems that I can’t just dismiss them. So my next experiment with this is a hybrid system where both mixin-based (code-driven) and composite (data-driven) entities can happily co-exist.
One would have to be implemented in terms of the other.
To rephrase the last paragraph of my previous comment, for my next game project I’m going to experiment with an entity system, which has both compile-time composition and run-time composition.
e.g. each Component is implemented as
1) a Trait that can be mixed into a compile-time composite entity class
2) a concrete Class extending the Trait, that can be added to a run-time composite entity object
My hope is that the compile-time composition is better for quick prototypes and for small games that don’t have full-featured level editors and are lead mainly by a programmer.
And the run-time composition is better for flexibility, large games, level editors etc.
I’m not yet sure how the EntityManagers/Subsystems will fit into this exactly, there are a few different ways to do it while supporting both the compile-time (mix-in) and run-time (composite) approaches.
This is really interesting stuff. I have been following these post with great interest and have implemented an Entity System of my own along these lines.
I am looking at how I can make my implementation more thread safe. For example my rendering, ai and input systems all I want to be on different threads.
One thing I thought is that the subsystem owns the list of components that it just cycles through but went against as I think its not correct that a subsystem will necessarily have a single primary component that it will read/write to unless its a very simple game. I am thinking about double buffering the data in the component in some nice way and allowing only one subsystem write access to the data.
Hi adam. Thanks for your articles.
If i understand the behaviours of a component is managed by a system. It’s that correct? So, for example, if we have a PhysicsComponent then it will contain only data such as: mass, inertia, velocity, etc.
Without methods of any kind? I mean, without an update() or other methods. Thus we would have an PhysicsSystem/manager/whatever who controls the behaviour, i.e via an update() method. I’m correct?
On the other side, about communication… You say that if components are pure data, there is no need to communicate them but, how about this case: if we have an ControllerComponent and a PhysicsComponent and we want to change the velocity in the Controllercomponent (let’s say with UP_key of the keyboard)… If the velocity is in the PhysicsComponent, how we change it? With a ControllerSystem accessing a PhysicsComponentList?
Thanks!
@rauru
Yep – have your system directly access whichever components it needs to.
This (unfettered access to all components) could be horrendous. In practice, it’s fine – Since you can pre-filter the components that are passed-in to a system on each update() tick, it’s easy to have simple but effective checks that make sure each system is only accessing the things you thought it would access.
(although that level of self-checking isn’t *required*, its usually very welcome in larger codebases, where it makes it much easier to see what’s going on)
@jeff
Why *those* systems on separate threads? For an MT CPU, those don’t sound like great choices – rendering and physics I would expect, *maybe* ai (but how complex is your AI, really?) … but input? on its own thread?
Short answer: yes, you can architect *your* chosen set of components so that only one system ever writes to one particular component (that’s usually quite easy), although you will likely get some strange artifacts (sometimes these will cause siginificant bugs – often they will just be momentary hiccups / cosmetic) if a different system reads from two components that are in different partially-updated-state.
Alternatively (probably my preferred route these days), thread safety is enforced at the “who is accessing the components of type X right now” level. This isn’t particularly difficult: you record which components (list of type + entity_id) were passed to which system, and then refuse to hand out those components again until that system returns from that method call.
(a system WILL only be accessing some-not-all component-types. In a larger game, it may also be only accessing a subset of the entities that have those components – although this *MIGHT* be a sign that one of your components should really be refactored into two (or more) components. i.e. if you’ve got a component “health” and you have two different ways you use the health, so that a system only reads one set of entities with health OR the other set of entities with health BUT NOT both … that suggests you should split it into two components)
i.e. it’s a batched lock/unlock semantic – and it works pretty well. It has the major advantage that you can automatically re-order (if you *really* need to) the calls to systems to achieve the “most efficient” use of your CPU cores.
…since you have enough information to calculate which calls are dependent upon each other, and which are not (although this does require some extra info from your own game-design to decide whether it’s “required” that e.g. “rendering always happens last, no matter what”. You’ll usually need to add a few manual rules like that…
I have a couple questions which I would be grateful if somebody could clarify for me.
1. Regarding the global defaultEntitySystem… the way this is implemented it looks like the first entity system/manager that’s created assumes this role. This could be any system then, the physics system, the rendering system, etc, depending on the order they’re created in, and it doesn’t matter? It seems like it would be more “symmetric” to have a special single instance that assumes this role, and then none of the specialized systems would have to.
2. I’m not very familiar with Java, so I’m not sure I understand what a HashMap<Class, HashMap> is. It’s a nested map (map of maps) which, given an entity id, gives you the map between component ids and component instances for that entity?
3. getNextAvailableID is declared as protected on the BaseEntitySystem, which means only the entity systems can generate new ids. The Entity constructor registers itself with the default manager, and inside registerEntity I assume the manager creates a new id and assigns it to that entity instance? Why then, does the Entity constructor take an id parameter, if nobody but an EntitySystem would be capable of generating one to begin with?
Thanks!
1. A subsystem would have a different base class; only (re-)implementations of the overarching ES would extend EntitySystem. NB: your question makes it clear that “EnitySysrem” is a poor name for this class! This setup is merely convenience so that you can instantiate an EntitySyatem instance an not even be aware of the global/sngleton references.
2. Hashmap is the academically correct name for a hashtable.
In this case, you give it an identifier for a “kind” of compoent, and it gives you back a set of all the components – oganized by entity – which exist of that kind. Iirc (I’m writig this reply on iPhone and cannot re-read the article at same time; wordpress has seemingly poor JavaScript which is killing iPhone performance)
3. This is poor design on my part – the knowledge that i will almost certainly want a feature in future where I can serialized and deserialize an entity, and I would LIKE to deserialize it with the same entity Id it originally had.
This method signature makes it easy to add that feature.
(although IMHO there are better ways of providing that functionality and/or actually I think it’s a stupid feature and I would prefer never to implemnt it)
In reality, I shouldn’t have jumped the gun like that. In my defence, I genuinely expected to add that feature in this iteration, but never got around to it :).
I see, so there’s really only one EntitySystem in the game. Specialized sub-systems are implemented completely independently of each other (and of the BaseEntitySystem). All they have in common is that they operate on Entities and Components?
Anyway thanks for the quick reply. These posts are very interesting.
I think its best to leave out the term component in Entity System. Entity System is 2 items, Entity and System. The entity itself should not contain id but the properties of an object. For instance, PositionEntity possesses x and y coordinates. The system is basically behaviors that acts upon the entity such as manipulating the properties of the entity. So this is more like a MVC structure where M (Model) is the entities, C (Controller) are the ones who manipulate these entities. No behaviors in Model (no getter/setter/methods)
This is a great article. I’ve read this along with your five part article on entity systems in MMOs.
I’m curious though, what is the purpose of calling registerEntity() in the EntityManager? Is it to maintain a list of Entity’s somewhere, kept within the EntityManager?
@eses
You seem to be missing the point of an ES: an entity/thing/gameobject is composed of many different lumps, e.g. a lump for “position”. The position is not itself a thing/entity/gameobject – it is merely one aspect of it.
It would be much better to say e.g. PositionAspect than to say PositionEntity.
(except “aspect” has specific meanining thanks to AOP)
@Brad
Yep – IIRC I mostly used this just for debugging: I could print out a list of all entities on-demand, and maintain a “kill list” of entities that had been deleted (but internally I kept them cached for a while, to help with debugging) etc.
Nice.
Regarding assemblages, what’s a clean way to implement them in Java?
I was thinking having a base Assemblage interface with a create() method that returns an id/entity.
Next I’d implement a separate class for each Assemblage I require.
Lastly I’d probably end up making an AssemblageManager of some sort, with a similar format to your EntityManager.
Does this sound appropriate?
I highly recommend NOT using a class for each assemblage – that poisons your system with lots of classes you don’t actually want.
Rather, I’d implement a single Assemblage class, that is data-driven.
i.e. it has a method “createFromFile( File )” or “createFromProperties( Properties )” or “createFromXML( String )” or similar, that reads in a list of components (and maybe default values for those components’ variables) and presents an Assemblage object.
You’ll have many different instances of this class, each one representing a separate instantiable Entity+Components.
But only one class – very little typing / maintenance / etc, and keeps you safely away from being stuck with OOP
I have a couple of implementation questions about your entity system that I haven’t been able to work out myself. I currently work at a game studio who is considering moving to a component system after working in a OOP system with a fairly deep hierarchy for a long time.
I like splitting up the data (component) from the logic (entity system) however I’m having trouble working out how a trigger system would work in this architecture. I need to be able to define a shape (Axis Aligned box), some flags (PlayerIsOnGround), and then be able to hook other entities into this trigger to know when an object enters or exits this trigger and respond accordingly.
From what I’m reading, I need to have an Trigger Component which contains the shape, the flags, and a list of current inhabitants. I can write a Trigger System which takes trigger components, checks to see if any collidable components are inside of the trigger volumes and adds them as well as making sure all current inhabitants are still valid inhabitants.
The problem I run into is building the messaging structure. When some object enters my volume, I want AI to spawn or an explosion to occur. How would you go about hooking this messaging structure up in data and code using your ES?
Thank you!
Trigger-based logic is incompatible with ES logic – it’s an event-driven paradigm, where ES uses a clock-driven paradigm.
However … fundamentally, that statement is true of 99% of game development – it’s very rare to see a true edge-triggered game, and yet designers talk about it all the time, and developers often pretend their systems are edge-triggered when they’re not.
ES doesn’t mandate that you do this – you could build an edge-triggered logic into your game, it’ll just lead to a really big opaque blackbox which the ES doesn’t interfere with. But for a lot of cases, it’s much more efficeint to do clocked/batched logic (makes it easier to optimize for performance, caching, streaming, etc)
I’m sure you know this, but for anyone new to this: you can convert from events > clock by the age-old trick of generating a list of “events that happened since the last clock-tick”, and making a system/sub-system that analyses that list each clock-tick, and makes the appropriate “reactive” function calls. However, you have to be careful about the content of those function calls – they shouldn’t be written as event-triggered logic (e.g. they shouldn’t make nested calls to other objects, that react, and re-react, etc – INSTEAD they should be doing just one clock-cycle of work, and generating any new “events” as items that go onto the master list for NEXT clock-tick).
…theory aside… things to note:
– that “list of events since last clock-tick” does NOT need to appear anywhere in the ES – it’s an implemetation detail of one of your Systems. Your systems *can* hold data that does not appear in the ES; the ES is purely for holding game-data – it’s not a replacement for using “variables” in your programming language.
– USUALLY, I end up splitting the CD system into 2 or more systems: one system that purely handles “detecting and classifying collisions”, and other systems that handle “reacting to collisions”. The first part can be written purely accessing position + velocity components – it will generate “fake” collisions for things in your game that can legitimately pass-through each other (or you can make it more advanced, by also accessing other components to filter the collisions better). The latter parts contain more and more game-specific specialization
…but honestly, I have no “best practice” suggestoins for how to do CD in an ES. It needs a lot more people to discuss it, really, and to come to some recommednations/conclusions.
[…] (this is a simplified, but complete, version of the “Entity System 1: Java/Android”) […]
[…] Entity System on Android phones – a concrete example using Java […]
I would like to ask if it’s possible to take a peek at your implementation of space invaders game?
I’m trying to use your ES approach to write Tetris (as an exercise for myself) but I’m having problems designing the right components and systems corresponding to each other. I could elaborate but i think a peek at the code would be much more beneficial.
Follow the link two comments before yours
@adam
I actually saw the ES in Objective-C that you made available, but what I was curios about what components you use in your game and how are they used in systems (like Graphics, CollisionDetection etc.)- thats why I’m actually curious how you use it rather how it’s constructed.
Thanks for your articles Adam. But i have a couple of questions about the entity system.
For example, in your design you need a “System” for every component, because there’s a 1:1 relationship. So, the question is clear: if you have 250 components you need 250 systems? In that case, the “gameloop” is going to be a big one because your are going to call 250 systems!!!
About the other question, what about the “states” (attack, jumping, idle, active, etc..) of an entity. Are components? Or there is a “State” component (so we only need 1 system) ?
The 1:1 is a guideline, really aimed at getting you going in the right direction.
Ultimately, on a medium to large project, you’ll have multiple components per system – but you should be generally starting from 1:1 and only increasing that as and when you need to. 250 components is insanely many for most projects.
You would only need a single state component (although in some cases you might want to do it the other way, it would be very unusual)
The articles are great. I am looking forward for the next article.
Can you expand the networking approach? I am very curious about the communication between client and server. I want to do an implementation of the client-server framework.
While trying to get components from the HashMap I get null because the key of the HashMap is an Entity.
I make a new Entity;
Entity e = new Entity(es.getNextAvailableID());
I add the Position component
es.addComponent(e, new Position());
I am making a PositionSystem containing:
public void doSomethingWithAnEntity( int globalId )
{
Entity e = entitySystem.get( globalId ); // on this line the Entity reference changes
…
}
Then I call public T getComponent(Entity e, Class exampleClass)
and the “result” is null because the key of the HashMap is the Entity reference which is changed when I’m trying to doSomethingWithAnEntity( int globalId );
How should I deal with this? what’s the most logical approach?
Should I change to HashMap<Class, HashMap> ?
where Integer would be the globalID
Best regards,
Alex