> Should the shield be its own entity
> that tracks the location of the
> player? That might make it hard to
> implement the damage filtering. It
> also kinda blurs the lines between
> attached components and entities.
No
> Should the shield be a component that
> houses other components? I've never
> seen or heard of anything like this,
> but maybe it's common and I'm just not
> deep enough yet.
See it in a different perspective; adding a component adds other components as well, and upon removal, the additional components are gone too.
> Should the shield just be a set of
> components that get added to the
> player? Possibly with an extra
> component to manage the others, e.g.
> so they can all be removed as a group.
> (accidentally leave behind the damage
> reduction component, now that would be
> fun).
This could be a solution, it would promote reuse, however it is also more error prone (for the issue you mentioned, for instance). It's not necessarily bad. You might find out new spell combinations with trial and error :)
> Something else that's obvious to
> someone with more component
> experience?
I'm going to elaborate a bit.
I believe you noticed how some components should take priority no matter when they've been added to an entity (this would answer your other question as well).
I'm also going to assume we're using message-based communication (for the sake of discussion, it's just an abstraction over a method call for the moment).
Whenever a shield component is "installed", shield component message handlers are chained with a specific (higher) order.
Handler Stage Handler Level Handler Priority
In Pre System High
Out Invariant High
Post AboveNormal
Normal
BelowNormal
Low
System Low
In - incoming messages
Out - outgoing messages
Index = ((int)Level | (int)Priority)
The "stats" component installs a "damage" message handler at the In/Invariant/Normal index.
Every time a "damage" message is received, decrease the HP by its "value" amount.
Fairly standard behaviour (put in some natural damage resistance and / or racial traits, whatever).
The shield component installs a "damage" message handler at the In/Pre/High index.
Every time a "damage" message is received, deplete the shield energy and substract
the shield energy from the damage value, so that the damage down the message
handler pipeline is reduced.
damage -> stats
stats
stats.hp -= damage.value
damage -> shield -> stats
shield
if(shield.energy) {
remove_me();
return;
}
damage.value -= shield.energyquantum
shield.energy -= shield.energyquantum;
stats
stats.hp -= damage.value
You can see this is pretty flexible, albeit it would require careful planning when designing component interaction, as you're going to have to determine in which part of the message handling pipeline component message event handlers are installed.
Makes sense? Let me know if I can add more detail.