> 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/tasks-timing.md).

# Ability Tasks and Timing

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

Ability tasks are cooperative async work units owned by an `AbilityRuntime`. They let an ability wait for time, input, target data, montage playback, gameplay tags, gameplay events, or attribute changes without hiding cleanup logic.

## What It Does

| Type                                 | Responsibility                                                        |
| ------------------------------------ | --------------------------------------------------------------------- |
| `AbilityTask`                        | Base lifecycle: bind, activate, finish, cancel, await completion.     |
| `ITickAbilityTask`                   | Task receives per-frame ticks from the owning ability.                |
| `IInputAbilityTask`                  | Task receives input press/release callbacks.                          |
| `AbilityTimerTask`                   | Timer-style task helper.                                              |
| `AbilityTask_WaitDelay`              | Completes after a duration.                                           |
| `AbilityTask_WaitInputPress`         | Completes on input press.                                             |
| `AbilityTask_WaitInputRelease`       | Completes on input release.                                           |
| `AbilityTask_WaitGameplayTagAdded`   | Completes when an owned tag is added.                                 |
| `AbilityTask_WaitGameplayTagRemoved` | Completes when an owned tag is removed.                               |
| `AbilityTask_WaitAttributeChange`    | Completes when an attribute changes.                                  |
| `AbilityTask_WaitGameplayEvent`      | Completes when a gameplay event is received.                          |
| `AbilityTask_WaitForTargetData`      | Completes when targeting returns data.                                |
| Montage tasks                        | Wait for montage end, notify, blend-out, or related animation events. |

## When To Use It

Use tasks when an ability needs to remain active across multiple frames:

* Charge until input release.
* Wait 0.5 seconds before impact.
* Wait for target confirmation.
* Play an animation montage and continue at a notify.
* Cancel if a tag is removed.
* React when an effect or attribute changes.

Do not use a task for immediate one-line logic. Run that directly in the runtime.

## Editor Setup

Tasks are authored in code, but their inputs often come from assets:

1. Configure ability fields such as duration, target collector prefab, montage, or tags.
2. In the ability runtime, construct and run the task.
3. Subscribe to task events before or immediately after running it.
4. Call `EndAbility` or continue the next phase when the task finishes.
5. Test cancellation by manually cancelling the ability or adding blocking tags.

There is no generic task asset menu. Task behavior belongs to ability runtime code.

## Runtime Flow

```mermaid
flowchart TD
    Runtime["AbilityRuntime"] --> Run["RunTask(task)"]
    Run --> Bind["Bind ability and ASC"]
    Bind --> Activate["task.Activate"]
    Activate --> Work["Tick, input, event, target, or montage work"]
    Work --> Finish["Finish"]
    Work --> Cancel["Cancel"]
    Finish --> Cleanup["OnFinish cleanup and deregister"]
    Cancel --> ForcedCleanup["Cancel cleanup"]
    Cleanup --> Continue["Ability continues or ends"]
```

A task must be idempotent: calling `Finish()` or `Cancel()` more than once should not cause duplicate cleanup. Base `AbilityTask` guards completion state.

## Built-In Task Patterns

| Task                     | Use                                                          |
| ------------------------ | ------------------------------------------------------------ |
| `WaitDelay`              | Cast time, recovery window, delayed effect.                  |
| `WaitInputPress`         | Confirm hold-to-cast start or chained input.                 |
| `WaitInputRelease`       | Charge-up release.                                           |
| `WaitGameplayTagAdded`   | Continue when actor enters a state.                          |
| `WaitGameplayTagRemoved` | Continue when stun, recovery, or lockout clears.             |
| `WaitAttributeChange`    | React to health threshold or resource change.                |
| `WaitGameplayEvent`      | Wait for hit confirm, combo event, or external script event. |
| `WaitForTargetData`      | Ground targeting, lock-on, multi-target selection.           |
| Montage wait tasks       | Animation-driven gameplay windows.                           |

## Cancellation Rules

Every task must clean up listeners and spawned objects on both natural finish and forced cancel. If a task subscribes to runtime events, it should unsubscribe in `OnFinish()` and `Cancel()`. If a task spawns a target collector or indicator, cancellation should hide or destroy it.

## Timing Scheduler

The ASC registers with the internal scheduler while enabled. `RuntimeAbilities`, `RuntimeEffects`, and `AbilityInputQueue` use ticking for active abilities, timed effects, periodic effects, queued input snapshots, and task updates. Do not create one MonoBehaviour update loop per ability unless the task specifically needs a scene component.

## Debugging Checklist

* If a task never completes, confirm it subscribed to the correct event and the event actually fires.
* If a task completes twice, check that cleanup is idempotent and `Finish()` is not called from multiple paths.
* If cancellation leaves objects in the scene, check `Cancel()` cleanup.
* If a delay seems wrong, confirm the ability remains active and ticking.
* If input tasks never receive input, confirm the ability was activated by an input-bound spec or the runtime forwards input.

## Common Mistakes

| Mistake                                          | Result                                   | Fix                                        |
| ------------------------------------------------ | ---------------------------------------- | ------------------------------------------ |
| Subscribing to events without unsubscribing      | Memory leaks or duplicate callbacks      | Clean up in finish and cancel.             |
| Calling `Finish()` inside `Cancel()`             | Deregistration can run in the wrong path | Override cancel cleanup without finishing. |
| Using tasks with `NonInstanced` abilities        | Shared runtime state problems            | Use instanced policies.                    |
| Spawning collectors without cancellation cleanup | Targeting objects remain in scene        | Destroy or hide in cancel.                 |

## Extension Points

* Subclass `AbilityTask`.
* Implement `ITickAbilityTask` for per-frame work.
* Implement `IInputAbilityTask` for input press/release work.
* Use UniTask completion if callers need to await task completion.

## Examples and Tests

* Cookbook: Charge-Up Ability, Channeled Ability, Ground-Targeted AoE.
* Tests: `DevelopmentTests/GameplayAbilityToolkit/Core.Tests/Editor/Tasks/AbilityTaskContractTests.cs`, `InputHoldDoubleTapTaskTests.cs`, `MontageTaskTests.cs`, `ReactiveTaskTests.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/tasks-timing.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.
