Right way to model per limb health with GAS?

Hello,

We’re working on a multiplayer project with the GAS and we want to implement a localized damage system. Each body part should have its own health and be individually affected by gameplay effects (e.g. poison affects the chest, neurotoxin affects head, fall damage hits the legs), like in Deus Ex or Fallout NV.

Concretely, we want our Health Component (shared by all entities in the game) to configure body parts through Data Assets, then expose a function like: TakeDamage(BodyPartTag, DamageAmount) to be used by various other components (fall damage, weapons, etc.).

We’re struggling to figure out how to cleanly model and route body part data:

  • The ASC does not support multiple Attribute Sets of the same type, so we can’t have one per body part;

  • An Attribute Set cannot contain maps or arrays, so we can’t index body part data this way from the component;

  • Hard-coding body part sets in one or multiple attribute sets would require branching logic in the component and knowledge of all possible body parts, which we want to avoid;

  • We could pass a gameplay tag as parameter to damage gameplay effects, then map tag → attribute data in the attribute set’s post effect callback. This should work, but I’m not sure if it’s a good idea;

  • Store and replicate health in the component instead of GAS and use gameplay effects to mutate the component.

Does anyone know the idiomatic way to achieve what we want? We can get it to work somehow, but I’d like to know the best way. Looking forward to your opinions!

Hi, nice question by the way!

I think you can still work within GAS for this. You can have additional Attribute Sets for body parts per archetype, just not multiple instances of the same set type. The trick is really how you route damage to them.

One approach that works well is forwarding the body part information into an Execution Calculation. Let the execution handle things like damage reduction, armor, and any modifiers first. After that, the execution can look at what attributes the owner actually has and propagate the result to the correct one.

You’ll probably want some kind of naming or convention there (for example sub-health_leg, sub-health_head, etc.) so the execution can find the right attribute. If that attribute exists, apply the damage. If it doesn’t, you can define a fallback rule for what should happen in that case.

About the branching if you are saying having different AttributeSetClasses (ULegAttributeSet , UCommonAttributeSet) is not something desirable maybe can be a single one containing all possible archetype limbs in the game with hardcoding which is imo more uglier. Is there a problem with classes of attributes for each body part? Since its more extendable from my point of view?

From there it’s just normal GAS flow again: the attribute changes, events fire, cues play, gameplay reacts. Lose an arm, trigger a cue, disable an ability, whatever your game needs.

You can also go for a more decoupled setup where body parts are predefined per archetype, matched to bones, and owned by a separate damage component. That component becomes the middleman between hit detection and GAS. It works, but in my experience it’s usually more complex than needed.

Personally I’d start with the first approach. Keeping health in attributes makes it much easier to integrate with the rest of gameplay logic and evolve it over time. For the component depending on t he gameplay logic you want think available attirbutes can be search on construction and health component as middle man tracks that in different archetypes.