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 am working on an Entity System design based largely off of Adam Martin's design and Ray Wenderlich's Objective-C Implementation.

I am working on the AI system using a state machine with a System for each state. However, many of these systems share a lot of functionality, for example:

-(NSArray*)findEnemiesOfEntity:(Entity*)entity withinRange:(float)range {
    // Get all entities with a Team component
    // Narrow down entities to those on opposing team
    // For those that have a Position component:
    //     Get their position
    //     If their position is within range:
    //         Add to array of return values
    // Return array of return values
}

Obviously this functionality could be used in many ways; for example, the AIDefendSystem could use it to know if it is safe to move to the Attack State and the AIAttackSystem could use it to know when to return to a Defensive State.

So my question is this: where does a function like the one above go in the design?

Things I have thought of so far:

  • A copy in each system: this seems quite redundant and hard to maintain. Perhaps because other design approaches view this as a code smell, I can't quite bring myself to do it.
  • Inheritance hierarchy for systems: the common OOP solution to the problem of keeping a copy in each system. This also seems like bad design as it will encounter the same sorts of inheritance problems ES was supposed to solve (e.g. what happens when a non-AI system needs to know how many enemies are within a given range).
  • A separate helper class with all these functions: to continue the database metaphor that Adam uses, I would interpret this as the "view" functionality in mysql. The downside to this would be a giant class full of seemingly unrelated helper functions
  • The above approach with a single class per functionality: solves the giant class problem but creates either a singleton nightmare or dependency injection nightmare.
  • Create another system with the functionality: this is the answer that "sounds" right, but I have no idea how it would work.

Let me know if I can provide any further detail or clarification. Thanks in advance!

share|improve this question
    
Why not have collisionSystem that has method getEntitiesInRange(position, range), then something like AISystem that has method findEnemiesOfEntity using collisionSystems method from above. Then whatever system you want referencing AISystem and using this aisystems method. (I dont know why would you ever want to have AIDefenseSystem and AIAttackSystem though) –  Kikaimaru May 22 '13 at 13:17
    
@Kikaimaru That sounds like it would work; how would the AISystem know what which collision system to use? In my current design I only have one, but how would it work in a more general sense? None of the examples I have worked with have had a system calling another system, is this normal in an ES? (Sorry for all the questions, just want to make sure I understand your suggestion, also the reasoning behind the Attack/Defend system comes from this article) –  Salmonhands May 22 '13 at 19:03
    
Personaly I can't imagine a reason for having multiple collision systems, in my game collision systems handle all collisions so there is no need for another. Note that Byte56 approach requires that his managers has access to all relevant entities, which makes them same thing as your system. By the way only component system that I saw actually working in real games was used in Unity that operated on much higher level components then AttackState –  Kikaimaru May 23 '13 at 7:30
add comment

1 Answer 1

up vote 0 down vote accepted

For my system I use an EntityDirector class. This takes care of common entity tasks, like tracking available entity IDs, reusing removed entities to save allocations, creating/deleting entities, adding/removing entity attributes and so on.

However, there are more specialized classes for different tasks. There's a SpatialEntity manager that has functionality like finding entities within an AABB, within a range of a specific point and other functionality having to do with location.

Then there's a ThreatEntity manager that knows the relationships between entity types. It can be queried for the threats between two entities. There are also functions that utilize the SpatialEntity manager to find all entities that are a threat to an entity.

Basically what I'm saying is, it's up to you. Split out the functionality into basic/simple logical classes. Then combine the simple functionality into more complex functions.

Where to place the more complex functionality depends on what's going to use it and how it's going to be used. This could be as simple as a large EntityUtilities class that contains and combines all the functions you want for your entities.

You can create a filter system for these functions. Where each simple function has a filter that describes the required components for an entity to be queried. For the more complex functions, these filters are combined to filter all the entities that don't have each of the required components to be passed into the functions. This would likely be something like a long, with a bit for each required component.

share|improve this answer
    
That makes a lot of sense, and I think I know where to go from here. Thanks; accepted. –  Salmonhands May 22 '13 at 19:27
add comment

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.