> 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-ecs/build-with-it/delivery.md).

# Abilities that reach other actors

An ability on its own acts on its owner: it pays its cost, starts its cooldown and applies its effects to the actor that used it. This page shows how to make an ability that hits other actors, such as a nova, a sword swing, a bite or a fireball, by filling in fields instead of writing code. A **delivery ability** says where to look, whom to hit and what to apply. The delivery systems find the actors and apply the effects.

By the end you will be able to:

* make a delivery ability with the New Ability window, and know what each setting does;
* choose a shape (area, arc, nearest or projectile), filter targets by tag, and decide when the hit lands;
* have an actor ask for its abilities by itself, on an input action, or as a combo;
* react to hits from code, and replace the target search or the projectile movement with your own systems.

**Before you start**

* You have an ECS scene that runs: a SubScene with a catalog and an actor. [Getting started](/docs/gameplay-ability-toolkit-ecs/start/getting-started.md) builds one.
* You know how abilities and effects are authored. The toolkit's [Authoring Abilities](https://morningheartgames.gitbook.io/docs/gameplay-ability-toolkit/foundations/03-authoring-abilities) and [Authoring Effects](https://morningheartgames.gitbook.io/docs/gameplay-ability-toolkit/foundations/04-authoring-effects) pages describe them.
* The project has an attribute set definition, if you want the window to make effects for you.

## How a delivery works

A delivery ability is a `GasDeliveryAbility` asset. It is an ECS ability, so its cost, cooldown, tags, own effects, waits and montages work as they do on `GasEntityAbility` (see [Authoring](/docs/gameplay-ability-toolkit-ecs/build-with-it/authoring.md#abilities)). It adds settings for the delivery. When the ability activates and succeeds, the delivery module:

1. waits for the moment you chose: at once, at a montage notify, after a delay, or on a beat while the ability runs;
2. finds the actors to hit, from the caster's position and facing;
3. asks for each hit effect on each actor it found, at the level the ability was asked for, with the caster as the source.

Keep these in mind:

* **A target is an actor with a transform.** Distances run from the caster's position to the target's position. There is no collider and no size. A catalog that lists delivery abilities gives its actors a transform when they bake.
* **A refused activation delivers nothing.** If the cost, the cooldown or a tag requirement refuses the ability, nothing is hit.
* **Only the ECS runtime delivers.** On the GameObject runtime a delivery ability applies its own effects and ends.

## Making an ability with the New Ability window

The window makes the ability asset, the effects it needs, and the actor's setup in one pass. Everything except the optional script can be changed in the Inspector afterwards.

1. In the Hierarchy, select the actor that should use the ability: a GameObject with **Gas Entity Authoring**. The window gives the ability to that actor when you finish. Optionally, select a folder in the Project window for the new assets.
2. Choose **Tools > Gameplay Ability Toolkit > ECS > New Ability...**. You can also choose **Assets > Create > Gameplay Ability Toolkit > ECS > Ability (Step by Step)...**. The **New ECS Ability** window opens.
3. Work through the six pages listed on the left, using **Back** and **Next**. A yellow warning under a page says what is missing. **Next** stays disabled until the page is complete, and a page opens only when the pages before it are complete.
4. On the last page, read the **It makes** list and click **Create**.

When it finishes, the window closes, the new ability is selected in the Project window, and the Console logs `[GAS ECS] Made GA_<Name> in <folder>.`

### The six pages

| Page                     | What you set                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **1. Ability**           | **Name**: a type name that starts with a capital letter; `Fireball` makes `GA_Fireball`. **Folder**: where it goes, with a **Browse...** button. The default is `Assets/EcsAbilities`, or the folder you selected. The ability's assets go into a folder of their own inside it, named after the ability. **What it does**: *Self*, *Area*, *Arc*, *Nearest* or *Projectile* (see below).                       |
| **2. Cost and cooldown** | **Cooldowns**: seconds before it can be used again, by level. **Cost Effect**: an existing effect, or click **Make a Cost Effect**, then choose an attribute and how much it takes. The tag fields: **Activation Owned Tags**, **Activation Blocked Tags**, **Cancel Abilities With Tags**, **Block Abilities With Tags** and **Ability Tags**.                                                                 |
| **3. What it hits**      | The shape's settings, the target filter and the hit effects. See [The delivery ability](#the-delivery-ability). **Hit Effects** has a **Make an Effect on the Hit** button, and **Effects** (applied to the caster, besides the cost) has **Make an Effect on the Caster**. For a *Self* ability this page is called **What it does** and has only **Effects**.                                                 |
| **4. When it hits**      | **Timing**, with **Notify**, **Delay** or **Interval** for the timings that need one. The **Animation** section: **A combo, one step a montage**, **Montages**, **Montage Events** and **Montage Ended Event**. The **Staying active** section: **Waits**. For a *Self* ability this page is called **Animation and waits**.                                                                                    |
| **5. Who uses it**       | **Give it to ''**, then **Asks for it** (see [Casters](#casters)): *Code*, *Automatic*, *Interval* with **Every (seconds)**, or *Input Action* with **Input action**. Then **At level**, which a combo does not have. With no actor selected, the page asks you to select one in the Hierarchy and click **Use the Selected Actor**. You can skip that and add the ability to an actor's **Abilities** by hand. |
| **6. Review**            | **Also write a script for custom logic**, with a **Namespace**. The **It makes** list names every asset and change. The **Next** button is now **Create**.                                                                                                                                                                                                                                                      |

*Self* makes a plain ECS ability (`GasEntityAbility`) that acts on its owner only: a heal, a buff, a stance. The other four make a `GasDeliveryAbility`.

A new effect is an instant effect that adds the amount you type to one attribute. Choose the attribute from the list of `<attribute set>.<attribute>` names. Type a negative amount to take health away. A cost effect takes the amount you type.

### What Create makes

* `GA_<Name>.asset` in `<Folder>/<Name>/`, the ability.
* `GE_<Name>Cost`, `GE_<Name>Effect` and `GE_<Name>Hit` assets next to it, for the effects you chose to make. If a name is taken, a number is added.
* On the actor you selected: the ability is added to the **Abilities** list of its **Gas Entity Authoring**, and a **Gas Caster Authoring** is added if it has none, with an entry that says how the actor asks for the ability. The scene is marked as changed, so save it.
* With **Also write a script for custom logic**: `<Name>Hook.cs` in the ability's folder. It holds a system, `<Name>HookSystem`, ready to fill in. For a delivery ability it runs once for each actor hit, after the hit effects were asked for. For a *Self* ability it runs each time the ability succeeds. The script compiles into the assembly definition that already covers the folder, if that has the references it needs. Otherwise the window adds an assembly definition for it. It never edits yours. The **It makes** list says which.

The catalog must list the new ability and its effects. While **Auto Collect Definitions** is on, which is the default, the catalog adds them when its SubScene is open for editing. You can also click **Collect Now** on the catalog. With **Auto Collect Definitions** off, add them to the catalog's lists by hand. See [Authoring](/docs/gameplay-ability-toolkit-ecs/build-with-it/authoring.md#the-catalog-gascatalogauthoring).

### Example: a fireball

1. Select the player actor. Open the window.
2. Page 1: **Name** `Fireball`, **What it does** *Projectile*.
3. Page 2: click **Make a Cost Effect**, choose your mana attribute and type 10.
4. Page 3: set **Range** 20, **Projectile Speed** 15, and **Hit Radius** 0.5. Put the enemies' side tag in **Hit Required Tags**. Click **Make an Effect on the Hit**, choose your health attribute and type -20.
5. Page 4: leave **Timing** at *On Activation*.
6. Page 5: set **Asks for it** to *Input Action* and **Input action** to the name of an action in your project-wide Input System actions, such as `Attack`.
7. Page 6: click **Create**.

Press Play. When you press the action, a projectile leaves the player, and each enemy it reaches loses 20 health. To see it fly, give **Projectile Prefab** a prefab with a renderer.

### When Next is disabled

| The page says                                                                                        | Fix                                                                              |
| ---------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| The name must start with an upper-case letter and hold only letters, digits and underscores          | Rename it.                                                                       |
| The folder must be inside Assets                                                                     | Pick a folder under `Assets`.                                                    |
| The folder already exists and is not empty, or the project already has an ability called `GA_<Name>` | Choose another name or folder.                                                   |
| The new cost needs an attribute and an amount above 0                                                | Choose an attribute, and type a positive amount.                                 |
| A new effect has no attribute                                                                        | Choose one, or remove the effect. The project needs an attribute set definition. |
| It hits actors but does nothing to them                                                              | Add a hit effect.                                                                |
| The range must be above 0                                                                            | Raise **Range**.                                                                 |
| The projectile's speed must be above 0                                                               | Raise **Projectile Speed**.                                                      |
| It hits while it runs, but nothing keeps it running                                                  | Add a wait. See [Hold to keep firing](#hold-to-keep-firing).                     |
| Hitting at a montage notify needs a montage                                                          | Add a montage to **Montages**.                                                   |
| Name the notify it hits at                                                                           | Fill in **Notify**.                                                              |
| A combo needs two or more montages, a step has no montage, or a montage has no `Combo Start` notify  | See [Combos](#combos).                                                           |
| Name the input action                                                                                | Type the action's name in **Input action**.                                      |
| The namespace must be a dotted name                                                                  | Fix **Namespace** on the last page, or leave it empty.                           |
| Go back to a page: it is not finished                                                                | Open that page and fix its warning.                                              |

## The delivery ability

Create one by hand with **Assets > Create > Gameplay Ability Toolkit > ECS > Delivery Ability**. Its settings are in the **Subclass Details - GasDeliveryAbility** section of the Inspector. Add the ability to the catalog and to an actor's **Abilities**, then make the actor ask for it (see [Casters](#casters)).

| Setting                                     | Means                                                                                                                                                     |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Shape**                                   | *Area*, *Arc*, *Nearest* or *Projectile*. See [Shapes](#shapes).                                                                                          |
| **Range**                                   | How far. For an arc, how far in front. For a projectile, how far it flies.                                                                                |
| **Angle**                                   | Arc only: how wide, in degrees, centred on the caster's facing. 360 is all around. The default is 120.                                                    |
| **Projectile Speed**                        | Projectile only: metres a second.                                                                                                                         |
| **Hit Radius**                              | Projectile only: how close to an actor it must come to hit it.                                                                                            |
| **Pierce**                                  | Projectile only: how many actors it hits before it is removed.                                                                                            |
| **Projectile Prefab**                       | Projectile only: what you see flying. Give it a renderer. Empty fires an entity nothing draws, which still hits.                                          |
| **Max Targets**                             | At most this many actors are hit, the nearest first. 0 is no limit, except for *Nearest*, where 0 means one. A projectile ignores it and uses **Pierce**. |
| **Hits Caster**                             | Whether the caster can be hit. Leave it off for a projectile, which starts at the caster.                                                                 |
| **Hit Required Tags**, **Hit Ignored Tags** | The target filter. See [Target filters](#target-filters).                                                                                                 |
| **Hit Effects**                             | Effects applied to each actor hit, at the level the ability was asked for, with the caster as the source. Any effect type works.                          |
| **Timing**                                  | When it hits. See [Timing](#timing).                                                                                                                      |
| **Notify**, **Delay**, **Interval**         | The setting that the chosen timing uses.                                                                                                                  |

### Shapes

| Shape        | Hits                                                                          | Notes                                                                                    |
| ------------ | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| *Area*       | Every actor within **Range** of the caster.                                   | A nova, a stomp, an aura pulse.                                                          |
| *Arc*        | Every actor within **Range** and inside **Angle** around the caster's facing. | A sword swing, a cone of fire. An actor standing on the caster counts as inside any arc. |
| *Nearest*    | The nearest actors within **Range**: one, or **Max Targets**.                 | A bite, a zap.                                                                           |
| *Projectile* | Whatever the projectile reaches. See [Projectiles](#projectiles).             | A fireball, an arrow.                                                                    |

Area, arc and nearest hits are taken nearest first. The facing is the caster's forward direction, the +Z axis of its transform. The caster is left out unless **Hits Caster** is on.

### Projectiles

A projectile leaves the caster's position along its facing. Each frame it moves by **Projectile Speed** and hits every actor within **Hit Radius** of where it is now that it has not hit before. It is removed after it has hit **Pierce** actors, or after it has flown **Range**.

A projectile checks only where it is each frame, not the path between frames. If it covers more than twice **Hit Radius** in one frame, it can step over an actor. Raise **Hit Radius** or lower **Projectile Speed** if fast projectiles miss.

### Target filters

**Hit Required Tags** and **Hit Ignored Tags** decide which actors can be hit. An actor is hit only if it owns every required tag and none of the ignored ones. Sides in a game are usually tags: put the enemy side in **Hit Required Tags** and your own side in **Hit Ignored Tags**.

* A child tag counts. An actor that owns `Team.Enemy.Boss` passes a filter on `Team.Enemy`.
* The tags must be in the catalog. Put them in the catalog's **Tag Asset**. A required tag the catalog does not know means nothing can pass, so nothing is hit. An unknown ignored tag excludes nothing. The Console warns about both when the catalog bakes.
* The filter reads the tags the actor owns at the moment of the search.

### Timing

| **Timing**          | The hit lands                                                                                                                                                                                                                                                                                                                                  | Setting      |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| *On Activation*     | In the frame the ability activates.                                                                                                                                                                                                                                                                                                            |              |
| *On Montage Notify* | When the ability's montage reaches the notify named in **Notify**: an instruction clip's event name on the montage's Instructions track. The default is `Hit`. In a combo it lands once at each step's own notify. If the notify does not come within 10 seconds of activation, or another montage replaces the ability's, the hit is dropped. | **Notify**   |
| *After Delay*       | **Delay** seconds after activation, 0.5 by default. It lands even if the ability has ended by then.                                                                                                                                                                                                                                            | **Delay**    |
| *While Active*      | As the ability activates, then every **Interval** seconds for as long as it runs. The default is 0.2, and the least is 0.02.                                                                                                                                                                                                                   | **Interval** |

An area, arc or nearest delivery finds its targets in the frame the ability activates, and its effects take hold in the next frame. A projectile's effects take hold in the frame it reaches an actor.

## Casters

An ability does nothing until something asks for it. **Gas Caster Authoring** lists how an actor asks for its own abilities. It sits next to the actor's **Gas Entity Authoring**.

1. In the SubScene, select the actor. Choose **Add Component > Gameplay Ability Toolkit > Entities > Gas Caster Authoring**. The New Ability window does this for you.
2. In **Casts**, add an entry for each ability. Choose the **Ability**, which the actor must be granted, and a **Mode**.

| **Mode**       | The actor asks                                                                                                                                                                                                   |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *Code*         | When your code calls `GasCasting.Request(entityManager, actor, abilityIndex)`. It returns `false` if the actor has no entry for that ability.                                                                    |
| *Automatic*    | Every frame. The cost and the cooldown decide how often it runs. Use it for enemies and turrets.                                                                                                                 |
| *Interval*     | Every **Interval** seconds.                                                                                                                                                                                      |
| *Input Action* | When the Input System action named in **Input Action** is pressed, such as `Attack`. It reads the project-wide actions, needs the Input System package (1.8.0 or newer), and works in single-player worlds only. |

The other fields of an entry: **Level** is the level the ability is asked for, and **Combo** asks for the ability as a combo (see [Combos](#combos)).

Your code can always ask without an entry, with `GasEntityFactory.RequestActivation`. Finding an ability's index is shown in [Writing gameplay code](/docs/gameplay-ability-toolkit-ecs/build-with-it/gameplay-code.md#finding-indices).

While the action is held, the actor's `GasInputState` says so. Input waits read it. An actor has one held state, shared by all its abilities. If two abilities are held down at once, both see the same state.

The bake warns, with `[GAS ECS]` at the start, about an entry whose ability is not in the actor's catalog, or that is a combo with no montages.

## Hold to keep firing

A flamethrower, a beam, a channelled heal: it keeps going while the input is held and stops on release. All of it is data.

| Where                | What                                                                                                                                                                                |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| What it hits         | An *Arc* in front, with the burn or the damage in **Hit Effects**.                                                                                                                  |
| When it hits         | **Timing** *While Active*, **Interval** 0.2. On page 4 of the window, **End It When the Input Is Released** adds the wait that stops it: kind `InputReleased`, action `EndAbility`. |
| Who uses it          | The player's actor, asking by *Input Action*.                                                                                                                                       |
| What the player sees | Give the ability a tag it owns while it runs (**Activation Owned Tags**, say `State.Flaming`). Have your presentation code show the flame while the actor owns the tag.             |

A while-active ability hits once as it activates, whatever else it declares. Without a wait that keeps it running, it is a single hit. The window warns about this.

The ECS Swarm demo's flamethrower, `GA_SwarmFlamethrower`, is built this way: an arc of 9 metres and 50 degrees, hitting every 0.15 seconds, with a damage effect and a burn. Its game asks for it from its own input code instead of an Input Action. It requests the ability when the key is pressed, and it writes whether the key is held into the hero's `GasInputState`. It holds that state for at least the frame of the press, so a tap still ends the flame a frame later.

The burn is re-applied on every beat. So that the re-application does not restart its period, which would stop it from ever ticking while the flame is on it, the burn effect sets **Stacking Period Policy** to *Never Refresh*. Do the same for a periodic effect in a while-active ability.

## Combos

A sword's light attacks, a staff's three-hit chain: each press in rhythm plays the next swing.

1. In the ability, list one montage for each step, in order, in **Montages**. Each montage but the last needs a notify named `Combo Start` where the next swing may begin. A notify named `Combo End` closes that window earlier. Without it, the window stays open until the montage ends. Notifies are instruction clips on the montage's Instructions track.
2. In the actor's **Gas Caster Authoring**, tick **Combo** on the ability's entry.

The window does both for you on page 4: tick **A combo, one step a montage**. It checks the montages. Each step must end the ability so the combo can go on, so creating the ability also sets **Montage Ended Event** to `Event.<Name>.End`, unless you already set one, and adds a `GameplayEvent` wait on that event that ends the ability.

| What happens               | How                                                                                                                                      |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| The first ask              | Starts step 1: the ability is asked for at level 1, which plays its first montage.                                                       |
| An ask during a step       | Waits for the step's window, from the montage's `Combo Start` notify to its `Combo End`.                                                 |
| An ask in the window       | Ends the step's ability and asks for the next step at the next level, which plays the next montage. After the last step comes the first. |
| Holding the input action   | Carries the combo on by itself, window after window.                                                                                     |
| No ask                     | The step plays out, its montage's end ends the ability, and the combo is over. The next ask starts at step 1.                            |
| A step the runtime refuses | A stunned caster, say. It is asked for again for 0.6 seconds, then dropped.                                                              |
| Another ability's montage  | If it replaces a step's montage, it ends that step's ability and the combo.                                                              |

Each step is its own level. A level curve on a hit effect makes later steps hit harder. **Timing** *On Montage Notify* hits at each step's own notify, once.

`GasComboSystem` follows the montages after the runtime, and `GasCastTriggerSystem` asks for the steps before it. The state is on the caster's `GasCastTrigger` buffer, which your code can read: `ComboStep` is the step playing, and `ComboWindow` says whether its window is open.

## Reacting to hits

Use data for what data can say. For what it cannot, such as a sound, a knock-back or a score, read the hits.

After `GasDeliveryApplySystem` asks for the hit effects, it reports each hit as a `GasDeliveryHitEvent` on the delivery state entity. An event holds the `AbilityIndex`, the `Caster`, the `Target` and the `Level`. Events last one frame: the next frame's apply system clears them.

Read them in `GasRequestSystemGroup` after `GasDeliveryApplySystem`, or later in the same frame. The window's hook script does this. [Writing gameplay code](/docs/gameplay-ability-toolkit-ecs/build-with-it/gameplay-code.md#handling-hits) has a system that reads them.

## Activation results

The runtime appends a result for every activation it serves and never clears them. In a world with delivery abilities, `GasDeliveryStartSystem` reads the results first in `GasResultSystemGroup`, and `GasDeliveryResultsCleanupSystem` clears them last. Read results inside that group. A system of yours that clears them as well is harmless, as long as it runs inside the group.

## Large crowds

The built-in search is made for crowds. It runs in Burst jobs, and when many searches happen in one frame among a large population it shares one snapshot of the actors' positions between them. With 20,000 actors or more, it keeps the snapshot until an actor moves, is created or is destroyed.

* Set **Max Targets** when you need only a few targets. The search then keeps only the nearest candidates instead of sorting everything in range.
* Keep **Range** as small as the ability needs. A very large range makes the search check every actor.
* Expect a new snapshot every frame in a crowd that moves every frame.

[Performance](/docs/gameplay-ability-toolkit-ecs/reference/performance.md#delivery-searches) has the numbers and the habits that matter.

## Using your own queries

A game with its own grid, a physics world, line-of-sight rules or a target-selection UI can take over finding targets, moving projectiles, or both. Your system produces the hits. The module still applies the effects and reports the hit events, so the rest of the ability keeps working.

Each switch belongs to one world. Set them once, when your game sets up:

```csharp
GasDelivery.ConfigureQueries(world.EntityManager, new GasDeliveryQueryOptions
{
    ExternalTargetSearch = true,
    ExternalProjectileSimulation = false,
});
```

`ConfigureQueries` sets both switches at once. A switch you leave out is off.

| Switch                         | While it is on                                                                                                                                       |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ExternalTargetSearch`         | `GasDeliverySearchSystem` returns before it reads or clears the pending deliveries. Your system does the search for area, arc and nearest abilities. |
| `ExternalProjectileSimulation` | `GasProjectileSystem` returns before it moves projectiles, records collisions or changes their lifetime. Your system does all of it.                 |

The two switches are independent. Omit the options to use the built-in systems for both. Pass `default` to `ConfigureQueries` to give both back. Code that switches a built-in system off through its `SystemHandle` still works.

Your system fits in here:

| Your system           | Where it runs                                                                                       | What it does                                                                                                                                                                                              |
| --------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Target search         | `GasResultSystemGroup`, after `GasDeliveryStartSystem` and before `GasDeliveryResultsCleanupSystem` | Read the `GasDeliveryPending` requests, query your targets, append a `GasDeliveryHit` for each, and clear the requests you handled. Copy `Entry`, `Caster` and `Level` into each hit.                     |
| Projectile simulation | `GasRequestSystemGroup`, after `GasCastTriggerSystem` and before `GasDeliveryApplySystem`           | Move the `GasProjectile` entities, choose the collisions, update `GasProjectileHitActor`, `HitsLeft` and `Remaining`, append a `GasDeliveryHit` for each hit, and destroy the projectiles that are spent. |

A pending request has the `Entry` (an index into the `GasDeliveryEntry` buffer on the `GasDeliveryCatalog` entity, which holds the ability's authored settings), the `Caster`, the `Level`, and the caster's `Origin` and `Forward` when the delivery was made. Your query owns the geometry, the order of the targets and the limit on how many.

`GasDelivery.PassesFilter` applies the ability's authored tag filter to one target. You pass the catalog blob by `ref`, the entry, the filters (a `DynamicBuffer<GasDeliveryTagFilter>` or a `NativeArray<GasDeliveryTagFilter>`), a `BufferLookup<GasTagCount>` and the target. You can call it from Burst code. Use it if your query should keep the authored rules. `GasDelivery.EnsureState` gets or creates the delivery state entity for a world you built yourself.

### Example: hit the selected target

This system hits the actor your game selected, instead of searching a radius. Your game adds `SelectedAbilityTarget` to the caster and writes the target into `Value`. A delivery whose caster has no selected target hits nothing.

```csharp
using GameplayAbilityToolkit.Entities;
using GameplayAbilityToolkit.Entities.Delivery;
using Unity.Entities;

namespace Game.Abilities
{
    public struct SelectedAbilityTarget : IComponentData
    {
        public Entity Value;
    }

    // Single-player and server worlds. Clients do not run deliveries.
    [WorldSystemFilter(WorldSystemFilterFlags.LocalSimulation | WorldSystemFilterFlags.ServerSimulation)]
    [UpdateInGroup(typeof(GasResultSystemGroup))]
    [UpdateAfter(typeof(GasDeliveryStartSystem))]
    [UpdateBefore(typeof(GasDeliveryResultsCleanupSystem))]
    public partial struct SelectedTargetSearchSystem : ISystem
    {
        public void OnCreate(ref SystemState state)
        {
            // This system owns target search in this world.
            GasDelivery.ConfigureQueries(state.EntityManager, new GasDeliveryQueryOptions
            {
                ExternalTargetSearch = true,
            });
            state.RequireForUpdate<GasDeliveryCatalog>();
            state.RequireForUpdate<GasCatalog>();
        }

        public void OnUpdate(ref SystemState state)
        {
            state.CompleteDependency();
            var queue = SystemAPI.GetSingletonEntity<GasDeliveryState>();
            var pending = SystemAPI.GetBuffer<GasDeliveryPending>(queue);
            var hits = SystemAPI.GetBuffer<GasDeliveryHit>(queue);
            var deliveryCatalog = SystemAPI.GetSingletonEntity<GasDeliveryCatalog>();
            var entries = SystemAPI.GetBufferLookup<GasDeliveryEntry>(true)[deliveryCatalog];
            var filters = SystemAPI.GetBufferLookup<GasDeliveryTagFilter>(true)[deliveryCatalog];
            var tags = SystemAPI.GetBufferLookup<GasTagCount>(true);
            var selected = SystemAPI.GetComponentLookup<SelectedAbilityTarget>(true);
            var catalog = SystemAPI.GetSingleton<GasCatalog>();

            foreach (var request in pending)
            {
                if (!selected.TryGetComponent(request.Caster, out var target)
                    || !state.EntityManager.Exists(target.Value)) continue;

                // Keep the ability's Hit Required Tags and Hit Ignored Tags.
                if (!GasDelivery.PassesFilter(ref catalog.Value.Value, entries[request.Entry],
                    filters, tags, target.Value)) continue;

                hits.Add(new GasDeliveryHit
                {
                    Entry = request.Entry,
                    Caster = request.Caster,
                    Target = target.Value,
                    Level = request.Level,
                });
            }

            // Every request is handled, so clear them all.
            pending.Clear();
        }
    }
}
```

The `UpdateAfter` and `UpdateBefore` lines state the order. The start system is first in its group and the cleanup system is last, so any system in the group runs between them. If your game code is in an assembly definition, it needs references to `GameplayAbilityToolkit.Entities`, `GameplayAbilityToolkit.Entities.Delivery`, `Unity.Entities` and `Unity.Collections` to compile this. Scripts in the default assembly (`Assembly-CSharp`) need no setup.

`GasDeliveryApplySystem` still applies the hit effects and reports the hit events for the hits you append. The costs, the cooldowns, the timing, the montages and the cleanup stay with the existing systems.

## Netcode for Entities

The delivery module runs on the server only. A predicting client simulates some ticks more than once, and a delivery is not rolled back, so it would fire again on each. The module switches itself off in client worlds.

* Clients see a delivery through what it causes: the replicated attributes, tags and effects.
* Caster entries, combos included, are served on the server. A player's client asks for abilities through `GasAbilityInput`. The *Input Action* mode is for single-player.
* A projectile the server fires is seen on clients only if its prefab is a ghost. See [Netcode for Entities](/docs/gameplay-ability-toolkit-ecs/build-with-it/netcode-for-entities.md#abilities-that-reach-other-actors).
* A target search or projectile system of your own should run only in single-player and server worlds. The example above does this with its world filter.

## If nothing is hit

| Check                                          | Why                                                                                                                                                                                                    |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| The Console, after the SubScene bakes          | Warnings that start with `[GAS ECS]` name an ability or hit effect that is not in the catalog, a tag filter the catalog does not know, and a caster entry whose ability is not in the actor's catalog. |
| Whether anything asks for the ability          | The actor needs an entry in **Gas Caster Authoring**, or code that asks.                                                                                                                               |
| Whether the activation succeeded               | A refused activation delivers nothing. The result says why. See [Activation results](#activation-results).                                                                                             |
| The targets                                    | They need a transform and the runtime's attributes. They must be within **Range**, measured from pivot to pivot, and for an arc inside the **Angle** in front of the caster.                           |
| **Hit Required Tags** and **Hit Ignored Tags** | A required tag that an actor does not own keeps it from being hit.                                                                                                                                     |
| **Hits Caster**                                | It is off by default, so a lone caster hits nothing.                                                                                                                                                   |
| **Timing**                                     | *While Active* with no wait that keeps the ability running is a single hit. The montage notify must be spelled exactly as on the montage, including the case.                                          |
| The hit effects                                | They must be in the catalog, and the target must pass their application requirements.                                                                                                                  |

## Where to go next

* [Authoring](/docs/gameplay-ability-toolkit-ecs/build-with-it/authoring.md): the waits, montages and effects that a delivery ability uses.
* [Writing gameplay code](/docs/gameplay-ability-toolkit-ecs/build-with-it/gameplay-code.md): ask for abilities from code, and read hits and results.
* [Cues and presentation](/docs/gameplay-ability-toolkit-ecs/build-with-it/presentation.md): show the flame, the hit and the sound.
* [Netcode for Entities](/docs/gameplay-ability-toolkit-ecs/build-with-it/netcode-for-entities.md): run deliveries in a server-authoritative game.
* [Performance](/docs/gameplay-ability-toolkit-ecs/reference/performance.md): keep large crowds fast.
