> 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/build-with-it/03-authoring-abilities.md).

# Authoring Abilities

> Online doc: <https://morningheartgames.gitbook.io/docs/gameplay-ability-toolkit/foundations/03-authoring-abilities?fallback=true>

Abilities are reusable actions: attacks, spells, item uses, interactions, AI moves, channels, dodges, and scripted gameplay moments.

In Gameplay Ability Toolkit, an ability is usually built from one `ScriptableObject` definition and one runtime class.

![Practical ability lifecycle diagram showing activation checks, commit, active state, finish, and cancel paths.](/files/BXklKqeWQh2BaGVPBo06)

## Use This Page When

| You want to build...                                                  | Start with                                                                     |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| A simple attack, spell, dodge, item use, or interaction               | An `AbilityDefinition` asset with tags, costs, cooldowns, and granted effects. |
| An ability that waits, channels, targets, spawns, or reacts over time | A concrete `AbilityRuntime` with ability tasks or custom activation logic.     |
| A designer-tunable variant                                            | Shared runtime code plus different definition assets.                          |
| A one-off prototype                                                   | The smallest definition/runtime pair, then move repeated values into assets.   |

Prefer asset configuration first. Write custom runtime code when the ability needs multi-step behavior, temporary state, async waits, custom targeting, or cleanup.

## Editor Entry Points

The fastest editor path is the Dashboard **Abilities** page.

![Unity Editor screenshot of the Dashboard Abilities page.](/files/IJvKLtJvOgsB4ZUPJ5cI)

Open it from:

```
Tools > Gameplay Ability Toolkit > Dashboard > Abilities
```

Use this page when you want to:

| Action                                                             | Dashboard control                      |
| ------------------------------------------------------------------ | -------------------------------------- |
| Generate a new ability definition/runtime script pair              | **Ability Script > Create**            |
| Create an asset from an existing concrete `AbilityDefinition` type | **Ability Asset > Create**             |
| Check how many concrete ability types are available                | **Concrete Ability Types** status card |
| Jump back to shared asset creation                                 | **Core Authoring > Open**              |

You can also create ability assets from the Project window:

```
Project window right-click > Create > Gameplay Ability Toolkit > Ability Asset...
```

![Unity Editor screenshot of the Create Ability Asset picker.](/files/wh1RKiz6z5yI3cP5Nc68)

## The Three Layers

| Layer      | Type                | Responsibility                                                  |
| ---------- | ------------------- | --------------------------------------------------------------- |
| Definition | `AbilityDefinition` | Tags, costs, cooldowns, granted effects, triggers, editor data. |
| Runtime    | `AbilityRuntime`    | Activation logic, tasks, targeting, custom state, cleanup.      |
| Spec       | `AbilitySpec`       | Per-actor wrapper and activation entry point.                   |

```mermaid
flowchart LR
    Def["AbilityDefinition asset"]
    Spec["AbilitySpec on an actor"]
    Runtime["AbilityRuntime instance"]
    Effects["Apply effects, tasks, cues, tags, and targeting"]

    Def --> Spec --> Runtime --> Effects
```

## Minimal Ability

Create a definition class and return a runtime instance:

```csharp
using GameplayAbilityToolkit.Core;
using UnityEngine;

[CreateAssetMenu(menuName = "Gameplay Ability Toolkit/Demo/Punch Ability")]
public sealed class PunchAbilityDefinition : AbilityDefinition
{
    public override AbilityRuntime CreateRuntime() => new PunchAbilityRuntime();
}

public sealed class PunchAbilityRuntime : AbilityRuntime
{
    protected override void OnActivate(GameplayEventData eventData)
    {
        Logger.Info(LogCategory.Ability, "Punch activated");
        EndAbility();
    }

    protected override void OnEnd(bool wasCancelled)
    {
        // Release temporary state, listeners, spawned objects, or task resources here.
    }
}
```

After the script compiles, create the asset from the Create menu, grant it to an actor, and activate it through code, input, or a gameplay event.

### Create The Asset In The Editor

1. Open `Tools > Gameplay Ability Toolkit > Dashboard`.
2. Click **Abilities** in the left navigation.
3. In **Ability Asset**, click **Create**.
4. Use the search box if the list is long.
5. Find your concrete ability definition type.
6. Click **Create**.
7. Save the new asset in your chosen `Abilities/` folder.
8. Rename the asset with the `GA_` prefix, such as `GA_Punch`.

The picker only lists concrete, non-abstract `ScriptableObject` types derived from `AbilityDefinition`. If your new class does not appear, check that it compiled, is not abstract, and is not inside a test assembly.

### Configure The Ability Asset

After creating the asset, inspect these groups first:

| Inspector area  | What to configure                                                  |
| --------------- | ------------------------------------------------------------------ |
| Tags            | Ability identity, required tags, blocked tags, cancel/block rules. |
| Costs           | Cost modifiers or a generated cost effect.                         |
| Cooldowns       | Cooldown duration and cooldown tags.                               |
| Triggers        | Gameplay event or tag-based auto-activation.                       |
| Granted effects | Effects that should apply during activation or commit.             |
| Custom fields   | Fields declared by your concrete definition class.                 |

Keep the first version small: one ability tag, one cost, one cooldown, one target/effect path, then test.

## Instancing Policy

The instancing policy controls how runtime objects are reused.

| Policy                  | Runtime lifetime           | Use it when                                                                                                   |
| ----------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `NonInstanced`          | Shared singleton           | The ability has no mutable per-actor or per-activation state.                                                 |
| `InstancedPerActor`     | One runtime per actor      | The ability has state, but only one activation should run on that actor at a time. This is the usual default. |
| `InstancedPerExecution` | One runtime per activation | The ability can overlap with itself or needs isolated multi-phase state per activation.                       |

Decision rule:

```mermaid
flowchart TD
    State["Does runtime logic hold mutable state?"]
    Shared["Use NonInstanced"]
    Overlap["Can the same actor run overlapping activations?"]
    Actor["Use InstancedPerActor"]
    Exec["Use InstancedPerExecution"]

    State -- "No" --> Shared
    State -- "Yes" --> Overlap
    Overlap -- "No" --> Actor
    Overlap -- "Yes" --> Exec
```

## Costs and Cooldowns

Costs and cooldowns are normal gameplay effects applied during commit.

Recommended cost ability:

1. Add cost modifiers to the ability definition's `Costs` list.
2. Click **Generate / Refresh Cost Effect** in the inspector.
3. Let the generated child `EffectDefinition` handle the actual attribute mutation.

Cooldowns resolve through `GetCooldown(level)` and create a duration cooldown effect with the configured cooldown tags.

### Cost Authoring Checklist

1. Select the ability asset.
2. Add one or more cost modifiers to the `Costs` list.
3. Click **Generate / Refresh Cost Effect** in the Inspector.
4. Confirm the generated child/sub-asset exists.
5. Enter Play Mode and activate the ability.
6. Verify the resource attribute changes before the ability performs its main effect.

If `Costs` is non-empty but the generated cost effect is missing, validation should warn in the Inspector.

### Cooldown Authoring Checklist

1. Select the ability asset.
2. Set the cooldown duration through the level-based value field.
3. Assign cooldown tags if your UI or activation rules need tag checks.
4. Enter Play Mode and activate the ability.
5. Try activating again before cooldown ends.
6. Watch for `EventAbilityActivationFailed` or HUD cooldown feedback.

Useful HUD reads:

```csharp
asc.TryGetAbilityCooldownRemaining(definition, out float seconds);
asc.TryGetAbilityCooldownNormalized(definition, out float zeroToOne);
```

`zeroToOne` is suitable for radial fills or disabled-state overlays.

## Activation Triggers

An ability can activate from several sources:

| Source         | Configuration                                                 |
| -------------- | ------------------------------------------------------------- |
| Direct code    | Call runtime ability APIs on the actor's ASC.                 |
| Input          | Bind logical input IDs through an `AbilityInputBindingSet`.   |
| Gameplay event | Add an `AbilityTriggerData` entry for the matching event tag. |
| Tag added      | Add a trigger for an owned tag appearing on the actor.        |
| Tag removed    | Add a trigger for an owned tag leaving the actor.             |

Input wiring lives in `Tools > Gameplay Ability Toolkit > Dashboard` and input binding assets. The ability definition owns the activation rules; the input layer only says which logical input occurred.

### Grant And Bind In The Editor

For a scene actor:

1. Select the actor GameObject.
2. Find its `AbilitySystemComponent` or setup component.
3. Add the `GA_*` asset to the granted/initial ability list used by that actor.
4. Assign an input binding set in the actor's initial input field, if input activation is needed.

For a binding asset:

1. Select the input binding asset.
2. Add a new entry.
3. Choose the logical input ID.
4. Assign the `GA_*` ability asset.
5. Enable press/release behavior that matches the ability.

Keep the logical input name identical across the input source, input library, and binding set.

## Tag Filters

Tag filters make activation rule-driven:

| Field                                      | Meaning                                                   |
| ------------------------------------------ | --------------------------------------------------------- |
| `AbilityTags`                              | What this ability is. Used by block/cancel matching.      |
| `ActivationOwnedTags`                      | Tags granted to the activating actor while active.        |
| `ActivationRequiredTags`                   | Actor must have these tags to activate.                   |
| `ActivationBlockedTags`                    | Actor must not have these tags to activate.               |
| `SourceRequiredTags` / `SourceBlockedTags` | Same idea for the instigator.                             |
| `TargetRequiredTags` / `TargetBlockedTags` | Same idea for the target.                                 |
| `BlockAbilitiesWithTags`                   | While active, prevent matching abilities from activating. |
| `CancelAbilitiesWithTags`                  | On activation, cancel already-active matching abilities.  |

`OnValidate` warns on common mistakes such as self-blocking tags.

### Common Tag Setups

| Pattern                                | Fields                                                                    |
| -------------------------------------- | ------------------------------------------------------------------------- |
| Attack owns state while active         | `ActivationOwnedTags = State.Attacking`                                   |
| Dodge blocks damage handling elsewhere | Effect or ability grants `State.Invulnerable`                             |
| Silence blocks spell abilities         | `ActivationBlockedTags = State.Silenced` on spells                        |
| Stun blocks most actions               | Runtime effect grants a blocked-ability tag or state checked by abilities |
| Combo cancels previous stage           | `CancelAbilitiesWithTags` targets earlier combo tags                      |

Add tags to the project tag asset before assigning them. Unknown tags are harder to debug than missing object references because they often look like valid strings.

## Ability Tasks

Use `AbilityTask` derivatives for delayed, asynchronous, or multi-frame ability logic. Prefer them over coroutines for gameplay timing because they run inside the toolkit's tick model.

Built-in tasks include:

| Task                               | Purpose                                                          |
| ---------------------------------- | ---------------------------------------------------------------- |
| `AbilityTask_WaitDelay`            | Wait for framework-driven time.                                  |
| `AbilityTask_WaitForTargetData`    | Run a target collector and wait for confirm/cancel.              |
| `AbilityTask_PlayMontageAndWait`   | Play an `AnimationMontage` through the current animation driver. |
| `AbilityTask_WaitInputPressed`     | Wait for a bound input press.                                    |
| `AbilityTask_WaitInputReleased`    | Wait for a bound input release.                                  |
| `AbilityTask_WaitForGameplayEvent` | Wait for a gameplay event tag.                                   |

Tasks compose through UniTask awaiters and runtime callbacks.

## Custom Runtime Hooks

Override the smallest hook that matches your behavior:

| Hook                            | Use it for                                                                        |
| ------------------------------- | --------------------------------------------------------------------------------- |
| `OnActivate(GameplayEventData)` | Main activation body. Apply effects, start tasks, spawn targeting, play montages. |
| `OnEnd(bool wasCancelled)`      | Cleanup that must run after success, cancellation, or early exit.                 |
| `CanActivateAbility(...)`       | Additional preconditions beyond tags, costs, and cooldowns.                       |
| `CheckCost(...)`                | Custom cost rules.                                                                |
| `CheckCooldown(...)`            | Custom cooldown rules.                                                            |

Call `EndAbility()` when the ability has finished. Long-running abilities should end from task completion, input release, montage completion, or cancellation.

## Editor Debugging Checklist

When an ability does not activate:

1. Select the actor and confirm it has an initialized ASC.
2. Confirm the ability asset is granted to that actor.
3. Confirm the input source is raising the same logical input ID used by the binding.
4. Confirm required tags are present and blocked tags are absent.
5. Confirm cost and cooldown checks pass.
6. Watch `EventAbilityActivationFailed` or the `GAS Event Log` if your scene has one.
7. Temporarily activate the ability from code to isolate input wiring from ability rules.

## Next Steps

* Read [Authoring Effects](/docs/gameplay-ability-toolkit/build-with-it/04-authoring-effects.md) to build the damage, costs, buffs, and cooldowns your ability applies.
* Follow [How To Add an Ability](/docs/gameplay-ability-toolkit/tutorial-details/howtoaddability.md) for a hands-on tutorial addition.
* Inspect the [Arena Demo](/docs/gameplay-ability-toolkit/try-it/arena.md) for combo, projectile, dodge, channel, and ground-targeting examples.


---

# 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/build-with-it/03-authoring-abilities.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.
