... or better yet, removing the need to search the map altogether.

I'm either looking for suggestions on how to optimize my code, or a change in design.

In my component-based entity system, the Entity is comprised of Attribute and Behavior objects. The Behavior objects are just stored in an std::vector; they are no issue, I just call their update function.

Attributes, I store in a map of <std::string, Attribute> and they represent the path of communication between Behaviors (Behaviors never interact directly). When a Behavior needs an attribute it searches its Entity's map.

That's a bit problematic for Behaviors that access that information a few times a second, like the Rendering behavior (draws the Entity on-screen). Rendering needs to read the Position, the Orientation, and a few other things, and it needs to do that a few times a second.

How can I solve this issue? It should also be noted that the base classes Entity, Attribute, and Behavior are written in C++, but their implementations in Python.


Before I say anything else -- Is this causing problems? Because if its not causing problems, don't prematurely optimise it. I'm sorry if you already knew that, but it had to be said. If you don't know the old Knuth saying, I'll note it here for you.

Otherwise... Too much indirection is very often going to be a problem in real-time simulations. If you overarchitect things, this is the kind of wall you may well hit. You already know what the problem is; I guess it's time to make decisions about where it is really necessary to have that level of indirection. With entity systems, it is better to keep things very simple, as in terms of game logic this is "the metal" so to speak. Better to keep all that metal really close together.

The only other solution I can suggest is to use a much more efficient data structure... if that is possible in your case.

Why, if I may ask, is it a problem for your Behaviours (which are I think what I and I others would call entity components) to talk directly to one another?

I can suggest an article: Coding Cowboy -- Evolve Your Hieararchy. It should give you a bit of insight into how simple this can be, and has been in many games. In the article, the author is referring to the development of the early Tony Hawk games in particular.

EDIT: (In response to your 1st and 2nd comments) No, they wouldn't have to query the entity. That's the problem! Every individual EntityComponent has to have fixed references to other EntityComponents which it bears relevance to, or which bear relevance to it (depending on how you look at things). You problem is you're doing a lookup on every update. What I'm saying is you are meant to do this only once: You give each component a fixed reference to any component it depends on, from the time that these dependencies are injected, meaning, for example, that a pathfinding component is going to need to reference the spatial component; without it, it cannot know where it sits in space, and thus cannot pathfind. So you either inject all these components into your entity in the right order on entity creation (usually your entity factories will do this), or you build an intelligent system into your base entity class that rechecks all dependencies on every new component addition, and set fixed refs between them. But the fixed references are a necessity, otherwise you will face exactly the problem you are facing now -- no matter how you look at it, lookups have a cost and they do not belong at this point in your architecture, in any real-time game.

  • \$\begingroup\$ I read that article a few times before. Even if components talk to each other, they'd still have to query the entity for the right component, wouldn't they? The reason I made the distinction between Attributes and Behaviors is to reduce the number of unnecessary calls to update() (Attrbutes don't update themselves), and to reduce the size of the map so that it only holds the components of interest (ie. Attributes). [cont'd] \$\endgroup\$ – Paul Manta Aug 31 '11 at 8:09
  • \$\begingroup\$ [cont.] Behaviors and Attrbutes are still just components, and the only difference is that Attributes don't have an update function. Again, I made this specialization for optimization purposes, and I really don't think it's complicated to understand (at least not any more than the model suggested in that article). \$\endgroup\$ – Paul Manta Aug 31 '11 at 8:11
  • \$\begingroup\$ @Paul, see my edit in response to your comments. \$\endgroup\$ – Engineer Aug 31 '11 at 8:27
  • \$\begingroup\$ Oh... I really don't know how it didn't occur to me that I could pass the necessary Attributes to the Behavior when it is created... :| Thanks. \$\endgroup\$ – Paul Manta Aug 31 '11 at 8:32
  • \$\begingroup\$ Paul, you're most welcome. The thing is, do you even need the Attributes vs Behaviours aspect? I guess that's what I'm wondering, beyond the lookup issue you were having. But, if it works for you for now, great. If the distinction between these two is unecessary, then you'll realise it sooner or later and factor them out. \$\endgroup\$ – Engineer Aug 31 '11 at 8:36

Swap the map for a hash_map or an unordered_map (whatever your compiler supports).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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