> For the complete documentation index, see [llms.txt](https://morningheartgames.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://morningheartgames.gitbook.io/docs/gameplay-ability-toolkit/subsystems/attributes.md).

# Attributes

> Online doc: <https://morningheartgames.gitbook.io/docs/gameplay-ability-toolkit/subsystems/attributes?fallback=true>

Attributes represent numeric actor state: Health, MaxHealth, Mana, Stamina, Damage, Armor, temporary derived values, and any other stat that effects or abilities need to read or modify.

![Practical attribute aggregation diagram showing authored values, modifiers, and a clamped runtime result.](/files/m9i3dzORWyF6vug4XrKV)

## What It Does

The attribute subsystem separates authoring data from actor runtime values.

| Layer                | Type                                                  | Responsibility                                                                         |
| -------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------- |
| Attribute definition | `AttributeDefinition` inside `AttributeSetDefinition` | Name, base value, clamping config, derived flag, stable GUID.                          |
| Attribute set asset  | `AttributeSet`                                        | Chooses one or more definitions and optional per-actor overrides.                      |
| Runtime attribute    | `RuntimeAttribute`                                    | Per-actor base/current value, modifiers, clamp behavior, change events.                |
| Runtime subsystem    | `RuntimeAttributes`                                   | Owns all runtime attributes for one ASC, applies modifiers, recalculates dirty values. |

## When To Use It

Use attributes for values that:

* Need effects or costs to modify them.
* Need UI display.
* Need clamps such as `Health <= MaxHealth`.
* Need change hooks, damage popups, or death logic.
* Need deterministic current/base value separation.

Do not use attributes for one-off booleans. Use [Gameplay Tags](/docs/gameplay-ability-toolkit/subsystems/tags.md) for states such as `State.Stunned`, `Status.Burning`, or `Weapon.Equipped`.

## Editor Setup

Create the definition:

1. Right-click in the Project window.
2. Choose `Assets > Create > Gameplay Ability Toolkit > Attributes > AttributeSetDefinition`.
3. Name the asset `ASDef_Character`.
4. Add attributes such as `Health`, `MaxHealth`, `Mana`, `Damage`, and `Armor`.
5. Configure base values and clamping.

Create the actor set:

1. Choose `Assets > Create > Gameplay Ability Toolkit > Attributes > AttributeSet`.
2. Name the asset `AS_Player` or `AS_Enemy`.
3. Add `ASDef_Character`.
4. Enable overrides for actor-specific base values.
5. Assign the `AttributeSet` to `Inspector > AbilitySystemComponent > Initial Attributes`.

## Configuration Fields

| Field            | Where                 | Meaning                                                                                        |
| ---------------- | --------------------- | ---------------------------------------------------------------------------------------------- |
| Attribute name   | `AttributeDefinition` | The readable name used by `AttributeId.Create(definition, name)`.                              |
| Base value       | `AttributeDefinition` | Default value for actors that do not override it.                                              |
| Stable GUID      | `AttributeDefinition` | Persistent identity used by drawers and serialized IDs. Generated automatically.               |
| Clamping config  | `AttributeDefinition` | Optional min/max or max-attribute clamp behavior.                                              |
| Is derived       | `AttributeDefinition` | Transient value reset after effect execution. Useful for execution-only values such as Damage. |
| Override enabled | `AttributeSet`        | Allows one actor set to replace the definition base value.                                     |
| Override value   | `AttributeSet`        | Actor-specific starting base/current value.                                                    |

## Runtime Flow

```mermaid
flowchart TD
    SetDef["AttributeSetDefinition"] --> SetAsset["AttributeSet"]
    SetAsset --> ASC["AbilitySystemComponent Initial Attributes"]
    ASC --> Runtime["RuntimeAttributes"]
    Runtime --> Values["RuntimeAttribute values"]
    Effect["Effect modifiers"] --> Runtime
    Runtime --> Clamp["Clamp and derived reset"]
    Clamp --> Events["Attribute change events"]
    Events --> UI["HUD, popups, hooks"]
```

`RuntimeAttributes` creates per-actor `RuntimeAttribute` instances during ASC initialization. Effects add persistent modifiers or apply instant modifier deltas. Dirty attributes are recalculated, clamped, and then surfaced through events.

## Base vs Current Values

| Value         | Meaning                                                          | Typical writes                                              |
| ------------- | ---------------------------------------------------------------- | ----------------------------------------------------------- |
| Base value    | Long-lived actor value before active duration/infinite modifiers | Permanent upgrades, healing as state mutation, stat growth. |
| Current value | Final value after active modifiers and clamps                    | UI display, gameplay checks, immediate damage application.  |

Instant effects usually write to current values. Duration and infinite effects usually add modifiers that affect the current value while active.

## Clamping

Use clamping when a value must remain inside a valid range:

* Health can clamp between `0` and `MaxHealth`.
* Mana can clamp between `0` and `MaxMana`.
* Armor can clamp at `0` if negative armor is not part of your design.

If a max attribute changes, dependent clamped attributes are recalculated. For example, lowering `MaxHealth` should also adjust `Health` if `Health` is above the new max.

## Derived Attributes

Derived attributes are execution-time pass-through values. The common pattern is:

1. An effect calculation writes `Damage`.
2. Attribute hooks or calculations use `Damage` to reduce `Health`.
3. The derived `Damage` value resets after execution.

Use derived attributes when you need temporary numeric context, not persistent actor state.

## Practical Usage Patterns

Read current Health:

```csharp
var id = AttributeId.Create(characterDefinition, "Health");
if (asc.RuntimeAttributes.GetAttributeCurrentValue(id, out float health))
{
    // Display or branch on health.
}
```

Write base value:

```csharp
asc.RuntimeAttributes.ModifyAttributeBase(id, newBaseValue);
```

Attach an actor-specific hook:

```csharp
public sealed class DeathHook : MonoBehaviour, IAttributeChangeHook
{
    public float BeforeAttributeChange(AttributeId id, float newValue, float currentValue)
    {
        return newValue;
    }
}
```

## Debugging Checklist

* If an attribute cannot be found, confirm the same `AttributeSetDefinition` asset is used when constructing the `AttributeId`.
* If a value starts wrong, inspect the `AttributeSet` override toggles.
* If a value ignores active effects, inspect the ASC `Effects` tab to confirm the effect is active and not inhibited.
* If a value exceeds its max, inspect the attribute's clamping config.
* If a derived value persists, confirm it is marked as derived in the definition.

## Common Mistakes

| Mistake                                   | Result                                     | Fix                                    |
| ----------------------------------------- | ------------------------------------------ | -------------------------------------- |
| Renaming an attribute casually            | Serialized references can become confusing | Prefer stable naming once assets ship. |
| Using attributes for status flags         | Hard to query and count                    | Use gameplay tags.                     |
| Forgetting the actor `AttributeSet`       | Effects cannot find target attributes      | Add the set to `Initial Attributes`.   |
| Writing UI against definition base values | HUD ignores runtime modifiers              | Read from `RuntimeAttributes`.         |

## Extension Points

* Override `AttributeSetDefinition.CreateRuntimeAttribute()` to return a custom `RuntimeAttribute`.
* Implement `IAttributeChangeHook` on the actor for pre-change or post-execution behavior.
* Use custom modifier calculators when attribute values depend on level or source/target captures.

## Examples and Tests

* Basic Tutorial: Health, Mana, Damage, and UI bars.
* Arena Demo: player/enemy stats, status bars, combat popups.
* Tests: `DevelopmentTests/GameplayAbilityToolkit/Core.Tests/Editor/Attributes/AttributeClampContractTests.cs`, `AttributeChangeHookTests.cs`, `RuntimeAttributeSubclassHookTests.cs`, `AttributeWritePathParityTests.cs`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://morningheartgames.gitbook.io/docs/gameplay-ability-toolkit/subsystems/attributes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
