I want to perform a special effect on a group of entities’ spatials before removing the entities. In this case, it is necessary that all the entities lose all their functionality (except basic display) during the effect, so they’re not moving, shooting, etc.
I thought I could do this by removing all components from those entities, but it turns out DefaultEntityData does not have methods to remove all components, and it doesn’t have a method to list out all components belonging to an entity. So, how should I do this?
Edit: note that it’s possible that removeEntity() will not remove all of the components because “all of the components” is generally unknowable. It will remove all of the components the EntityData knows about. For example, if you are using SQL persistence then the SqlEntityData does not know about some persisted components until you have tried to use them (either by querying them or storing them). When you start a persistent game up “cold”, SqlEntityData doesn’t know about any persisted components.
Because of how components are resolved, it is difficult/impossible for Zay-ES to know about them all ahead of time.
If I knew more about your use-case then I might be able to advise better… but usually removeEntity() is enough if you are aware of the caveats.
You should also try to minimize which systems will remove an entity because it can be difficult to know what other systems might be trying to update/read that entity at the time. To stay nicely decoupled, it’s sometimes better to use something like the DecaySystem with a 0 timeframe just to have all removals done in one place.
Ah, a misconception on my part. That is exactly what I need.
Here’s the idea:
I have a dungeon layout. As the player moves from one room to another, the previous room unloads itself while playing a fade-out effect on all the entities belonging to that room (fades entities farthest from the player first). During this effect, I don’t want these entities doing anything, so removing all their components (except the visual component) seemed like the best way to guarantee they do nothing.
I have a decay system, but in this case I don’t think I can use it. I have to add the visual component back into the entity without the visual system catching it in between and removing the spatial altogether.
Although, I could add a “remove all except these” component which yet another system would act on (idk tho, I’ve got, like, 52 components in use already; not really sure if that’s ok). At least that would keep operations like this together in one system.
Just something to consider is the relationships between systems, both implicit and explicit.
A system that removes all (or almost all components) suddenly has an implicit relationship with every other system. Including all future systems.
If two weeks from now you add another system that attaches some state component to these rooms and expects them to be there later, too bad. Your implicit relationship screws you.
“doing anything”… what is “anything”? What does “anything” trigger off of? Why does this action get to decide that all now and future “anythings” should be halted. What if someday you want some passive AI that goes into a low-detail mode or something… you can’t because you’ve already unilaterally decided to kill it all somewhere else. And as the size of your game grows “somewhere else” may not be obvious when you’re working on that new thing and finding it’s randomly not working like you expect.
Just be careful with these situations because they will almost always come back to bite you later and there is generally a better approach depending on context.
Edit: without knowing more about your situations, another way to handle this would be to have the systems doing the various “anythings” to be aware of the room going to sleep. Perhaps entities have an “in room” component that gets changed in some way when the room is put to sleep.