EntityMonkey, a simple Entity System for JME

I have some also:



http://slick.cokeandcode.com/wiki/doku.php?id=entity_tutorial



Entity Systems are the future of MMOG development – Part 1 – T-machine.org



http://www.richardlord.net/blog/what-is-an-entity-framework



http://www.richardlord.net/blog/why-use-an-entity-framework



http://www.altdevblogaday.com/2011/08/24/the-game-entity-–-part-iv-game-systems/

After refactoring and changing the system to ‘valid’ EntitySystem i have one more question, is communication between EntitySystems allowed?

I am asking because i found a big bottleneck using

[java]rootNode.getChild(Entity.getUuid());[/java]

If communication between Systems is allowed introducing a EntityToNodeMapperSystem would be valid.



The performance increases by the faktor of 10 by using a the MapperSystem…



The EntitySystem is currently running 10000 randomly moving entitys at 57 FPS in SingleThreaded and 127FPS in MultiThreaded Mode…

4 Systems and 7 Components per Entity

Yes, systems/controls can communicate between themselves, and that’s a good way to do that. For example, let’s say you have a Model system, that controls spatials on the screen, how they are rendered, and their position (99% done by the engine). You could create a way for other systems to add objects to the scene graph through this Model system, and that Model system should be the only one who would store a Map<EntityID,Spatial> for your game. Whenever a system needs the spatial, just grab from the Model system.

@zzuegg said:
After refactoring and changing the system to 'valid' EntitySystem i have one more question, is communication between EntitySystems allowed?
I am asking because i found a big bottleneck using
[java]rootNode.getChild(Entity.getUuid());[/java]

An entity system doesn't need to concentrate on Interfaces / globalizations on the *system* side, that isn't really part of the entity system. Idk what you mean by communication but you definitely don't have to work with entities all the time, its just what connects the systems and what they "talk about".
The rootNode having to grab the entities UUID looks wrong though, somethings inside out there. Look at my example, it contains the full entity system already basically. The spatial needs to know nothing but what Entity it represents, after that its all handled by the Control based on the info of the Entity. If it has to store info that is available through the entity somethings flawed.
@normen said:
An entity system doesn't need to concentrate on Interfaces / globalizations on the *system* side, that isn't really part of the entity system. Idk what you mean by communication but you definitely don't have to work with entities all the time, its just what connects the systems and what they "talk about".
The rootNode having to grab the entities UUID looks wrong though, somethings inside out there. Look at my example, the spatial needs to know nothing but what Entity it represents, after that its all handled by the Control based on the info of the Entity. If it has to store info that is available through the entity somethings flawed.


I get what you mean. Instead of updateing the spatial's position from a EntitySystem i should use a control which gets the position from a EntityComponent. This would eliminate the need of a MapperSystem.

Yes. Note that the Control is a System too, anything thats not a Component or an Entity(ID) in an ES is automatically a System.

Just to remember that’s an option, you can do both. A jME Control in this case applies to a single spatial, so it’s a system for 1 spatial only. You can create a system to handle multiple spatials at once, and for that you would need a map. That’s all choices you need to do. If you prefer to each spatial to have their own control (system), do it.

What would be the point of an entity system if you wouldn’t want to display one model per entity somehow? :wink: But sure, a whole city should probably be handled by an AppState that grabs all entities with the HouseComponent so it can care for batching and other optimization. Though a Control on a RootNode could handle that too…

@normen said:
What would be the point of an entity system if you wouldn't want to display one model per entity somehow? ;) But sure, a whole city should probably be handled by an AppState that grabs all entities with the HouseComponent so it can care for batching and other optimization. Though a Control on a RootNode could handle that too..


Just design decisions in my opnion.

As in my case I have created an event system with triggers, I prefer to work with 1 system instance per bhavior to all entities. They combine pretty well togheter. Although I could change this to work with the other approach, I prefer not =]

Hm I mostly found event systems in games dangerous, thats why jME also doesn’t use event-based loops but does checks on every cycle. They can cause sudden overhead while running smoothly under normal circumstances. Also the entity system is already a messaging system as I said, setting a Component on an Entity is kind of the “Event” just that it can be evaluated on another thread and doesn’t have to be carried around to everybody on one thread like in an event based system.

Just to clarify something:



An entity system consists of two things:

Components and Entities.

Ofc you need some kind of EntityManager that maps Components to entities and is able to get entities based on required components.

That is the whole ES. Basically you can do that with two (2) Java classes.



Anything else is already part of your program that uses the ES. A “system” in any kind does simply not exist in an ES. A “system” can be anything. it could be an AppState. It can be a control. It can be something that runs on a seperate thread. You can even use physics and use some kind of “system” to get the data computed by (j)bullet back into your components.



“systems” itself should be self-contained. When you remove one system. all other systems should continue to work properly. System do ONLY communicate over the components / by manipulating components.



There are two ways i see to design this:

Either you have a system that processes all entites with a “RenderComponent” (or whatever component is necessary for you to display something), that maps spatials to entity IDs and updates that whole thing, or, you have the same system, but only register which entities have gotten the component that were not handled before, ceate a spatial, attach a control to it and let that do the rest. The control should then ofc detach the spatial when the component gets removed.



The second approach has the disadvantage that the control is updated on the render thread, while, when you use the first approach, you can run it on a different thread. But it also has the advantage that you do not need a mapper system. You’ll have to figure out yourself what works better.



personally, i prefer “systems” that process all entities with component ‘X’ and update them. Imho that makes refactoring VERY easy. You can have one package with all your system classes and just add / remove systems at will and have a very good overview over your systems.

I did some benchmarking and i have to say that you core devs did a great job with the updateloop.



Testscenario: 10000 batched boxes, Random movement which changes at random time.

Test a) ES-SingleThreaded, Updates on the Renderthread take 20ms → 23FPS

Test b) ES-MultiThreaded, Updates on the Renderthread take 9ms → 27FPS

Test c) NO-ES, but logic is in a simple Control… → 43 FPS



Since i the above measured 9ms is all i do on the updateloop i can’t think of any overhead which could cause such a big difference. But based on the difference in FPS between 20ms and 9ms ‘updatetime’ there has to be some kind of overhead im am overseeing…

@normen said:
Hm I mostly found event systems in games dangerous, thats why jME also doesn't use event-based loops but does checks on every cycle. They can cause sudden overhead while running smoothly under normal circumstances. Also the entity system is already a messaging system as I said, setting a Component on an Entity is kind of the "Event" just that it can be evaluated on another thread and doesn't have to be carried around to everybody on one thread like in an event based system.


Yes, this is true, but I prefer to have events firing and being carried over adding/removing components. For example, whenever an unit try to attack, we check if it can attack. If it's able, then I'll fire the attack event, and any trigger that listens to it can take an action. In this case, both an attack and an animation system can listen to it to make the desired processing. And, as a bonus, I can add another trigger whenever I want to add extra logic without the need of re-compile, if I put it as a script. That's my goal =]

But as said, you kind of make having an ES futile if you don’t use it for messaging… Thats exactly what its there for. If the entity has a weaponComponent and an attackCommandComponent or w/e then it attacks… No need to send any “event”, its just setting the right components. I agree to what @polygnome said and my example pretty much does exactly that and implements the whole entity system already. There isn’t more to it.

@shirkit said:
Yes, this is true, but I prefer to have events firing and being carried over adding/removing components. For example, whenever an unit try to attack, we check if it can attack. If it's able, then I'll fire the attack event, and any trigger that listens to it can take an action. In this case, both an attack and an animation system can listen to it to make the desired processing. And, as a bonus, I can add another trigger whenever I want to add extra logic without the need of re-compile, if I put it as a script. That's my goal =]

Why don't you just add an "StartAttack" component? That way every "system" that has to do some kind of processing could see "oh, there's a new entity with that component, let's process it".

If you used @normen 's approach and used a control on the proper spatial, the control would see the the new component, start the animation, and process the outcome of the attack (or relay that to an "CombatManager" or else) and then remove the component when it is not longer needed.

Really, you already have a data-driven solution, why going through the trouble and add an event-based solution on top of that?
1 Like
@polygnome said:
Why don't you just add an "StartAttack" component? That way every "system" that has to do some kind of processing could see "oh, there's a new entity with that component, let's process it".

If you used @normen 's approach and used a control on the proper spatial, the control would see the the new component, start the animation, and process the outcome of the attack (or relay that to an "CombatManager" or else) and then remove the component when it is not longer needed.

Really, you already have a data-driven solution, why going through the trouble and add an event-based solution on top of that?


To allow new content to be delivered through a scripting interface. I want to allow new content to be easily added by anyone, in a friendly interface. I don't have a better idea to do this besides this.
@shirkit said:
To allow new content to be delivered through a scripting interface. I want to allow new content to be easily added by anyone, in a friendly interface. I don't have a better idea to do this besides this.

Why wouldn't it be possible to add a "system" that does what you want via a scripting interface? What's the difference between adding an event listener via a scripting interface or adding an "system" that processes entities?

You could still add a system that queries all entities with the startAttack component and processes them, e.g. starts the animation. When the animation already runs, you don#t need to start it, do you?
You just need to make sure the component is removed properly.
1 Like
@polygnome said:
Why wouldn't it be possible to add a "system" that does what you want via a scripting interface? What's the difference between adding an event listener via a scripting interface or adding an "system" that processes entities?

You could still add a system that queries all entities with the startAttack component and processes them, e.g. starts the animation. When the animation already runs, you don#t need to start it, do you?
You just need to make sure the component is removed properly.


That way only in the next frame I would process the attack, but that would work also. And with that I would shrink my code to work with just 1 type of system, instead of two. Attractive. This makes more sense then the way I'm currently doing, I shall probally change that. Thank you @normen and @polygnome

You can still have callbacks in the scripting system if that fits better there but you also don’t have them “the next frame” necessarily, using an entity system as described you can easily have the other logic on another thread. If the component is set it reacts and the other systems react to components it sets… That can be a frame later or instant… If you are that far there is few need for anything but the rendering-related operations to run on the update loop. That doesn’t mean it doesn’t make sense for some stuff just that its not required per se. For example physics should definitely be implemented with the base PhysicsRigidBody etc. objects instead of the PhysicsControl extensions and have the physics thread run completely separate, only setting the results on objects that are in “free fall” or otherwise physics enabled.

@shirkit said:
That way only in the next frame I would process the attack,

Nah, that's imprecise. You'd process it the next time your "system" is updated. If you update your system from the update loop, then sure, it is only updated on the next frame. But you don't have to update it from the render thread. You can use a multitude of threads. You might for example have a network thread that updates your ES, a thread for physics, one for AI, and maybe one or more threads from a thread pool that process a bunch of other systems which update for ES.

. And with that I would shrink my code to work with just 1 type of system, instead of two.

Why would you? It can still be in two systems. You just need to think about when to attach what component, when to process which component and when to detach it.
1 Like