What become created entity when they got no more Component attach to it?

Hello,

I’m currently using the Entity System in my project and i was wondering if when an entity got no more component attached to it, it was removed from the entitySystem (entityData) or it does nothing and keep it stored !?

if the entityID is keep in entityData how to remove it without breaking the design ?
If the entityID is keep and there is no way to remove it what is the cost of it ? (i know that the entityID is only a number, but they aren’t illimited. Is it something i’ve to worry ?)

Thx for reading.

Only components are stored.

EntityID’s are essentially unlimited, though. It’s just a number… but it’s a 64 bit number. If you created 1000 new entities per second, it would take you well over 500 million years to run out (almost 600 million).

Put another way, if a Tyrannosaurus Rex had started counting 1000/sec and were still alive today… even he wouldn’t have run out of entity IDs yet. (he’d have more than 500 million years left to go.)

3 Likes

You will need to remove Entity objects from your EntityData as entities become obsolete. If you don’t, the EntityData will become bloated and require extra processing to retrieve data you want. In extreme cases, you may get an “out of memory” exception.

You can remove obsolete entities from your entityData object like so:

entityData.removeEntity(e1.getId());

Here is a code example that may (or may not) help …

You will see that I am testing the age of an Input component which contains inputs from the keyboard or mouse. If the component is older than say 500 mS, it will be removed from entityData, i.e. deleted.

Entity e;
EntityData entityData;
EntitySet entitySet;
FieldFilter ff;
    
InputCt testCt;
long age, birthTime, cutoffBirthTime, currentTime;
    
private void removeOldEntities() {
    for( Entity e1 : entitySet ){
        testCt = e1.get(InputCt.class);
        birthTime = testCt.getBirthTime();  // returns time (mS) when component was  created
        age = currentTime - birthTime;
        if (log) {System.out.println("## ct age = " + age);}
        if(birthTime < cutoffBirthTime){ // if birthTime is lower, i.e. younger.
            entityData.removeEntity(e1.getId());
        }
    }
}

I hope that helps.

The removeEntity() methods is a crutch that simply removes all of the components for an entity (with one caveat). There is no internal entityId->Entity map that gets filled if you don’t call remove… because Entity objects are views and only exist when you ask for them.

So removing all of the components is enough to remove the entity.

(The removeEntity() caveat is that when using the SQL persistent version of EntityData, it will only remove components whose types have been accessed during that run. This will be fixed someday but usually doesn’t matter anyway.)

Regarding your InputCt.birthTime stuff… the more “ES way” to do this might be to have a special component to signify things that should die at some point in the future… then some kind of reaper system that simply watches for them and purges anything past its expiration time.

Input may be a special case but I find having some kind of “Decay” component is usually required for other things, too… whether they are mob drops or sound effects or whatever… “things that need to be removed in a little while” seems to come up often.

Thx for reply,
But for the time being i guess i’ll stick to not remove the ID, since my issue isn’t about how to remove the entity, but, how to safely remove the entity without knowing what other component is attach to it… I’ve currently solved this issue by avoiding this kind of scenario directly, As exemple :
[Before - MethodA]
There was 2 system - 1 to handle the rendering (RenderSystem) and 1 to handle the Event (EventSystem).
RenderSystem used 2 component : PositionComp(where to render) & RenderComp(what to render).
EventSystem used 2 component : PositionComp(where to put the event) & EventComp(What the event is).
The issue there was that when i want to remove an event, i can’t remove the entity and i can’t even remove the PositionComp, all i can, is removing the EventComp even if it was the EventSystem who added that comp (i’m not keeping track of what system add to the ES), but then i’m left with an entity with a PositionComp wich is pretty useless by himself, a weird spot for me if i can say…

[Now - MethodB]
Still two system but now the EventSystem no longuer use the PositionComp, the position value is inside the EventComp, I don’t like the idea since it make me have duplicated value, which is what i realy don’t like, but this solve me my first issue who where that i couldn’t remove the positionComp, by extension the entity since the PositionComp was shared on two system, now it isn’t.

As you might understand this first issue by resolving it, make me create another issue… This is where i am currently, i found myself kinda lost on the ES currently since this issue is something i’m having all over the Project and i didn’t founded any convincing answers on this.
This thread is about “what become an entity when it got no Component” but the root issue is concerning “shared Component over multiple system”, maybe should i edit the thread Title ?
Anyway is it right to do so ? or a component shouldn’t be shared at all !? I kinda like to have shared component since it make stuff a lot easyer, not to mention avoiding duplicated data, on the exemple i’ve showed, the exemple [MethodA] is the one i like the more but as explained it lead to some conflict, so, is it the right way to go ? or is the exemple [MethodB] who follow the design better ? or any xD

Thanks for reading, even if i’m a bit off topic.

Sure, you can share components across systems. It happens all the time. It’s even possible that your other components are too coarse grained but it’s hard to say. “Event” sounds especially suspicious… but I don’t know exactly what it’s doing.

But for example, I’d use (Position, ModelType) to display my spatial, (Position, Name, Icon) for map markers, (Position, SoundType) for positional audio, etc… Position and Name are almost on every object and used by a bunch of systems.

I’m not sure why you feel like you can’t remove the position component in the event system… if the entity only existed to be an event then it should be no problem. But perhaps I don’t know enough about what you are doing.

you can share components across systems

Firstly, thanks, now i’ll not feel guilty of doing so :smiley:.
Then, be kind, i’m still on the prototyping phase of the project, not everythink is set on the ground or marble (on the major part)…
Currently the used EventSystem only concern special event on the map like player start position, teleportation etc… (i’m using an hexGrid board), so, where i was feeling that i was doing it wrong when removing the entity, was when looking forward.
On the project the player use card to play, these card, can be used to generate stuff on the grid (spell, building, event etc…) and as exemple i was thinking about if i put this EventComponent on an entity that already contain a CardComponent the EventSystem could not remove the entity when removing the EventComponent since it is an Event ok but it is also a card… This isn’t a problem that i’m being confronted so far, i might be just wondering too much…

Well, I’d see those as separate entities, I guess. Many entities can have the some position, of course.

I kinda don’t want to have to multiple entities for my purpose, the power i saw when using the ES is the fact that an entities can become whatever you like just by adding, swaping, removing component, without too much effort it allows weird stuff… as a card being a character, an event and being or not controled by the player…
Anyway, Thanks a lot for these answers. Have a nice Monkey days :grinning:.

Yes, and entity can take on the “attributes” that allow it do be other things… but some things still don’t make sense. For example, an event is not a mob and it seems a little silly to make them the same entity. And position is not a good enough reason to make two entities the same for no other good reason.

…but I’m still not really clear on what your events are… since from your description it sounded like something else.

Note: there are two working Zay-ES example projects you can look at if you haven’t already seen them.

Well, last time i’ve said that i was working on a project where player use card to play, but that’s is only a part of the picture, the project contain also a WorldEditor, something on the idea of RPGMaker (less generalist & the goal isn’t to have something like it) RPG Maker - Events Commands
It is not realy used in the actual game, it is used on the editor to make the world generation easier. this is how a monster can be an events, data generated by the event system will be saved with the map then on the game loading these data then will be used to populate the world. I’m not sure currently if it will work nice, since i actually didn’t reached the the loading point but the idea is there, maybe i’m wrong of doing so, idn… Hope i’ve helped.

Note (this part is fully off-topic): I’ve looked on the zay-ES example project and i was wondering on why always using the “entitiesSet.applychange()” on the update loop this seam kinda rude (i got the Zay-ES implemented the same way) is there another way to fire the applyChange() without having to run it on each frame ? i mean there is other way to fire it ofc, but let say i use a trapSystem, i know all trap i got can only be trigger after a movement of any type, how can i update the trapSystem (so call the applyChange() outside the update loop) without having to call “manualy” the TrapSystem on each movement change, it is kinda not realy pratical… well, the way i think about it isn’t pratical since it is realy prone to error since it is called “manualy” which mean if i forgot the call it won’t work and might put me on bad spot… Well i won’t get further i guess you got the idea :smiley:

You have to call applyChanges() to get updates to happen to the local entity views. It’s nearly free when there are no updates so there should be no worries about calling it. That’s kind of the ES way… other entity system frameworks just hide this from you but they still do it.

…but the data-oriented nature of the approach guarantees that you will be updating your entities once a “frame” for some definition of frame.

I’m not sure I understand enough about your trap system to comment further… though to me already a “trap” system seems “too big” in an ES sense. Meaning, in an RPG, I can think of at least three systems (most general) that could handle a trap triggering and applying damage. (TriggerSystem, DamageSystem, HealthSystem or whatever)… but maybe your “trap system” is just what I think of as a trigger system… just triggers and applies effect components.

the trapSystem is only an exemple that come me to mind, and yes it is as you said :

what I think of as a trigger system… just triggers and applies effect components.

It seam that what you call a triggerSystem is what i call eventSystem.

As i’ve understand from what you said about applyChange, there is no real cost of calling it each frame. But even when using networking !?

It is especially better when using networking… any changes are delivered in the background and queued up. applyChanges() is just applying those that are queued up… so if there’s nothing queued up then it’s only the cost of a queue size check, ie: almost free.

This as opposed to real polling where there would be networking involved (ie: slow).

The whole approach was designed with networking in mind.

1 Like