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.

Possible Duplicate:
Retrieving components from game objects (entities)

I'm working on an entity-component-system game at the moment. I've looked in particular at the Artemis framework and a c# port of it but I am writing my own implementation of the pattern.
http://gamadu.com/artemis/manual.html

I'm puzzled as to how components are retrieved from the EntityManager. As far as I can tell I have two options:

  • Assign each type of component a static ID, that is used as the index of the component (my entities are held as EntityComponent[entityID][componentIndex]) but I'm concerned that in a situation where an entity has a component of ID 9, that I will then have size the array to 10 and have 9 empty elements preceding the sole component, consuming memory unnecessarily.
  • Alternatively I could write a generic method e.g EntityManager.GetComponent(int entityID) but this would require a look up or OfType<> call against the entities components.

Surely there is a more efficient way. What am I missing? Artemis includes a ComponentMapper class but I struggle to understand what it does. I want to ensure the basics of the system work as efficiently as possible. Many thanks in advance for any feedback.

share|improve this question

marked as duplicate by Byte56, Tetrad Jan 25 '13 at 18:08

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
See my answer in the duplicate. –  Byte56 Jan 18 '13 at 15:38
    
Thanks Byte56. The C# equivalent of HashMap is Dictionary<> and I'm not sure it is O(1) / constant time for retrievals by key as an array would be. –  Drew R Jan 18 '13 at 17:02
    
Actually, it's very close to constant time. See the documentation (under Remarks): "Retrieving a value by using its key is very fast, close to O(1):". –  Byte56 Jan 18 '13 at 17:11
    
I've just commented on the below answer. I now have an EntityManager that maintains an array: EntityComponent[entityID][componentIndex] but also a Dictionary<Type,Dictionary<int,EntityComponent>> but I'm finding that FPS falls in half. It could be that Type.GetHashCode() makes for a poor key but there aren't more than 5 component types at the moment! –  Drew R Jan 18 '13 at 17:28

2 Answers 2

up vote 1 down vote accepted

Assign each type of component a static ID, that is used as the index of the component (my entities are held as EntityComponent[entityID][componentIndex]) but I'm concerned that in a situation where an entity has a component of ID 9, that I will then have size the array to 10 and have 9 empty elements preceding the sole component, consuming memory unnecessarily.

As long you are reusing your Entities and their static ID (something Artemis does). I don't see the problem with this. Chances are you are going to fill in the spots anyway, with the entities that are in an object-pool or something similar. And in the case where you reuse your Entity the memory is already allocated for you. From Artemis point of view Components are very small objects( they can be big, but I doubt that will happen ). I Really don't think you're loosing too much memory.

share|improve this answer
    
This is the implementation I am going with. It offers a two fold decrease in access time vs a dictionary all else being equal. –  Drew R Jan 19 '13 at 17:55

In a very reduced implementation example, this is what I do in my GameObject / Entity class:

private Dictionary<Type,Component> compMap;

public T GetComponent<T>() where T : Component
{
    Component result;
    this.compMap.TryGetValue(typeof(T), out result);
    return result as T;
}

Basically the lookup you try to avoid - but as far as my experience goes, this has always been "fast enough". I have a specific optimization for Transform Components, though, because they're accessed very often. I hold a special private field for them and allow access via predefined property.

private Transform transform;

public Transform Transform { get { return this.transform; } }

When adding or removing Components, I check if its the Transform Component and update the internal field. It's kind of a hack, but since almost every GameObject / Entity has a Transform Component, it speeds up things a bit.

I'm not sure whether we're using the same Component System approach, but a lookup actually isn't that bad - you just have to use them wisely. A Component that needs a reference to another one might look it up once and store the reference until its disposed or no longer attached to the GameObject / Entity. Even if you do a once-per-frame lookup for a lot of Components, other things are more likely to affect your performance: Rendering, streaming audio, complex AI, etc. usually consume more CPU power.

share|improve this answer
    
This is one implementation I did try. I've evolved it slightly, I now have an EntityManager that maintains an array: EntityComponent[entityID][componentIndex] but also a Dictionary<Type,Dictionary<int,EntityComponent>> that maintains a dictionary. This is purely so I can compare speed of access between the two, I'm sure just one of the above would suffice. –  Drew R Jan 18 '13 at 17:18
    
Although I am running the game windowed i.e not full screen, and rendering and processing a large number of sprites every game iteration, (25,000 sprites are being .Draw()n whether on screen or not at the moment), my FPS falls in half when I use a Dictionary to retrieve components from the EntityManager! It seems a static location for the component is a lot more efficient. –  Drew R Jan 18 '13 at 17:24
    
You need to profile the code to see where the real bottleneck is. –  Byte56 Jan 18 '13 at 17:39
    
Run it though SlimTune and it is the GetComponent<ComponentType>(int entityID) call and the subsequent _componentsByType[component.GetType()][entityID] and .GetHashCode() calls with it that are costing me. Frustrating that I can't find that ideal method. C# dictionaries may well often be O(1) but that's no good in my case as they are O(2) compared to explicitly referencing an array element! –  Drew R Jan 18 '13 at 18:00
1  
@Drew R I really doubt that you'll ever actually need 25000 distinct entities in a 2D game. If you have any kind of requirement that needs huge object numbers like this, I wouldn't use the component-based approach for them at all and instead group multiple objects of the same kind to one Entity simulating / rendering them all. A very good example for this are particle systems: You wouldn't really model each particle as a single Entity, would you? –  Fetze Jan 18 '13 at 22:01

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