EntitySystem: How to represent entities in the SceneGraph

@shirkit said:
Well @pspeed , as @polygnome , I don't see any other option. I store the Spatial so the I can play animations, change material definitions, add objects to the object's node (healthbar). I don't see any other option to do that besides this :/ I thought this at the start of using Artemis in my game, and this was the best solution I could think of. It may be still wrong, but this is the "wrongless" I can thought of.


You described a bunch of potential components that should be applied to a spatial as a reason to put a spatial into a component.

I'm not sure why you need to do that. In the worst case, your system could have a Map that maps entity Ids to spatial... but at least it would give you the flexibility of having different systems with different Spatials representing the same entity. When you stick the system in the component, you lose all of the flexibility and make your life ultimately harder down the road.

I have a few controls that work this way. They manage a [java]Map<EntityId,Spatial>[/java] of children for the control's spatial.

The way I do this is this: Theres a System (AppState) that checks for Entities that have a VisualRepComponent (which stores the model name) but no InSceneComponent (which is just a bool basically) and then loads the model and attaches a special jME Control that gets a link to the entity (and then adds the InSceneComponent ofc). From then on the Control handles everything. It moves the spatial around based on the LocationComponent and MovementComponent and plays the appropriate animations. It even reloads or completely removes the spatial (and itself) from the scene when the VisualRepComponent changes or is removed. Remember what paul said that its always wrong to have system-specific data in a component (e.g. Spatials), it should always be generic data. Hence if you feel like you need system-specific data in your Components something is backwards in your logic. The point of an entity system is that systems do not need any other connection than the enities and their component data. Thus the Control and the Spatial don’t even need to be in a list of some other system, all communication happens via the entity components.

@pspeed said: In the worst case, your system could have a Map that maps entity Ids to spatial...

Funny, when i read your first post i immediately thought about that, too.

So basically i would just have a marker component that marks the entity as some kind of visible entity (there are several components that might have a position, but no visual rep, e.g. waypoint for NPCs) and holds some metadata that can be used in a system to construct some kind of visual rep based on the requirements of the system (model for 3d , some "flat" rep for a minimap, or something entirely different).

In my system i could then map the entities to their visual representation. But then again, mapping an entity (= an ID) to something else (a component) is what the whole ES basically does :S That's why i initially considered adding a component that holds the spatial.
But then again you are correct, a spatial is much more then just data. It doesn't really fit there.

From then on the Control handles everything. It moves the spatial around based on the LocationComponent and MovementComponent and plays the appropriate animations

I'm curios: Why would you need a control to calculate the movement? Why don't you use a system to process all entities that have both MovementComponent and LocationComponent and just use a Control on the spatial that just updates the location (and maybe rotates it for the correct direction).


Thanks for your input guys. This is exactly the kind of feedback i hoped for!
@polygnome said:
I'm curios: Why would you need a control to calculate the movement? Why don't you use a system to process all entities that have both MovementComponent and LocationComponent and just use a Control on the spatial that just updates the location (and maybe rotates it for the correct direction).


Remember... "system" is a concept and not a formal thing. All of the controls are technically parts of the "system".

This is why I immediately distrust ES toolkits that put any emphasis on a "system" interface or framework. It's a waste of space and a sign that they view the ES incorrectly.
1 Like

@polygnome: Each control is basically a system yeah. Like paul said, the “system” part isn’t specified in an ES and basically describes “everything else but the ES”. The systems just use the ES and they could be a completely separate library not working based on ES data internally but exchanging data with the other systems via the ES. Also I didn’t say it “computes” anything, I just said it sets the location etc. based on the Components. Ofc, why not let it interpolate based on its own tpf framerate, then you can update the MovementComponent less frequently from whatever system(s) update(s) it.

Edit: And btw, yes, Components are ideally only classes with one Constructor that gives them all their fields data and only getters for the data fields. Also as said they contain generic data (numbers, strings) and not much more. If you come to put anything but getters into your components you are basically doing it wrong or to put more friendly, you have a hint that you could do it better and more ES-like.

@normen said:
Edit: And btw, yes, Components are ideally only classes with one Constructor that gives them all their fields data and only getters for the data fields. Also as said they contain generic data (numbers, strings) and not much more. If you come to put anything but getters into your components you are basically doing it wrong or to put more friendly, you have a hint that you could do it better and more ES-like.

Yeah, that is exactly as i have it. A component hast just some fields, potentially getter/setter methods, and a constructor to conveniently create it.
Actually, currently i don't even use getters but make the fields public.

I did not want to tie the 'system' or what ever one prefers to call it (control, processor, what so ever) directly to a JME-control since then it only works when the spatial is attached to something. But there might be moving things that do not (or at least not at the moment) have a visual rep and therefore there would not be a spatial. And without a spatial to which a control is attached the control won't get updated, which is bad.

This is why I immediately distrust ES toolkits that put any emphasis on a “system” interface or framework.

I do not really like that terminology either. It doesn't really matter how you do it. But i guess, using AppStates would be a good solution?
If i add a new type of component i can add just a new AppState that does something with that compoenent and i'm done. When i don't need it anymore i simply remove the AppState. Sounds to work quite well.
@polygnome said:
Yeah, that is exactly as i have it. A component hast just some fields, potentially getter/setter methods, and a constructor to conveniently create it.
Actually, currently i don't even use getters but make the fields public.

No setters! Components should be immutable, hence public fields are also not a good idea. Create a new one that you set to the Entity when you want to change it. This magically brings "thread safety" for asynchronous access.

@polygnome said:
I did not want to tie the 'system' or what ever one prefers to call it (control, processor, what so ever) directly to a JME-control since then it only works when the spatial is attached to something. But there might be moving things that do not (or at least not at the moment) have a visual rep and therefore there would not be a spatial. And without a spatial to which a control is attached the control won't get updated, which is bad.

Again, anything that isn't an ID, an Entity or a Component is automatically a system. Also if theres no spatial why should there be a control? Its for the *visual* interpolation. If other systems also require a higher update rate of the location then of course the location generating system (whatever that is, its *not* the control in my example) should update it at that frequency. Still, an update rate of 20 cycles per second should suffice for most simulations while with visual display you might get as high as 120fps. So the control can easily do that interpolation part w/o having to do anything for the rest of the application. Again, it would not update the MovementComponent, only interpolate *visually* if it hasn't been updated yet.

@polygnome said:
I do not really like that terminology either. It doesn't really matter how you do it. But i guess, using AppStates would be a good solution?
If i add a new type of component i can add just a new AppState that does something with that compoenent and i'm done. When i don't need it anymore i simply remove the AppState. Sounds to work quite well.

Again and again, a "system" has no blueprint it can be anything and you already have two different "systems" if you have physics and AI. Bullets physics space isn't an AppState but it would be part of a system. In my example the controls are separate because you need a 1 to 1 connection of spatial an entity. An AppState would have to maintain a map of the spatials and entities to manage them, the control only needs the connection to the entity and can then work in "mid air". If you put yourself a premise like "a system has to be an AppState" then you are restricting yourself unnecessarily. E.g. running the physics system on a completely different thread would probably make much more sense than using an AppState as theres no need to bind it to the visual update.
@normen said:
No setters! Components should be immutable, hence public fields are also not a good idea. Create a new one that you set to the Entity when you want to change it. This magically brings "thread safety" for asynchronous access.

well, public final will it be then. That is as "immutable" and "thread safe" as it can get, even if you make it private and use getters. i don't really like to clutter the class with boilerplate code that essentially does nothing.

Also if theres no spatial why should there be a control? Its for the *visual* interpolation. If other systems also require a higher update rate of the location then of course the location generating system (whatever that is, its *not* the control in my example) should update it at that frequency. Still, an update rate of 20 cycles per second should suffice for most simulations while with visual display you might get as high as 120fps. So the control can easily do that interpolation part w/o having to do anything for the rest of the application. Again, it would not update the MovementComponent, only interpolate *visually* if it hasn't been updated yet.

Hm, maybe you have a more complex use case, but why would i want additional visual interpolation? It seems to complicate the whole matter for no real benefit. If a already update my ES regularly and update all LocationComponents regularly, then there should not be additional need for visual interpolation.


Again and again, a "system" has no blueprint it can be anything and you already have two different "systems" if you have physics and AI. Bullets physics space isn't an AppState but it would be part of a system. In my example the controls are separate because you need a 1 to 1 connection of spatial an entity. An AppState would have to maintain a map of the spatials and entities to manage them, the control only needs the connection to the entity and can then work in "mid air". If you put yourself a premise like "a system has to be an AppState" then you are restricting yourself unnecessarily. E.g. running the physics system on a completely different thread would probably make much more sense than using an AppState as theres no need to bind it to the visual update.

Yes, i thought about physics, too. I don't think that will be an issue. An entity that does behave physical will not have a MovementComponent, so it would not be processed by that system. instead i'd simply do the reverse as with the control that updates the spatials translation based on the LocationComponent. The control would be attached to the proper spatial and update the LocationComponent based on the translation applied by bullet physics.

Maybe it just came over wrong:
I am aware that there are more ways to update and interact with the ES: using a control to update the spatial based on the Location component for non-physical movement and vice-versa for physical movement is one kind of such a "system", if you want to word it so.
Using an AppState for periodical updates is another solution.

And yes, AI is also something i thought about and this is why i ultimately was attracted to integrate an ES in the first place. This might again require a different kind of interaction with the data.

I just realized that i implicitly assumed when i started to write about this topic a "system" would be something that updates the ES periodically, e.g. the MovementSystem, while there were other interactions possible that would also manipulate the ES but would have another term / word for them. So this is probably more a terminology issue then an actual issue of my understanding of entity systems.
@polygnome said:
well, public final will it be then. That is as "immutable" and "thread safe" as it can get, even if you make it private and use getters. i don't really like to clutter the class with boilerplate code that essentially does nothing.

Its one of the most basic java patterns really and a JVM will inline this anyway

@polygnome said:
Hm, maybe you have a more complex use case, but why would i want additional visual interpolation? It seems to complicate the whole matter for no real benefit. If a already update my ES regularly and update all LocationComponents regularly, then there should not be additional need for visual interpolation.

As I said, because the visual and other update rates seldom match. But do as you like, if you need 60+ updates per second for everything then make it so.

@polygnome said:
Yes, i thought about physics, too. I don't think that will be an issue. An entity that does behave physical will not have a MovementComponent, so it would not be processed by that system. instead i'd simply do the reverse as with the control that updates the spatials translation based on the LocationComponent. The control would be attached to the proper spatial and update the LocationComponent based on the translation applied by bullet physics.

Why not? Why double the spatial movement code? In my example the MovementComponent would then just be updated by the physics and the Control would still update the spatial position. Ofc you wouldn't use physics *controls* but the base bullet objects and a physics space running on another thread (or more).

@polygnome said:
Maybe it just came over wrong:
I am aware that there are more ways to update and interact with the ES: using a control to update the spatial based on the Location component for non-physical movement and vice-versa for physical movement is one kind of such a "system", if you want to word it so.
Using an AppState for periodical updates is another solution.

I don't know if you mean using physics controls here or whats "vice versa" about it. You have the visual representation of your entity and it should move around based on the data, thats one system. Everything else that sets the location is another system. So for example if the entity is running on rails then the rails course update the movement component, if it falls off the rails the physics system updates the movement component so it tumbles around.

@polygnome said:
And yes, AI is also something i thought about and this is why i ultimately was attracted to integrate an ES in the first place. This might again require a different kind of interaction with the data.

I just realized that i implicitly assumed when i started to write about this topic a "system" would be something that updates the ES periodically, e.g. the MovementSystem, while there were other interactions possible that would also manipulate the ES but would have another term / word for them. So this is probably more a terminology issue then an actual issue of my understanding of entity systems.

Terminology is important, especially for something that is so far from the normal OOP Java ways. The AI system would also just set some Components that are evaluated by other systems that act on it and/or give the appropriate data back in form of other Components.
@normen said:
I don't know if you mean using physics controls here or whats "vice versa" about it. You have the visual representation of your entity and it should move around based on the data, thats one system. Everything else that sets the location is another system. So for example if the entity is running on rails then the rails course update the movement component, if it falls off the rails the physics system updates the movement component so it tumbles around.

What i mean is the following:
If you have an entity that is moved not by physics but by some other data, e.g. based on a MovementComponent, then you would have to have update that LocationComponent regularly and set th new location based on the old location and the movement direction and speed. you would also have to have some means to update the location of the visual representation. Since an entity in my ES is just an UUID, this is relatively easy. When the spatial is created, a control is attached to the spatial that holds the UUID. Then the control can update the location of the spatial by retrieving the current location from the LocationComponent. If the entity no longer has that component the control can detach the spatial.

If i were to use physics, i simply have to do it the other way round: let bullet determine the location and direction / orientation of the spatial and write that data back to the component(s). This can easily be done by attaching a control to the spatial that holds the UUID of the entity that this spatial represents. thats what i meant with "vice-versa". The disadvatage of that is that the ES will only get the new data when the control is updated. So maybe some other form of data transfer is better (stuff the spatial into a list, stuff the UUID into the spatials user data, regularly fetch all spatials from the list and update the entities). But that is implementation detail that i will have to figure out when the time comes.
Quote:
Terminology is important, especially for something that is so far from the normal OOP Java ways. The AI system would also just set some Components that are evaluated by other systems that act on it and/or give the appropriate data back in form of other Components.
Yeah, the problem is, terminology for ES is so screwed up it really sucks. I read the artciles on T=Machine and the comments (and not just the series on ES design, but also the other posts that came later, about component count etc.pp.) and even there the terminology is sometimes skewed. If you go on in literature it gets even worse. And since there is no real "official" definition of an ES, everyone calls everything a little bit different. So my apologies if i made myself not clear enough in the first place.
@polygnome said:
If i were to use physics, i simply have to do it the other way round: let bullet determine the location and direction / orientation of the spatial and write that data back to the component(s). This can easily be done by attaching a control to the spatial that holds the UUID of the entity that this spatial represents. thats what i meant with "vice-versa". The disadvatage of that is that the ES will only get the new data when the control is updated. So maybe some other form of data transfer is better (stuff the spatial into a list, stuff the UUID into the spatials user data, regularly fetch all spatials from the list and update the entities). But that is implementation detail that i will have to figure out when the time comes.

I just explained that using the physics Controls is not a good idea for an ES. Use the PhysicsSpace, PhysicsRigidBody etc. instead of the RigidBodyContol and the BulletAppState.

Hi @atomix!



As the author of Metawidget, I’m thrilled to hear you’re trying it for this purpose. Please let me know if there’s anything I can do to help, or any way I can improve Metawidget to suit your needs.



Regards,



Richard.

@kennardconsulting said:
Hi @atomix!

As the author of Metawidget, I'm thrilled to hear you're trying it for this purpose. Please let me know if there's anything I can do to help, or any way I can improve Metawidget to suit your needs.

Regards,

Richard.

@kennardconsulting :
Thank for your kind words. I like to say that I'm very appreciated your work in MetaWidget. Make Java UI programming a lot easier and more fun. In the example above I'm using a lot of library

Groovy (Swing Builder , binding),
Ousia (from GoogleCode) (Groovy hook to a lot of UI libs),
MetaWidget ( Autogen UI)
MyDoggy for Dockable Layout

In the plan for improving the Tool, I want to move to base on Netbean Platform, in which give UI Programming much much more power.

In this tool, what I love the most is:
1) Autogen UI from Bean ( POJO, of what ever in this example a Map of objects)
2) Autogen - connect - synchronization with data back-end with Apache Cayenne .
This is a solution I find super adaptable, because I've done the same thing with Wicket and Cayenne. still wait for Wicket to show up in MetaWidget supported list :p

Hi @polygnome . I did my simple ES. I refactored my NodeComponent to EntitySpatialController. So you can add any node to the controller.

My code is here with stressTest(500 entities):

http://code.google.com/p/jme-simple-examples/source/browse/#hg%2FJMESimpleExamples%2Fsrc%2Fentitysystem

There are several points i don’t like about your ES:



1.) Your entity is to heavyweight. An entity, in it’s purity, is not an actual class. It is just an ID. I don’t like the idea of your Entity class which holds an HashMap for it’s components.



2.) Your ES allows you to get the entity object when you know the entity ID, but i did not find a easy way to get all entities with component ‘X’ in your system. This is actually caused because instead of storing your components in a central place, you store them on the entities. Which is imho not the correct way anyways, since your entity contains logic, while it should be pure data (more precisly, just be an ID). In your EntityLists you simply have to iterate over all entities and pick the ones that have that component. That is slow as hell.



3.) Why did you tie that EntitySpatialControl stuff directly into the EntityManager? Your entitymanager should NOT be aware of anything that is part of another engine. Your ES should work standalone, or it is not an ES.



4.) 500 entities is NOT a stress test. I made it with 10000 entities and multiple components and systems, and it worked remarkably well, although it was not optimised at all.



5.) Code style: You naming is inconsistent. in EntityManager, EntitySpatialControl etc. you use Suffixes to describe the base of the object, in your Components (e.g. ComponentTransform) you use prefixes. It is not much, but that’s a minor thing that immediately caught my eye. I’m very fussy about such things in my own code.

1 Like

Thanks man for your reply. It helped me a lot. 500 entities are good enoght for the test as i will not get more entities in the scene more than 500-700.



I refactored my code again. Please, check it out again.



I tied ComponentControl and SpatialControl to the EntityManager. That’s more comfortable for me.



Also what’s better to use: HashMap or ConcurrentHashMap?



Thanks again.

@mifth: At least two good examples have been posted here already… Also can you please, please, please at least mark your simple examples project so that people see that its your own experiments and not some official repo? Thank you.

@normen said:
@mifth: At least two good examples have been posted here already.. Also can you please, please, please at least mark your simple examples project so that people see that its your own experiments and not some official repo? Thank you.



Ok, I added this to my project: WARNING: THESE EXAMPLES ARE NON OFFICIAL JME TESTS. SO, SOME EXAMPLES CAN BE NOT SO GOOD AND EVEN WRONG.
2 Likes
@mifth said:
Thanks man for your reply. It helped me a lot. 500 entities are good enoght for the test as i will not get more entities in the scene more than 500-700.

What about a potential server? A server might need to handle several hunderd players, several thousaned NPCs and even some more entities for others stuff.


I tied ComponentControl and SpatialControl to the EntityManager. That's more comfortable for me.

Well, you should really try to decouple your ES from anything else.


Also what's better to use: HashMap or ConcurrentHashMap?

There is no easy answer to that, and certainly not a single one that is right or a single one that is wrong. It depends on the use-case, and what you are trying to achieve. I am still in the process of prototyping some stuff, but as it is now, i will not need a ConcurrentHashMap. Thread safety will be ensured by other means.
@polygnome said:
...I am still in the process of prototyping some stuff, but as it is now, i will not need a ConcurrentHashMap. Thread safety will be ensured by other means.


Just remember, a single synchronized is many times more expensive than a ConcurrentHashMap.

And the danger of using a regular HashMap (unsynchronized) from multiple threads is that it's possible for a put() to cause a get() to loop forever. It's not just an inconsistent data issue in this case.