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”
Well, not exactly what I wanted to hear, but thanks for the reply! I guess for the time being I’ll try asking around like you suggest, and continue hammering together code until it “clicks”… I plan on getting this game finished one way or another, so if I have to rewrite it a few times at least I’ll learn how *not* to write it.
Anyway, thanks again!
The C++ skeleton of an Entity System at http://entity-systems.wikidot.com/ really does scale up to a small game (in my hobby playing-around). It needs a couple more convenience functions, like removing components from an entity. It uses some of the antipatterns Adam disparages, like having the Entity hold a map of its components, but I think when you hit performance problems with it it wouldn’t be hard to factor them out.
If you can’t see a way to do a wonderfully elegant template metaprogramming monster … please instead follow the “Entity System Beta” (described on this blog ans on http://entity-systems.wikidot.com/rdbms-beta ) – it’s been ported to several langs, but not C++ yet. It would be great to get a clean port of that.
(it’s “good enough” for prototyping – I’ve had it running 100’s of game entities at 30 FPS on old Android phones)
hi i would like to ask the following.
can a component be an entity ?
Ex. i have an rpg game :
Entity unit : has component Attack.
Entity Attack : has component damage ( damageType, damageAmount).
has component canMiss (miss chance).
has component canCrit (crit chance).
Is this the correct way to model it ?
isn’t this considered linking ?
Previous discussion:
MIkeD August 4th, 2010 at 7:29 pm
————————————————–
You are saying that linking two components as a configuration/data is the poison?
adam August 5th, 2010 at 12:28 pm
————————————————–
This is why you have “entities” in an ES – to link instances of components together.
me:
————————————————–
Ok so in the above question,
Attack is both an entity and both an component.
It is an entity because it contains subcomponents (many).
It is a component because it is contained by unit.
Note that in warcraft 3 units can have more than 1 attack,
for example chimera’s had lighitng bolt autoattack and poison bolt autoattack.
So how do you model that in your entity system.
“attack is both…” – no, it is not. You claimed it was, for no apparent reason. Why did you do this? You give no explanation for this “Entity Attack” – it serves no obvious purpose.
Let me explain,
I need to make my component have the ability to contain other components.
Else a component will be a huge monolithic object (code bloat / god object), containing 32 variables, some of which may not even be used.
Example:
Some attacks have splash component. Splash component makes attack deal area of effect damage to all nearby enemies.
Therefore Attack Component should have splash component
To summarize:
I am taking this example from warcraft 3 editor.
Enity Unit has Attack.
Attack
{
damage,
attack_type,
has component splash
}
Spash
{
allowed_targets { humanoid, giants, buildings },
aoe_range,
max_number_of_targets e.g 3
}
1) You don’t consider attack as a entity ? it contains components.
Its an aggregation relation, an attack has a splash. Some attacks e.g archer’s bows don’t splash and deal damage to only 1 target.
Maybe its a different type of aggregation, this is “inlined” and doesn’t have to ask the entity manager for “help”.
32 variables is barely 10 lines of code; that is NOT a monolithic object!
Even if you had 100 variables, it wouldn’t be something to worry about (except that: with 100 variables in a single component … you’d have to ask … did I make a mistake in my design?)
If you have “too many variables”, then … add more components.
In your example, you have listed:
“BasicAttack” component
“SplashAttack” component
Why would you “contain other components”? I think you should re-read the main Entity Systems articles, it sounds like you’ve missed the point completely, I’m afraid. The whole point is to have “many components on each entity” – you have listed no reason why these should not be two separate components that go on one single entity.
@CommentGuy – since you keep entering a series of fake spam email addresses, this page has started to attract spammers – and WordPress can’t tell the difference between you and them.
You didn’t really think before posting, you don’t seem to have read the articles, and because you can’t be bothered to type a single email address you’re bringing spam onto a page that was 100% spam free beforehand.
I don’t have time for this. All your comments are now being DELETED AS SPAM. If you choose to post under your actual email address, go ahead – I’ll approve it. Until then, go away.
Hi Adam, wonderful series of articles. Was especially happy to see this one after having read all the others, as it answered – or the discussions in the comments answered – a good deal of the outstanding questions I had wrt performance in this sort of context.
Seems that there will be a little more research for me to do before diving further into this, for example I’ll have to give a little more thought to how systems organise themselves concurrently so as to access / update data in order without interrupting each other. For example I have already separated out logic and rendering threads such that they only block during a small and well optimised buffering operation, and the renderer interpolates any data it needs to such that logic can operate at a frequency independent of a devices refresh rate, without compromising smooth animation.
I feel like this sort of capacity for cooperation should be generalised and made a part of whatever meta-system is in charge of organising systems, though for the most part I suppose systems would just do their thing on the same logic tick, with only a couple needing to be partially ordered if they were operating on the same components sequentially.
Have you got any thoughts on this? Am I over thinking it? After writing that I feel like I am forming an idea of how this could be achieved, so unless you or anyone else pulls me up on some great misunderstanding I’ll procede with cautious optimism. Perhaps I also need to re-read the articles, but I don’t remember you talking much about the issue of inter-system organisation.
Anyways, I also am surprised that nobody mentioned this in two years (I only read about half the comments, but the article hasn’t been updated), but I think the following is what you were looking for earlier:
public T getComponent( Entity e,
Class exampleClass )
rather than:
public T getComponent( Entity e,
Class exampleClass )
Nice and simple! You don’t need to – and indeed it doesn’t make sense to – qualify T with ‘extends Component’ when parametrising Class, as T has already been defined as being upper bounded by Component. This feels right off the top of my head, but I feel a little uneasy in correcting someone who wrote such a high quality article… At any rate, even if this is a valid suggestions I do understand you aren’t exactly actively developing this, but perhaps it could be helpful to other readers :).
I plan on writing up a few articles on my experiences with this if they are successful. I presume you won’t mind if I link to this as required reading? I will let you know, of course, if I ever do this.
Cheers,
Eli
Oh poop! It seems my generics may have been filtered out as tags. Please feel free to delete this post and edit in the correction if necessary, and if you can be bothered :).
*
public <T extends Component> T getComponent( Entity e,
Class<T> exampleClass )
rather than:
public <T extends Component> T getComponent( Entity e,
Class<T extends Component> exampleClass )
One last thing, I am a little confused about to what degree components can (or should be able to) share data. I’m only talking about the sort of sharing which would be opaque to the components interfaces, and to any systems which required these components, and in particular the sharing between multiple ‘instances’ of the same component.
For example, rather than using something like a scene graph, each ‘renderable’ component would have its position stored as a potentially complex transformation compositions, where transformations and their compositions are lazily evaluated expressions. This means that a lot of processing can be avoided by having renderables share sub expressions for transformations, and we actually end up with a more flexible and potentially more optimised system than a scene graph, without each node actually having to know about and reference parent nodes explicitly.
I feel like this does nicely solve the problem of having to traverse a scene graph as a pre-rendering step, as was mentioned in response to a previous commenter – as all we need to do is rely on the lazy evaluation to make sure we get the same (or better) benefits of sharing transformation calculations between nodes. Order of evaluation is not important. I also have a clear idea of which parts of these complex transformation hierarchies actually need to be exposed to other systems: there will be certain bufferable properties typically, for example, ‘angle’ or ‘position’ whose current and previous values will be exposed to the outside world for scripting or modification by a physics system and such, and which will be then buffered and interpolated between by the rendering system.
Is it bad to have data shared in complicated ways like this between more than one ‘renderable’ component?
Sorry for asking so many long questions, but I am worried about jumping into implementing this further without a really good understanding of what I’m doing.
I think Mike Leahy and one or two others have done things with sharing data between components
The problem is that it (typically) blows away cache performance benefits, by moving from a pure data stream to something
more nuanced.
Thats not a concern for most people of course – until they get to a point where theyre already more than comfortable solving it anyway. And its not insurmountable.
So … Feel free to do it foryour own projects
Cheers Adam. Given, then, that there is no fundamental issues with this approach other than performance difficulties, I’m fairly confident in moving forward with it.
I’ll re-read the orginal series of articles – and perhaps do a little more research – before thinking more about a generalised mechanism for organising inter-system execution orderings and dependencies.
Oh, and thanks again for taking the time to write these articles and reply to comments :).
Hey Adam, I was trying to implement a small TD last year (im a student 5.semester now) but got stuck somewhere since i didn’t have any desing concept :)
So I found this site and it looks pretty interesting and want to try it again with an ES. Actually I already started with it and I’ve got some question about the systems and how they know about the entities which to process.
I had several ideas about how to do that but Im not quite sure if they are good ones, so maybe you can tell what are advantages/disadvantages of these approchements?
1) For the component types there will be a class which has an unique id of each component:
public class ComponentTypesIdentifier {
public static long POSITION = 0x001;
public static long VELOCITY = 0x010;
public static long SPRITE = 0x100;
}
You would have to add each component by yourself (which I think isn’t that much effort).
Now in this approchement an entity would also have a long field ‘components’ and every time a component is added to the entity it will look in the class above and add the specific value to this field.
Then in each system you specify which component are allowed and calculate with the class above the sum of these components. Now you can easily find out which entities belong to a system by xor/and however you want to do it.
You said somewhere that an entity is just an integer an shouldnt know about its components right? So I’m not sure if I should just drop this idea (but I also dont see why this would be bad).
2)Haven’t thought this much about it yet but the idea was that whenever an entity is created and components are added/removed, they check which systems they satisfy and then register themself for the specific systems.
I hope you can understand what I mean :)
Cheers, Jan
If you’re *only* using this to improve performance of component-fetch / lookup / add / remove … That works fine.
The issue would be if you’re using it for design / features.
Hey Adam,
I got some other questions. First off all: Is it a bad idea to youse an ES for an AgeOfEmpires clone?
Because it seems kinda difficult to keep entities only an integer. I thought abit about the functionallity of AOE and for example if you double click a unit, all other units of the same “type” are also selected. So surely one can add a Component for this, but a field for each entity to know what it is would also be possible. Then again there isn’t a problem using MetaEntity if performance is not a problem.
So could you maybe state when are MetaEntity bad (I mean like for MMORP one maybe needs >50k entities and for aoe <10k but I dont know when performance issues will occur with MetaEntity).
Other questions:
1)Is it ok to use objects for special entities like the map (2D) and the gui? So for now I got a WORLD class which extends ENTITYMANAGER and i thought i handle the map seperate in the world class instead of with the entitymanager.
2)For the input I just implemented a INPUTSYSTEM which checks which button was pressed and then gets all entities which are involved. So in the end this will be a very big Switch or if/else part… Is there a better way to do this?
(I search pretty long to find answers to that but there were just to many ideas so i though maybe ill ask you since you seem to know what you are talking about^^)
Cheers and thank you in advance,
Jan
PS: also thanks for the fast answer last time :)
” ES for an AgeOfEmpires clone?”
Yes, it’s very good for that.
“it seems kinda difficult to keep entities only an integer”
No, it’s very easy. If you think it’s difficult, you should stop and re-think, and make sure you understand the entity system properly. You should find it EASIER to do this with components (leaving the “entity” as a pure integer).
Hey Adam,
i’ve got some more questions :)
I’m really unsure about these things beacause I’m nnot sure if i don’t understand some fundamental stuff of ES.
1)How often are the methods addCompontent/removeComponent used (not in the creation of an entity)? (all the time or just a few times)
I ask this since the following question are based on this.
2)An entity can play different sounds but I don’t know how i should manage them (same for different movements).
– One sound component which holds all sounds the enitity can play and an field which says which sound should be played.
– For each sound a seperate component which is added as soon as it should be played and is removed if it has been played (for example when the unit shoots)
– If you have an attack sound is it better to ‘save’ the sound in the attack component?
3) How should I implement the selection of a unit:
– SelectableComponent with an boolean field which says if its selected or add a isSelectedComponent as sson as the entity is selected and will be removed if its unselected?
4)Is it possible that all entity posses the same component like a PositionComponent?
I changed the entites now back into integers only. Before I had an field for the bitValues of all components an entity possess for efficient look up. This restricted my total number of different components to 64 (long value) what was quite annoying.
5) How would you search for entities which possess more than 1 components (let’s say components x,y and z) in an efficient way? (add a component bitValueComponent instead of the field i used? or take all entities of each component and search in the one with the least entries)
6)Is there a way to bypass this restriction of 64 components and still have good performance for look up?
big thanks in advance,
Jan
“Sound” is an interesting one.
For simple examples, you might think of sounds as “one-off events”. But for most games, sounds are simply a form of Animation: they have a timeline, a current time-offset, a state (playing/paused/etc), and triggers for “do stuff as soon as it finishes”.
e.g. when you pause the game, you want your explosion sound effect to pause, right? Because when you un-pause it, you want the animation + sound to resume from where they were.
Given that animations *always* need complex state, unless you have a very very simple game … you can expect to have at least one component dedicated to them, maybe several.
(e.g. you could have a general “Animatable” component which stores stuff like “duration, starttime, currenttime, etc” … and a “VisualAnimation” which has info for animating the graphics (uses the Animatable to handle the core animation stuff), and an “AuralAnimation” that has info for playing the sound(s).
re: “SelectableComponent” – depends entirely on your game. If you have lots of things selected at once, it might help your code to have BOTH (so you can easily check “what’s selectable” and also easily check “what’s currently selected”).
If you only select one thing at once, then a SelectableComponent is probably enough, and you simply store the “current selected unit” inside the System that deals with mouseclicks and selection etc.
I just thought I’d chime in on your EntitySystemSimple class where you wanted your getComponent method signature to be this:
public T getComponent( Entity e, Class exampleClass )
well you weren’t too far off. I got it to work (read not give compile errors) like this:
public class EntitySystemSimple extends BaseEntitySystem
{
//note that even the Class object is too. May as well enforce that
HashMap< Class, HashMap > componentStores;
//you only have to write “T extends Component” once at the beginning
//all the other T’s in the method refer to it, including in the parameter list
public T getComponent( Entity e, Class exampleClass )
{
//The rest of the code is the same as how you originally wrote it
HashMap 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;
}
…
}
a call to the getComponent method now enforces that the Class you give it is a subclass from Component like you wanted. I hope that helped.
it didn’t post all the code properly :( let’s try one more time…
public class EntitySystemSimple extends BaseEntitySystem
{
//note that even the Class object is too. May as well enforce that
HashMap< Class , HashMap > componentStores;
//you only have to write “T extends Component” once at the beginning
//all the other T’s in the method refer to it, including in the parameter list
public T getComponent( Entity e, Class exampleClass )
{
HashMap 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;
}
}
… sorry I guess it didn’t work post all the
? extends Component
T extends Component
and T
Updated post with – I think – the correct signatures.
Also: re-written to take advantage of a new plugin I installed that makes code-in-posts MUCH more readable!
Hi Adam,
I have a question regarding on-off actions aka events. I know you already answered in other post that it is an orthogonal topic but in one of your previous ES articles you actually suggest a non-event based solution – temporary (single-frame) components. You suggested that when physics system detects a collision (a collision event occurs) it attaches say CollisionInfoComponent to the Entity. Other systems can then check for this component and act accordingly.
Q1: Would you use this technique also to play a collision sound? I mean, would SoundSystem iterate over CollisionInfoComponent array and play sounds according to attached collision information.
Q2: Are “temporary” components a proper part of ES or is it more of a hack? I mean it is understandable that an Entity -has- a location in the world it also -has- health, it does not -have- collision tho.
Great series. Please don’t stop ;)
[…] go back to business. This awesome post describes skeleton implementation of ES in Java. I recommend you to to read that, as a base for my […]