I haven't actually implemented this system yet. I'm trying to work through the major conceptual hurdles before I actually start writing code, and the proper way to generate IDs is a little confusing to me. Should I just give each entity an integer ID in the order that it's created? Use the C# guid? What is the proper way to assign IDs in such a way that there won't be issues later on?
|
|
The sole constraint of an identifier in an entity component system is that the generated identifier be unique. That's the only criteria. If it's unique, it's good. Any method which satisfies this one constraint is a proper way to assign IDs.
Doesn't matter. Do any of the above, or do some other method that I haven't thought of. As long as whatever method you pick generates unique identifiers, that's all that matters. Ignore folks who argue about which method is faster. This is just generating unique identifiers; it will almost definitely not be a factor in your game's execution time. Trying to optimise this sort of thing for speed is a total waste of effort until you have profiler results which prove otherwise. And in that case, the only thing you'd have to change is this one function which generates the identifier. It wouldn't be a major change to switch from one mechanism to another. So do whatever you're comfortable with, and don't stress about it. |
||||
|
|
|
I don't think there is a proper way. You might want to let the user assign his own identificators on creation, if he wants, it's what Ember does, it then lets you retrieve entities by it. Artemis probably uses consecutive integers, reusing them if they're freed when an entity is destroyed, because it uses an array implementation. Personally i use the consecutive integer approach, because inside of the manager i store entities in an array and i want to be able to quickly access an entity by its index. Reusing identificators means that you don't have to use lists because you don't shift the array when removing an entity. Also, for me in code identifying entities comes down to It depends on your needs. If you're using an array approach, then the algorithm is simple, pop an id from the id stack, or if the stack is empty, assign the next integer. When destroying an entity, push the id to the stack. If you're using lists and just want a unique identifier then you don't even need this, unless you're worried that somebody might create four billion entities. |
|||||
|
|
Our ES implementation basically uses an unsigned integer to assign a unique ID to each entity that gets created. The entity ID is essentially an index offset to various subsystem vectors where component data is stored. When an entity is destroyed at the end of the frame, those IDs are placed into a free list and simply reused later. In other simulations & in networked games, I've often resorted to some 64-bit ID which we referred to internally as a GUID that identified a few characteristics about the entity by simply doing some bitwise math. As for editor friendly names or possibly encounter-specific names that make scripting easy, we generally associate a TagComponent to those entities. It allows us to query entities by some human readable name such as "General of Death" or some system-defined name such as "Target", "Player", "TargetTarget", "Leader", etc. |
|||
|
|
|
You could also use a dictionary (map, hasmap, etc). It would be just as easy as using an array approach, but more flexible since shifting and all that is handled for you. You just need an IdManager class, an instance of which would be a member of your EntityManager class. The IdManager should have a public method called
Now, when you're adding an entity just do Most of the problems raised in that AltDevBlog article Darcy posted don't really apply here: we're not letting anyone name entities, strings are just numbers here. If you're using C++ you might not need strings at all, as integers work as keys too. |
|||||||
|

