> 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/input-modes.md).

# Input Modes

| Class             | Header                     | Parent              | Create from                                         |
| ----------------- | -------------------------- | ------------------- | --------------------------------------------------- |
| `UMIPS_InputMode` | `Runtime/MIPS_InputMode.h` | `UPrimaryDataAsset` | **Modular Input System > Data Assets > Input Mode** |

## Overview

An Input Mode describes how input behaves in one situation: on foot, in a menu, mid-attack, driving. **Gates** decide which events get through; **processors** act on the ones that do.

Modes are pushed onto a component's mode stack and the top one is active, so a situation can take over input for a while and hand it back when it ends. There is no need to enable and disable individual bindings: pushing a menu mode on top of the on-foot mode is enough.

## Properties

### Gates

| Property            | Default | Description                                                                                                                                                                                                                             |
| ------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Bypass Inputs**   |         | Inputs that skip every gate. A parent tag covers its children. Useful for inputs that must always work, such as a pause menu.                                                                                                           |
| **Gates**           |         | Evaluated in order. Only gates whose filter matches the event are asked. The first gate that does not allow the event decides what happens to it.                                                                                       |
| **Buffer On Block** | Never   | What happens to an event a gate **blocked**: dropped (*Never*), held while an open buffer window accepts it (*When Window Open*), or always held (*Always*). A gate that returns **Buffer** holds the event regardless of this setting. |

### Processors

| Property                    | Default        | Description                                                                                                                                        |
| --------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Dispatch Policy**         | Until Consumed | How the processor list is walked for one event. See below.                                                                                         |
| **Processors**              |                | Offered every allowed event, in order.                                                                                                             |
| **Buffer Unhandled Inputs** | Off            | Also holds allowed events that no processor handled, so code that polls the buffer (abilities, anim notifies, State Trees) can still pick them up. |

### Debug

| Property          | Default | Description                                         |
| ----------------- | ------- | --------------------------------------------------- |
| **Log Decisions** | Off     | Logs every decision made while this mode is active. |
| **Log Filter**    |         | Only logs these inputs. Empty logs all of them.     |

In the **Gates** and **Processors** lists, each entry is titled with its class and filter, for example `Push Mode (Menu · Started)` or `Move (Move)`, so a long list stays readable while collapsed.

## Dispatch Policy

Allowed events are offered to the processors in list order. A processor only sees an event when its **Input Tags** and **Trigger Events** filter matches and its **Should Handle** returns true.

| Policy                         | Behaviour                                                                    | Typical use                                                                     |
| ------------------------------ | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| **All**                        | Every matching processor runs. Consumption is ignored.                       | Several independent reactions to one input, e.g. move and play a footstep hint. |
| **Until Consumed** *(default)* | Matching processors run in order until one returns **Handled And Consumed**. | A specific processor early in the list overrides a general one later.           |
| **First Match**                | Only the first processor that handles the event runs.                        | Exclusive choices, e.g. context-sensitive "interact" processors.                |

A processor returns **Handled And Consumed** when its **Consume Input** option is on; Push Mode and Pop Mode have it on by default.

```
Processors (Until Consumed)
  1. Pop Mode       (Back · Started)      Consume ✓   ── pressing Back leaves the menu, nothing else sees it
  2. Broadcast Tag  (UI)                              ── every other UI input is broadcast
  3. Debug String   (all inputs)                      ── still sees UI inputs, since 2 did not consume
```

## The Mode Stack

Each component has its own stack:

* The **highest priority** entry is active. Among entries with the same priority, the **latest push** wins.
* With nothing pushed, the component's **Default Mode** is active.
* Every push returns an `FMIPS_ModeHandle`. Pushing the same mode twice creates two entries and needs two pops, so two systems can push the same mode without stepping on each other.

```
Priority   Entry
   100     DA_Mode_PauseMenu      ◄── active
    10     DA_Mode_Attacking
     0     DA_Mode_Driving
  default  DA_Mode_OnFoot         (used when the stack is empty)
```

**On Active Mode Changed** `(NewMode, PreviousMode)` fires on the component whenever the active mode becomes a different asset.

### Pushing and Popping

{% tabs %}
{% tab title="Blueprint" %}
From anything that has an actor (the pawn, the controller, an ability, a widget's owning player's pawn):

```
Push Input Mode (Actor = Self, Mode = DA_Mode_PauseMenu, Priority = 100)
  └─► store the returned Mode Handle in a variable

Pop Input Mode (Actor = Self, Handle = <stored handle>)
```

**Push Input Mode** and **Pop Input Mode** find the component on the actor, its controller or its pawn. With a component reference, call **Push Mode**, **Pop Mode** or **Pop Mode By Asset** on it directly. **Is Mode Handle Valid** tells whether a stored handle still refers to a push.
{% endtab %}

{% tab title="Processors" %}
Modes can drive the stack themselves, without any code:

* **Push Mode** pushes a mode on its input (Started by default). With **Skip If On Stack** on, repeated presses do not stack it up.
* **Pop Mode** pops a mode, or the mode it belongs to when left empty ("leave this menu").

A typical pair: the on-foot mode has *Push Mode (DA\_Mode\_Map) on Input.Map*, and the map mode has *Pop Mode on Input.Map* and *Pop Mode on Input.Back*.
{% endtab %}

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

```cpp
#include "Runtime/MIPS_InputComponent.h"

void AMyPlayerController::OpenPauseMenu()
{
    if (UMIPS_InputComponent* Input = UMIPS_InputComponent::FindInputComponent(this))
    {
        PauseMenuHandle = Input->PushMode(PauseMenuMode, /*Priority=*/100);
    }
}

void AMyPlayerController::ClosePauseMenu()
{
    if (UMIPS_InputComponent* Input = UMIPS_InputComponent::FindInputComponent(this))
    {
        Input->PopMode(PauseMenuHandle);   // also resets the handle
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The stack is cleared when the component ends play. With the component on a player controller, the stack survives respawns; on a pawn, a new pawn starts with an empty stack.
{% endhint %}

## Designing Modes

* **One mode per situation**, not per input. A mode is a complete description: what may pass and who reacts.
* **Put general rules in gates**, e.g. "nothing but UI inputs while `State.InMenu`", instead of checking conditions inside every processor.
* **Use priorities for layers that must win**, such as pause menus and cinematics, and priority 0 for ordinary gameplay modes.
* **Keep the default mode for the resting state**, e.g. on foot. Use a setup provider when different pawns need different defaults.

### Example: a menu mode

```
DA_Mode_Menu                       pushed at priority 100
├── Bypass Inputs    Input.Pause
├── Gates
│     └── Input Filter   Allowed Inputs: Input.UI           (everything else is blocked)
├── Dispatch Policy  Until Consumed
└── Processors
      ├── Pop Mode             (Back · Started)   Mode: empty = pop DA_Mode_Menu
      └── Broadcast Tag Event  (UI)               Event Tag: empty = the input tag
```

## Validation

| Check                                                                                                                | Severity |
| -------------------------------------------------------------------------------------------------------------------- | -------- |
| An empty entry in **Gates** or **Processors**                                                                        | Error    |
| A step's own validation fails, e.g. a Push Mode with no mode, an Open Buffer Window with no window tag               | Error    |
| An Open Buffer Window processor names a window that no config in the project defines                                 | Warning  |
| A Push Mode processor pushes its own mode with **Skip If On Stack** off, so every matching input stacks another copy | Warning  |

## Next Steps
