> For the complete documentation index, see [llms.txt](https://dante-3.gitbook.io/dante-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dante-3.gitbook.io/dante-docs/modular-input-system/core-concepts/gates.md).

# Gates

| Class             | Header                   | Parent            | Create from                                                |
| ----------------- | ------------------------ | ----------------- | ---------------------------------------------------------- |
| `UMIPS_InputGate` | `Gates/MIPS_InputGate.h` | `UMIPS_InputStep` | **Modular Input System > Gates & Processors > Input Gate** |

***

## Overview

A gate decides whether an input event may reach the processors. It returns an `FMIPS_GateResult`:

| Field            | Description                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------ |
| **Verdict**      | `Allow`, `Block` or `Buffer`.                                                              |
| **Reason Tag**   | Why the event was not simply allowed. Empty when allowed.                                  |
| **Debug Detail** | Free text for the debugging tools, e.g. `0.12s of 0.20s left`. Dropped in Shipping builds. |

A mode runs its gates **in order**:

* A gate whose filter does not match the event is skipped; the event counts as allowed by it.
* The **first** gate that does not allow the event decides its fate. Later gates are not asked.
* A gate that stops an event without a reason is reported with `ModularInput.Reason.Unspecified`.
* Inputs listed in the mode's **Bypass Inputs** skip every gate.

***

## Common Properties

Every gate has these, inherited from `UMIPS_InputStep` and `UMIPS_InputGate`:

| Property           | Default | Description                                                                                                       |
| ------------------ | ------- | ----------------------------------------------------------------------------------------------------------------- |
| **Input Tags**     | empty   | Inputs the gate applies to. Empty means every input; a parent tag covers its children.                            |
| **Trigger Events** | all     | Trigger events the gate applies to.                                                                               |
| **Fail Verdict**   | Block   | What happens to events this gate does not let through: **Block** drops them, **Buffer** holds them in the buffer. |

**Buffer** is useful when an input should wait rather than vanish. For example, a stun gate with **Fail Verdict = Buffer** keeps an attack pressed during the stun, and a buffer window or an ability can pick it up once the stun ends.

***

## Owner Tags

Tag-based gates test against **owner tags**. The component gathers them from every actor in the [owner chain](/dante-docs/modular-input-system/core-concepts/input-component.md) (owner, pawn, controller, player state) **and every component on those actors**:

{% stepper %}
{% step %}

### `IMIPS_TagProvider`

An object that implements `IMIPS_TagProvider` is read through **Get Input Gate Tags**.
{% endstep %}

{% step %}

### `IGameplayTagAssetInterface`

Otherwise, an object that implements `IGameplayTagAssetInterface` is read through `GetOwnedGameplayTags`. This includes an **Ability System Component**, so GAS state tags such as `State.Stunned` work without extra code.
{% endstep %}
{% endstepper %}

Tags are gathered once per event, on first use, and shared by every gate that looks at the same event.

{% tabs %}
{% tab title="Blueprint" %}
Add the **MIPS\_TagProvider** interface to your pawn (or any component on it) under **Class Settings > Interfaces**, then implement **Get Input Gate Tags**:

<figure><img src="https://4216330531-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsGXprPiDJ68FN8HnOaN%2Fuploads%2FACLfZjTlLaiNYAlqutbG%2Fimage.png?alt=media&amp;token=e7c91cd1-9693-46e1-bca5-d0e059849c71" alt=""><figcaption></figcaption></figure>

```
Get Input Gate Tags
  └─ Return: Make Literal Gameplay Tag Container (State.Aiming)  ── or your own state container
```

{% endtab %}

{% tab title="C++" %}

```cpp
#include "Core/MIPS_TagProvider.h"

UCLASS()
class AMyHero : public ACharacter, public IMIPS_TagProvider
{
    GENERATED_BODY()

public:
    virtual FGameplayTagContainer GetInputGateTags_Implementation() const override
    {
        return StateTags;   // e.g. State.Stunned, State.InMenu
    }

private:
    UPROPERTY()
    FGameplayTagContainer StateTags;
};
```

{% endtab %}
{% endtabs %}

To add tags from somewhere else entirely, subclass the component in C++ and override `GatherOwnerTags`.

***

## Built-in Gates

### Tag Query

`UMIPS_InputGate_TagQuery`: lets events through only while the owner tags satisfy a query.

| Property  | Description                                                                               |
| --------- | ----------------------------------------------------------------------------------------- |
| **Query** | A gameplay tag query the owner tags must satisfy. An empty query lets everything through. |

Reason: `ModularInput.Reason.TagQuery`. The detail lists the owner tags and the query description.

*Example:* on the Attack input, require `NONE(State.Stunned, State.Dead)`.

### Input Filter

`UMIPS_InputGate_InputFilter`: while a condition on the owner tags holds, restricts which inputs pass.

| Property           | Description                                                                           |
| ------------------ | ------------------------------------------------------------------------------------- |
| **Condition**      | The filter only applies while the owner tags satisfy this query. Empty means always.  |
| **Allowed Inputs** | While the filter applies, only these inputs pass. Empty puts no restriction in place. |
| **Blocked Inputs** | While the filter applies, these inputs never pass. Checked before Allowed Inputs.     |

Reason: `ModularInput.Reason.InputFilter`, with the detail *"is in the blocked list"* or *"is not in the allowed list"*.

*Example:* while `State.Stunned` is present, allow only `Input.Menu`.

### Cooldown

`UMIPS_InputGate_Cooldown`: enforces a minimum time between two **accepted** events of the same input and trigger event.

| Property           | Default | Description                                                                                                                                               |
| ------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Cooldown**       | 0.2 s   | Minimum time since the input last got past the gates.                                                                                                     |
| **Trigger Events** | Started | Filtered to Started by default: Triggered fires every frame while a button is held, and a cooldown on it would throttle the hold rather than the presses. |

Reason: `ModularInput.Reason.Cooldown`, with the time left in the detail.

The time is measured from the last time the event was **allowed** by the pipeline, so blocked presses do not restart the cooldown.

***

## Reason Tags

| Tag                                | Reported by                                                        |
| ---------------------------------- | ------------------------------------------------------------------ |
| `ModularInput.Reason.TagQuery`     | Tag Query gate                                                     |
| `ModularInput.Reason.InputFilter`  | Input Filter gate                                                  |
| `ModularInput.Reason.Cooldown`     | Cooldown gate                                                      |
| `ModularInput.Reason.BufferWindow` | The pipeline, when an open buffer window captured an allowed event |
| `ModularInput.Reason.Unspecified`  | The pipeline, when a gate stopped an event without naming a reason |

Reasons are tags rather than an enum, so your own gates can report their own, such as `Game.InputReason.OutOfStamina`, without touching the plugin.

***

## Writing Your Own

Override **Evaluate** in a Blueprint or C++ subclass and return **Make Allow Result**, or **Make Fail Result** with a reason tag (it uses the gate's Fail Verdict). See [Writing Gates & Processors](/dante-docs/modular-input-system/core-concepts/gates.md).

***

## Next Steps
