I notice when I remove an entity from EntityData it publishes an EntityChange event for all the component types I have in my game even if that entity does not have those components at all.
Shouldn’t EntityChange event be published only if the result returned by handler.removeComponent() is true?
I’d have to look into this stuff more deeply to fully have an opinion.
Wholesale removing an entity is already a little weird because it’s sometimes the case that the whole component set is unknowable from a reflective perspective. Some components could in theory be generative and therefore never really removed, for example.
So while removeEntity() is super convenient, it’s always going to be problematic on some level.
Attempting to request those components for some EntityId (fake or not) may be enough to cause them to register also.
I do not understand this. Would you mind elaborate more? thanks
Still unclear to me why EntityData.removeComponent() should send an EntityChange event when the entity does not have that component at all. (i.e there was no change at all)
I am going to modify it in my case to send the event only if the handler was able to remove the component (by checking the handler result) otherwise won’t send an event. I will report back if I noticed an issue.
if (result) {
// Can now update the entity sets that care
entityChange(new EntityChange(entityId, type));
}
And by the way, curious to know if there is a better way than looking through ALL the component handlers for removing an entity on SqlEntityData?
For example a special table that records component types an entity has, which automatically gets updated when adding/removing components on the entity.
But that would create a bottleneck on every component update for something that would only be set once. Also, how do you remove it again if someday your app doesn’t have that component anymore? How many dead components before it becomes a maintenance burden?
99% of the time your app already used all of the components by the time it removes something because something has hit them. If your app is such that this isn’t true then just ask for all of the components for entity ID -1 and they should register.
removeEntity() is very convenient for one-off entities but I would caution to use it carefully for real game objects as there might be some components you want to keep around. By murdering the whole entity, you force a cross-dependency between systems that otherwise wouldn’t be there. (And for the one-off entities like buffs, etc. the act of creating them already registered the components.)
…and I’m aware that the DecaySystem is already about this. (The original version before I created the open source one decayed components and not entities for exactly these cross-cutting reasons… but I ultimately opted for simplicity and convenience.)
Yes, this is not a big deal. I fixed this by manually registering component handlers at the beginning.
And to be clear, my concern is about the performance of this on the one-off entities. I am going to have lots of them (in RPG game) then decay them shortly.
Will this be an issue? As on entity removal it is going to make lots of SQL statements against ALL of the tables.
I may add a ComponentDecaySystem for this purpose, that acts like DecaySystem but instead of removing entity just removes the components I have specified.