I'm just starting really getting my head around component based design. I don't know what the "right" way to do this is.

Here's the scenario. The player can equip a shield. The the shield is drawn as bubble around the player, it has a separate collision shape, and reduces the damage the player receives from area effects.

How is such a shield architected in a component based game?

Where I get confused is that the shield obviously has three components associated with it.

Damage reduction / filtering

A sprite

A collider.

To make it worse different shield variations could have even more behaviors, all of which could be components:

boost player maximum health

health regen

projectile deflection

etc

Am I overthinking this? Should the shield just be a super component?
I really think this is wrong answer. So if you think this is the way to go please explain.

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.

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.

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).

Something else that's obvious to someone with more component experience?

5 Answers
5

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.

Edit: I think there's not enough "autonomous behaviour" for a separated entity. In this specific case, a shield follows the target, works for the target and does not outlive the target. While I tend to agree that there's nothing wrong with the concept of a "shield object", in this case we're dealing with behaviour, which fits just fine in a component. But I'm also an advocate of purely logical entities (as opposed to full-blown entity systems in which you can find Transform and Rendering components).

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).

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.

Edit: regarding multiple component instances (two armour components). You can either keep track of the total instance count in just one entity instance (this kills per-component state, however) and just keep adding message event handlers, or make sure your component containers allow for duplicate component types in advance.

You've replied "No" to the first question without giving any reason. Teaching others is about helping them to understand the reasoning behind any decision. IMO, the fact that in RL a force field would be a separate "physical entity" from your own body is enough to let it be a separate entity in code. Can you suggest good reasons to suggest why going this route is bad?
–
Arcane EngineerJun 20 '11 at 14:29

@Nick, I am by no means trying to teach anything to anyone, rather sharing what I know on the subject. I am however going to add a rationale behind that "no" that hopefully will remove that unpleasant downvote :(
–
RaineJun 20 '11 at 15:22

Your autonomy point makes good sense. But you note: "in this case we're dealing with behaviour". True -- behaviour involving an entirely separate physical object (the shield collision shape). For me, one entity ties to one physics body (or compound set of bodies connected eg. by joints). How do you reconcile this? For my part, I would feel uncomfortable adding a "dummy" physical fixture which would activate only if the player happens to use a shield. IMO inflexible, hard to maintain across all entities. Consider too, a game where shield belts keep shields on even after death (Dune).
–
Arcane EngineerJun 20 '11 at 16:04

@Nick, the majority of entity systems have both logical and graphics-related components alike, so, in this case, having an entity for a shield is absolutely reasonable. In purely logical entity systems, "autonomy" is the product of how complex an object is, its dependencies and lifetime. In the end, requirement is king - and considering that there's no real consensus about what an entity system is, there's plenty of room for project-tailored solutions :)
–
RaineJun 20 '11 at 17:32

It not clear what this means in your answer. Is this referring to the Shield component or did you mean the entity that's using the shield, its parent? The confusion might be my fault. "Component based" is kinda vague. In my version of component based entities, an entity is simply a component container with some minimal functionality of its own (object name, tags, messaging, etc).
–
deft_codeJun 20 '11 at 5:54

It would be less confusing if I used gameObject or something. It's a reference to the current game object/entity/whatever owns the components.
–
Tetrad♦Jun 20 '11 at 6:18

A shield, as a physical entity, is no different from any other physical entity, e.g. a drone which circles around you (and which in fact, could itself be a type of shield!). So make the shield a separate logical entity (thus allowing it to hold its own components).

Give your shield a couple of components: a Physical/Spatial component to represent it's collision form, and a DamageAffector component which holds a reference to some entity to whom it will apply increased or reduced damage (eg. your player character) every time the entity holding the DamageAffector takes damage. Thus your player is taking damage "by proxy".

Set the shield entity's position to the player's position every tick. (Write a reusable component class that does this: write once, use many times.)

You will need to create the shield entity, eg. on collecting a powerup. I use a generic concept called an Emitter, which is a type of entity component that spawns new entities (usually through the use of an EntityFactory which it references). Where you decide to locate the emitter is up to you -- eg. put it on a powerup and have it trigger as the powerup is collected.

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.

There is a fine line between logical subcomponents (Spatial, AI, Weapon slots, Input-processing etc. etc.) and physical subcomponents. You need to decide which side of it you stand on, as this strongly defines what sort of entity system you have. For me, the Physics subcomponent of my Entity handles the physics-hierarchical relationships (such as limbs in a body -- think scenegraph nodes), while the logic controllers noted above are typically what are represented by your entity components -- rather than these representing individual physical "fixtures".

If your component system allows scripting, the shield component could be almost a super component that just calls a script for its "effect" parameter. That way you maintain simplicity of a single component for shields, and offload all the logic of what it actually does to custom script files that get fed to shields by your entity definitions.

I do something similar for my Moveable component, it countains a field that is of keyreaction script (a subclass of script in my engine) this script defines a method that follows my input message. as such i can simply do something like this in my tempalte definition file