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 was thinking of how to implement overriding of behaviors in a component based entity system. A concrete example, an entity has a heath component that can be damaged, healed, killed etc. The entity also has an armor component that limits the amount of damage a character receives.

Has anyone implemented behaviors like this in a component based system before?
How did you do it?

If no one has ever done this before why do you think that is. Is there anything particularly wrong headed about overriding component behaviors?

Below is rough sketch up of how I imagine it would work. Components in an entity are ordered. Those at the front get a chance to service an interface first. I don't detail how that is done, just assume it uses evil dynamic_casts (it doesn't but the end effect is the same without the need for RTTI).

class IHealth
{
public:
   float get_health( void ) const = 0;
   void do_damage( float amount ) = 0;
};

class Health : public Component, public IHealth
{
public:
   void do_damage( float amount )
   {
      m_damage -= amount;
   }
private:
   float m_health;
};

class Armor : public Component, public IHealth
{
public:
   float get_health( void ) const
   {
      return next<IHealth>().get_health();
   }

   void do_damage( float amount )
   {
      next<IHealth>().do_damage( amount / 2 );
  }
};

entity.add( new Health( 100 ) );
entity.add( new Armor() );
assert( entity.get<IHealth>().get_health() == 100 );
entity.get<IHealth>().do_damage( 10 );
assert( entity.get<IHealth>().get_health() == 95 );

Is there anything particularly naive about the way I'm proposing to do this?

share|improve this question
    
Please see my answer here: gamedev.stackexchange.com/questions/13916/…. If linking to one own answers is frowned upon, please mods remove this. –  Raine Jun 20 '11 at 7:14
2  
Is there a specific reason why you create an extra interface for IHealth and then use multiple inheritance further down instead of having IHealth inherit from Component and then have Armor and Health inherit from IHealth alone? –  TravisG Jun 20 '11 at 8:25
    
@heishe: I was worried that a component may want to implement two disparate interfaces, ie IHealth and IKnockback. It would not make sense to join those two components in a single class hierarchy. Multiple inheritance is always troublesome I had considered having Shield use a proxy member class that derives from IHealth and then forwards all calls to Shield. With that implementation technique there is no MI at the expense of an extra non-virtual method call (which the optimizer may be able to inline). In either case the API (add, get, next, etc) is the same. –  deft_code Jun 20 '11 at 14:19
add comment

3 Answers

I think you're making it a little too complicated, or not complicated enough.

One direction I would suggest would be to break apart getting health and doing damage interfaces.

So maybe as an idea, your Armor component would look like this:

class Armor : public Component, public IDamageReceiver
{
public:
   void do_damage( float amount )
   {
      // just assume that subtract_health isn't used in client code maybe
      this.get<IHealth>().subtract_health( amount / 2 ); 
   }
};

Alternatively (and probably what I would do), you could make your components a little bigger and just have a generic "Entity" base class that your specific types derive from. This would contain the functionality of both health and armor and you could implement specific entities from that.

share|improve this answer
    
Your solution doesn't quite address my problem. I want to add the Armor component without adjusting any of the pre-existing components. Done right, I think you could just add two armor components and it would do the right thing (reduce damage to 25%). In other words with a general override solution I could override the overrides. –  deft_code Jun 20 '11 at 5:48
3  
I kind of agree with Tetrad here. I think you're making your system way too complex and granular. I would say if you want to override component X, find component X in the relevant entities and swap it out with component Y that does what you want. –  Josh Petrie Jun 20 '11 at 14:56
1  
@deft_code Based on what you said and your other post about components before this one. I think you want to introduce a 'CharacterEffects' (not using power ups as they may be bad at times :)) type of component where you could create (de)buffs to apply to a character. This will still require the health component to be updated to scan for associated effects to see if any apply, but it comes down to needing a new component type rather than inheriting from health and Not replacing health. Alternately, make your component system have a stack so there is guaranteed order of execution/resolution. –  James Jun 22 '11 at 23:10
add comment

Your thoughts are in the right place but I think you are trying to take the component system to a level of detail that it does not need. I would say make a component called Health when all you need is straight up health. But if you need a health component that also has armor in it, then make it a CHealthAndArmor component that still fits the API of Health in general so it can be used like any other, but then provide the manner of also changing the armor levels if needed.. If its completely a load time value then there is no need, that's just the internal workings of that particular health component.

Honestly the concerns you are having (from this and your other post) are how fine a level of detail you break components down into. If you ever find yourself inheriting or encapsulating a component within another component, you should reconsider what you are doing. You generally are trying to avoid inheritance like this in component based architectures.

Hope this helps

share|improve this answer
1  
Making a HealthAndArmor component kind of defeats the purpose of a component based architecture. –  Mitchell Nov 20 '12 at 8:17
    
@Mitchell That all depends on the game really. If your armor is nothing more than extra health like in the old Doom/Quake style games then splitting these things apart would be a complete waste. Your components should match your environment and game. –  James Nov 20 '12 at 17:21
    
I disagree, splitting them allows for easy modification in the future, and the change from 'armor and health' to 'health' only requires the removal of armor, instead of the removal of HealthAndArmor and the adding of Health. It might seem insignificant, but it can become really annoying when you're prototyping a lot. But I guess it also depends on your entity manager. –  Mitchell Nov 27 '12 at 8:15
    
@Mitchell I guess we just will have to disagree then.. I have always seen components as something you tailor to the game/application in question. Sure you gather a nice collection of them over time depending on how many projects you use/reuse the system for, but the entire point of component system to me is to create more complicated objects out of simple and specific smaller objects. –  James Nov 27 '12 at 18:02
add comment

Your Component stuff is too much OOP. See what I'm doing here:

https://github.com/thelinuxlich/starwarrior_CSharp

And this is the Entity System framework I've ported to C#: https://github.com/thelinuxlich/artemis_CSharp

share|improve this answer
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.