My question: How do you tackle new entity/component addition on the fly?
Background:
I'm using the c++ port of artemis framework https://github.com/vinova/Artemis-Cpp to architect my game objects. In artemis, whenever you create a new entity or add a component to an entity, you have to call refresh() on that same entity for the changes to take effect.
entity->addComponent(xyz);
entity->refresh();
- Entities in artemis possess 3 attributes: a unique id, a type bitstring(identifies which components it has), a system bitstring(identifies which systems will call this entity).
- When calling addComponent, the type bitstring is updated, but not the system bitstring. When calling refresh, the entity is added to a 'refreshed' array.
- At the start of each game loop iteration, a function loopstart() is called. This function goes over all the objects in the 'refreshed' array, and updates the systembits by looking at the type bitstring of those objects.
- The last sentence makes it clear that all new updates will be reflected in the next iteration. If I shoot a bullet, it will appear 1 frame later. If I want to process collisions, it will start 1 frame later.
- How would you suggest I tackle this ? If I add a component, I would like that entity to be processed by a new system immediately
What I've done so far
- Change the order of system updates. Call the removal system first, before any other, so that all entities with a 'destroyed' component collected in the previous frame will be destroyed in the beginning of the current frame
Problem: Even removal will need a refresh, which will not happen immediately. This causes invalid pointer access as the subsequent systems will expect to see some components which are now not there thanks to removal
- Instead of refresh, I call the function EntityManager::refreshEntity. This function is responsible for actually updating the system bits so that the entity is acted upon by any new system if a component is added to it. And the result is exactly how I want it
Problem: This function has a loop inside it, to update the bits for all the systems present. This can be a problem if there are tons of entities each frame being updated. Which is why, design-wise, it is called inside loopstart, only at the beginning
- I recently came across entity state machines http://www.richardlord.net/blog/finite-state-machines-with-ash . Any inputs?
Thanks for reading !