Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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?

share|improve this question
2  
I have entity component systems without entity IDs and it works fine. –  Kikaimaru Jan 20 '13 at 12:02
1  
There is nothing wrong with just increasing integer ids. By the way in SQL databases auto increment primary keys are very common which is the same thing. I did this in my game and it works fine. Your entity manager would provide a function for creating a new entity (which basically simply increases the last id variable by one) and a function for assigning properties to an id (where you first check if the passed id is less then the last id variable). –  danijar Jan 20 '13 at 16:15
    
@Kikaimaru what is the "size" of your project? This kind of stuff could be useful for MMORPGs, or something like patching saved games. –  Den Jan 21 '13 at 20:06
    
@Den: Its small mmorpg, and second one was small 3d engine. And in mmorpg i have component that holds id, because not every entity is on server (like particle effects on hit, test showing damage, etc). I think that main benefit of using entity ids (or numbers instead of entity classes) is optimalization, and in most cases its not nescessary. –  Kikaimaru Jan 23 '13 at 10:17

4 Answers 4

up vote 7 down vote accepted

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.

  • guid? Fine.
  • integer from an incrementing counter? Provided the counter isn't going to overflow during play, that's fine too.
  • random integer? Provided the integer is big enough, this is the same as a guid, so is fine. If you're generating smaller random numbers, you'll probably eventually randomly generate a duplicate ID, so that wouldn't be ideal.
  • current time as returned by a high-resolution timer? Sure, if you're certain that you're not going to generate more than one id per whatever resolution the timer's using.
  • hashed string? See the comment above about random integers; same deal here.

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.

share|improve this answer

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 entity1.id() != entity2.id(), not entity1.id() == 'player'.

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.

share|improve this answer
1  
Good article which goes into a bit of detail on why using strings for ids is usually a bad idea, particularly if that string might need to change later : altdevblogaday.com/2012/12/11/… –  Darcy Rayner Jan 20 '13 at 9:47

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.

share|improve this answer

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 GetId(), which would always return a unique string of n characters. You would also need a private method NextId(), which would be called from GetId() to compute the new unique ID.

GetId()
{
    old_id = current_id_; //Store the current id so it doesn't get changed.
    NextId(); //Advance to the next ID, just like counting.

    return old_id;
}

Now, when you're adding an entity just do entities[idm.GetId()] = some_entity;.

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.

share|improve this answer
    
TBH i don't see a point to this, you're introducing a lot of overhead for nothing. Hashing is an expensive operation, dictionaries are expensive data structures, strings are as well compared to integers. If you don't want to use arrays, it's better to just use a list. –  dreta Jan 20 '13 at 14:07
    
Not really that expensive at all. They're pretty standard for a lot of languages, and greatly optimized. Besides, you don't actually need to use strings (at least not in C++), as you could get the benefits of maps by using integer keys. The benefit of this is that it's easier to implement session-persistent IDs. –  jco Jan 20 '13 at 14:13
    
It's expensive enough though. CBES shouldn't introduce overhead, this is why Artemis does all the tricks it does. If you're only going to use CBES for something like the player or a monster in an MMO, then sure it's probably fine to use a dictionary, but usually CBES is used for everything from a few massive buildings to lots of tiny particles. These things matter. –  dreta Jan 20 '13 at 14:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.