What you often do in an ES system is to have normal java pojos doing the processing. For example the largest use case for that in my game would be the ship computers.
In the es there is a component specifying the computer’s existence and a few properties, like processing speed.
The Computer system basically then maintains a filter and a map uuid of entity with computer to a luaj runtime object.
This way I have a clean ES state of the game, but can still use extensive oo based librarys for processing the data they represent.
(i’m a user of my own Empire-ES :P, but zay es and my system are actually behaving pretty much 100% the same way)
ECS can give headache on it’s own. Mixing it with traditional OOP will brake the contracts that help you keeping things simple and stupid. You wil probably find it strange and unpredicatable where ECS is definitly not.
I recommand to do as much ECS as possible, or none.
So let’s suppose I am on a dungeon and I have an “HitPoint component” with value 100. Then I wear a magic ring that gives me a boost of hitpoints (component “hitpoint booster”). Then I drink a magic potion that gives me a temporary boost of hitpoint.
Does this scenario require “nesting” of components? So that the magic ring is like the potion, except for that the latter has a decay?
How should the original HitPoint component keep track of all the boosting components?
This has been covered in other threads a few times… even recently.
The ‘buffs’ would be their own entities attached to the player. You’d have one system somewhere that was responsible for adjusting player hitpoints up/down depending on damage entities or buff entities attached to the player.
Then you can decay those entities just like anything else… either to stop the effect of the potion or let the fire burn out on that fire damage.
And note, the beauty of the ES is that this is not even specific to players. It would work for anything with buff/damage entities and hitpoints. So you could even light a chair on fire if it had a Hitpoints component.
I would highly suggest to study first the asteroid panic from @pspeed. There is a thread Asteroid Panic: Why is Spatial in HashMap instead a Component - #18 by ia97lies of mine where I did try to understand that implementation. I asked a lot of stupid questions and got a lot of good and very detailed answers there. With that help it took me about 2 days to write my own simple clone of invaders with ES
Just one remark on this all or none. I think on the same abstraction level, yes absolute. But on a different abstraction level not necessarily true in my opinion. On a different abstraction level you can have also more “traditional” code. Game logic, AI and the like.
Well that’s true. I’ve found myself overkilling the “ECS at al cost” rule many times, like when I wanted to manage IA behaviors as component, or the terrains node as entites.
An ECS can effectively communicate with a physic engine, an IA behavior tree or state machine, a terrain generator. It actually is communicating with the viewing managed by jMonkey in our case.
I thought it was a cool idead to attach an entity to a spatial, so that on collision (managed by the scene graph) I can pull the game logic. My first attempt didn’t go well… I’ll do something else
GRAVE: Uncaught exception thrown in Thread[jME3 Main,5,main]
java.lang.IllegalArgumentException: Unsupported type: com.simsilica.es.EntityId
at com.jme3.scene.UserData.getObjectType(UserData.java:124)
at com.jme3.scene.Spatial.setUserData(Spatial.java:1357)
EDIT: maybe this will work?
node.setUserData("eid", myEntityID.getId());
EDIT2: Ahem… is there a way to get the EntityID from the “entity ID”?
You have to know that you can’t retreive an Entity, expecting an object with all its components attached. The object Entity represent a bucket, filled with the component you ask like in my exemple.
If you want to get a specific component of an entity, it may be simplier to write :
MyComp c = entityData.getComponent(eid, MyComp.class);
Knowing that it could be null if no such component is attached on that entity
Not to mention, storing them in a map is a HORRIBLE HORRIBL 1000 times over approach.
You may have MILLIONS of entity IDs in the course of a game. You definitely DO NOT want to save them around like that. Just really bad. Don’t do. Can’t stress this enough.
It’s a sign that you misunderstand something about ES somewhere.
I don’t know that it’s the intention but I was giving the benefit of the doubt as to why it would feel necessary to keep the instances around.
It’s not. Just a bad idea.
I use EntityIds in hashmap all the time. I compare them if I’m writing .equals() for components that have EntityIds. That’s probably it. I use .equals() in all cases, though.
I want to attach an entity “effect” to a Spatial, so that when the Spatial collides with another Spatial, I can retrieve the original effect from it and attach a “touching” component; so that I can later retrieve all the “effect”+“touching” entities and process them…