unreal-enhanced-input

Unreal 5.8 Enhanced Input

Build contextual remappable input systems

---
name: unreal-enhanced-input
description: Design, implement, remap, test, and debug player input with Unreal Engine 5.8 Enhanced Input. Use for Input Actions, Input Mapping Contexts, priorities, local-player ownership, trigger events, hold/tap/release/chord behavior, modifiers, dead zones, sensitivity, inversion, 2D movement, contextual controls, possession, split screen, player-mappable key settings, key profiles, conflict handling, saving, input buffering, coyote time, input injection, Common UI integration, or missing/duplicate input events.
---

# Unreal 5.8 Enhanced Input

## Ownership boundary

This skill owns action/context/trigger/modifier semantics and player-mappable key profiles. Route menu
layers, focus, and UI input routing to
[`unreal-umg-commonui`](../unreal-umg-commonui/SKILL.md). Use
[`unreal-save-load`](../unreal-save-load/SKILL.md) only when settings join a broader custom slot,
versioning, user, or cloud-persistence policy; do not duplicate key-profile authority in two systems.

## Build the input model

1. Define one `UInputAction` per player intent, not per physical key.
2. Choose its value type: Boolean, Axis1D, Axis2D, or Axis3D.
3. Group mappings by coherent situation in `UInputMappingContext` assets.
4. Add/remove contexts on the correct `UEnhancedInputLocalPlayerSubsystem` with documented
   priorities and mutual-exclusion rules.
5. Transform raw values with modifiers; decide activation timing with triggers.
6. Bind action trigger events through `UEnhancedInputComponent` or Blueprint action events.
7. Forward semantic intent to the possessed pawn, component, GAS, UI, or command layer.

Read [`references/architecture.md`](references/architecture.md) and
[`references/contexts-ownership.md`](references/contexts-ownership.md) first.

## Select event semantics deliberately

- `Started`: evaluation began.
- `Ongoing`: trigger conditions are partially satisfied.
- `Triggered`: all trigger conditions succeeded; may repeat depending on trigger.
- `Completed`: a triggered action returned to none.
- `Canceled`: evaluation ended before successful completion.

Read [`references/triggers-modifiers.md`](references/triggers-modifiers.md). Do not assume
`Triggered` means a one-shot press; without a one-shot trigger, actuation can trigger each tick.

## Separate detection from gameplay forgiveness

Enhanced Input detects and interprets input. A gameplay buffer stores a timestamped semantic
request until the gameplay state can accept it. Implement buffers and coyote time in the
gameplay action/movement layer, not as an invented built-in Enhanced Input feature. Read
[`references/buffering.md`](references/buffering.md).

## Rebinding

Use UE 5.8 `UEnhancedInputUserSettings`, Player Mappable Key Settings, mapping names, slots,
and key profiles. Register all relevant contexts with settings, map with `FMapPlayerKeyArgs`,
surface failure reasons/conflicts, apply, and save. Read
[`references/rebinding-settings.md`](references/rebinding-settings.md).

## Required answer format

Return:

1. **Input Actions** with value types.
2. **Mapping Contexts**, ownership, priorities, and add/remove lifecycle.
3. **Mappings, modifiers, triggers, and bound trigger events**.
4. **Intent routing** and gameplay-buffer ownership where applicable.
5. **Rebinding, conflict, profile, persistence, and accessibility behavior**.
6. **Device, focus, possession, split-screen, and packaged-build tests**.

Do not invent node names, default thresholds, context priorities, or save behavior.

## Hard rules

- Add contexts to the Local Player that owns the input, not to a global gameplay object.
- Do not leave mutually exclusive contexts active and hope priority hides every collision.
- Do not bind the same action repeatedly across possession/reinitialization.
- Do not put gameplay logic inside reusable modifiers or triggers when a semantic command will do.
- Do not identify saved mappings by localized display text; use stable mapping names and slots.
- Do not treat client input as authoritative gameplay state.
- Test context rebuilds while keys are held; UE 5.8 preserves trigger/modifier state more
  reliably, but custom classes must implement reinstancing behavior when stateful.

Use [`references/patterns.md`](references/patterns.md) for common controls and
[`references/troubleshooting.md`](references/troubleshooting.md) for missing, repeated, stuck,
or conflicting input. See [`references/sources.md`](references/sources.md) for the UE 5.8 trail.

## Ownership boundary

This skill owns action/context/trigger/modifier semantics and player-mappable key profiles. Route menu
layers, focus, and UI input routing to
[`unreal-umg-commonui`](/unreal/unreal-umg-commonui/). Use
[`unreal-save-load`](/unreal/unreal-save-load/) only when settings join a broader custom slot,
versioning, user, or cloud-persistence policy; do not duplicate key-profile authority in two systems.

## Build the input model

1. Define one `UInputAction` per player intent, not per physical key.
2. Choose its value type: Boolean, Axis1D, Axis2D, or Axis3D.
3. Group mappings by coherent situation in `UInputMappingContext` assets.
4. Add/remove contexts on the correct `UEnhancedInputLocalPlayerSubsystem` with documented
   priorities and mutual-exclusion rules.
5. Transform raw values with modifiers; decide activation timing with triggers.
6. Bind action trigger events through `UEnhancedInputComponent` or Blueprint action events.
7. Forward semantic intent to the possessed pawn, component, GAS, UI, or command layer.

Read [`references/architecture.md`](/unreal/unreal-enhanced-input/architecture/) and
[`references/contexts-ownership.md`](/unreal/unreal-enhanced-input/contexts-ownership/) first.

## Select event semantics deliberately

- `Started`: evaluation began.
- `Ongoing`: trigger conditions are partially satisfied.
- `Triggered`: all trigger conditions succeeded; may repeat depending on trigger.
- `Completed`: a triggered action returned to none.
- `Canceled`: evaluation ended before successful completion.

Read [`references/triggers-modifiers.md`](/unreal/unreal-enhanced-input/triggers-modifiers/). Do not assume
`Triggered` means a one-shot press; without a one-shot trigger, actuation can trigger each tick.

## Separate detection from gameplay forgiveness

Enhanced Input detects and interprets input. A gameplay buffer stores a timestamped semantic
request until the gameplay state can accept it. Implement buffers and coyote time in the
gameplay action/movement layer, not as an invented built-in Enhanced Input feature. Read
[`references/buffering.md`](/unreal/unreal-enhanced-input/buffering/).

## Rebinding

Use UE 5.8 `UEnhancedInputUserSettings`, Player Mappable Key Settings, mapping names, slots,
and key profiles. Register all relevant contexts with settings, map with `FMapPlayerKeyArgs`,
surface failure reasons/conflicts, apply, and save. Read
[`references/rebinding-settings.md`](/unreal/unreal-enhanced-input/rebinding-settings/).

## Required answer format

Return:

1. **Input Actions** with value types.
2. **Mapping Contexts**, ownership, priorities, and add/remove lifecycle.
3. **Mappings, modifiers, triggers, and bound trigger events**.
4. **Intent routing** and gameplay-buffer ownership where applicable.
5. **Rebinding, conflict, profile, persistence, and accessibility behavior**.
6. **Device, focus, possession, split-screen, and packaged-build tests**.

Do not invent node names, default thresholds, context priorities, or save behavior.

## Hard rules

- Add contexts to the Local Player that owns the input, not to a global gameplay object.
- Do not leave mutually exclusive contexts active and hope priority hides every collision.
- Do not bind the same action repeatedly across possession/reinitialization.
- Do not put gameplay logic inside reusable modifiers or triggers when a semantic command will do.
- Do not identify saved mappings by localized display text; use stable mapping names and slots.
- Do not treat client input as authoritative gameplay state.
- Test context rebuilds while keys are held; UE 5.8 preserves trigger/modifier state more
  reliably, but custom classes must implement reinstancing behavior when stateful.

Use [`references/patterns.md`](/unreal/unreal-enhanced-input/patterns/) for common controls and
[`references/troubleshooting.md`](/unreal/unreal-enhanced-input/troubleshooting/) for missing, repeated, stuck,
or conflicting input. See [`references/sources.md`](/unreal/unreal-enhanced-input/sources/) for the UE 5.8 trail.

unreal 5.8 enhanced input design, implement, remap, test, and debug player input with unreal engine 5.8 enhanced input. use for input actions, input mapping contexts, priorities, local-player ownership, trigger events, hold/tap/release/chord behavior, modifiers, dead zones, sensitivity, inversion, 2d movement, contextual controls, possession, split screen, player-mappable key settings, key profiles, conflict handling, saving, input buffering, coyote time, input injection, common ui integration, or missing/duplicate input events. enhanced input architecture enhanced input architecture asset model | asset/type | owns | |---|---| | uinputaction | semantic intent and value type; optional action-level modifiers/triggers/settings | | uinputmappingcontext | key-to-action mappings for one coherent context plus mapping-level modifiers/triggers | | uinputmodifier | raw value transformation before trigger evaluation | | uinputtrigger | conditions/timing that decide action state | | uenhancedinputlocalplayersubsystem | applied contexts and priorities for one local player | | uenhancedinputcomponent | action-to-delegate bindings in the input stack | | uenhancedinputusersettings | per-user mappable keys, profiles, input/accessibility settings, registration, persistence | ordered setup 1. ensure enhanced input is enabled and the project uses enhanced player input / enhanced input component classes where manual project setup requires them. 2. create input actions named for intent: iamove, ialook, iajump, iainteract. 3. choose exact value types. a 2d move action should be axis2d; a button is usually boolean. 4. create small mapping contexts by coherent availability/lifecycle: common gameplay, on-foot, vehicle, menu/debug, and similar. 5. add contexts to the owning local player subsystem with explicit priority. 6. bind actions once during the pawn/controller input initialization lifecycle. 7. forward intent into gameplay systems. input code should not own authoritative outcomes. intent boundary input says what the local player requested. the receiver decides whether it is legal: - character movement consumes movement/jump requests; - gas attempts ability activation; - interaction component resolves and validates targets; - ui routing decides whether gameplay should receive input; - server validates multiplayer outcomes. use gameplay tags for semantic input routing only when the project benefits from data-driven ability/loadout binding. keep input tags separate from ability identity/state tags; route tag taxonomy to $unreal-gameplay-tags. gameplay input buffering and coyote time gameplay input buffering and coyote time enhanced input determines that an action was requested. buffering preserves that semantic request until gameplay can accept it. minimal buffer model store per buffered action: - semantic action identifier or input action; - local request timestamp using a consistent clock; - optional value/target/direction snapshot; - expiration duration; - consumed/canceled state. procedure: 1. on the deliberate input event (usually triggered or started), record/replace the request. 2. immediately ask the gameplay system whether it can execute. 3. re-evaluate only on relevant state changes or a bounded update path—landing, montage window, cooldown end, state-tag removal—not by spawning unbounded timers. 4. if legal and unexpired, consume exactly once and execute. 5. if expired, canceled, context removed, pawn changed, or input semantics invalidate it, clear. 6. server still validates the resulting action in multiplayer. pseudocode: text onjumprequested(now): bufferedjump = { requestedat: now, expiresat: now + jumpbufferwindow } tryconsumejump(now) onlanded(now): tryconsumejump(now) tryconsumejump(now): if bufferedjump exists and now <= expiresat and canjump(): clear bufferedjump jump() coyote time track the last valid grounded time. permit jump when grounded now or when now - lastgroundedtime <= coyotewindow. combine with the request buffer: - early press before landing → input buffer; - late press just after leaving edge → coyote time. they solve opposite timing errors and should have separate tuning variables/telemetry. ability/action buffer for attacks/abilities, store semantic intent and consume at the next legal cancel/combo window. do not replay raw key events. define whether the newest request replaces the oldest, how many requests can queue, and whether direction/target is sampled at press or execution. multiplayer local buffering improves responsiveness but does not authorize the result. for character movement, integrate through the predicted movement/command path. for gas, request ability activation and let server validation/prediction policies decide. do not send an expired queue of raw inputs to the server without bounded validation. mapping context ownership and lifecycle mapping context ownership and lifecycle owner applied contexts belong to uenhancedinputlocalplayersubsystem, so split-screen players and local profiles remain isolated. obtain the ulocalplayer from the correct playercontroller, then its subsystem. never use player index 0 as a hidden assumption in reusable code. context design - base/common context: actions valid across related gameplay modes. - mode context: on-foot, vehicle, swimming, build mode, spectator. - overlay context: temporary targeting, radial menu, photo mode, debug. - ui/common ui: follow the project's ui input-routing architecture and ue 5.8 unified input workflow; do not merely stack a high-priority gameplay context over ui focus. prefer mutually exclusive mode contexts over collisions resolved only by enormous priority numbers. priority is for intentional overlap, not lifecycle replacement. add/remove procedure 1. resolve the correct local player subsystem. 2. add each required context once with a documented priority. 3. on mode transition, remove the old mutually exclusive context, then add the new one. 4. decide whether held inputs should remain active across the rebuild. use fmodifycontextoptions where the api exposes the needed behavior. 5. remove temporary contexts on cancel, teardown, unpossess, or ui close. 6. log applied context, priority, owner, reason, and lifecycle in development builds. possession - playercontroller/localplayer can outlive a pawn. - put persistent player-wide context management on the playercontroller or localplayer-facing service. - bind pawn-specific action callbacks through setupplayerinputcomponent and avoid repeated binding on repossession. - when the pawn changes, route semantic actions to the new controlled object and clear stale references/buffers. multiplayer enhanced input runs locally. it does not replicate a context, trigger, or action value. convert input to server-validated commands, gas activation, or character movement input through the appropriate networking system. never treat the presence of an input action as proof that an authoritative action occurred. enhanced input patterns enhanced input patterns camera-relative 2d movement - iamove: axis2d. - keyboard mappings use negate/swizzle; gamepad stick maps directly with a dead zone. - bind triggered for continuous movement values and handle zero/end only if receiver needs it. - convert input axes using controller/camera yaw basis, then call addmovementinput for the character. - do not multiply addmovementinput scale by delta time; character movement consumes input and performs time integration. look - ialook: axis2d. - separate mouse and gamepad mappings/modifiers when sensitivity units/acceleration differ. - apply inversion/sensitivity in modifiers or a centralized settings layer. - test time-dilation and frame-rate behavior; mouse delta and stick rate may require different treatment. jump with forgiveness - iajump: boolean + pressed/appropriate one-shot semantics. - press records jump request; release calls stop jumping for variable height. - gameplay movement layer owns buffer and coyote windows. - clear on pawn/context changes and consume once. sprint - hold: started/triggered sets request; completed/canceled clears it. - toggle: pressed toggles local intent; gameplay/server can reject based on stamina/state. - a context should not contain competing hold and toggle implementations simultaneously. tap versus hold on one key prefer separate semantic actions sharing a key with tap and hold triggers, or one action whose trigger-state flow is deliberately interpreted. test quick release, exact threshold, long hold, focus loss, mapping rebuild, and simultaneous chord conditions. ensure tap does not fire after a successful hold unless designed. vehicle transition 1. keep common pause/chat actions in base context. 2. remove on-foot context. 3. add vehicle context at documented priority. 4. route actions to current controlled vehicle. 5. on exit/unpossess, reverse and clear held/buffered state. gas ability input - input action produces semantic input identifier/tag. - player input binding layer finds granted ability specs or sends a gameplay event. - gas owns activation legality, cost, cooldown, prediction, and cancellation. - keep press/release state if the ability needs held-input tasks. - route the ability lifecycle to $unreal-gas-abilities. input testing/injection use showdebug enhancedinput for live actions/mappings and showdebug devices for devices. use enhanced input injection or input.+key/input.-key for deterministic test support where appropriate. injection tests the input pipeline; it does not prove physical-device or os focus behavior. rebinding and user settings rebinding and user settings use ue 5.8 uenhancedinputusersettings and player-mappable key profiles for shipping remapping. authoring 1. enable enhanced input user settings in enhanced input developer/project settings. 2. mark each remappable action mapping with player mappable key settings at the mapping or referenced input action according to its setting behavior. 3. assign a stable unique mapping name, localized displayname, display category, supported profiles, and optional metadata. 4. use mapping slots for multiple bindings to the same semantic row, such as primary and secondary. 5. register every relevant input mapping context with user settings, including unloaded plugin contexts through the intended registration point. do not use localized labels or asset display names as persistent identity. runtime remap 1. obtain user settings from the correct enhanced input subsystem/local player. 2. query the current key profile and mapping row/slot. 3. capture the new fkey. 4. query/report collisions according to project policy before mapping. 5. build fmapplayerkeyargs with stable mapping name, slot, new key, and hardware/profile data required by the current api. 6. call mapplayerkey and inspect the returned failure-reason tag container. 7. apply settings/rebuild ui as required. 8. save settings asynchronously for ordinary ux unless the project has a reason to block. provide reset-row, reset-profile, clear-slot, cancel, and restore-default operations. surface failure reasons instead of silently failing. conflict policy choose and communicate one: - reject duplicate; - ask to swap; - replace old binding; - allow duplicates only across mutually exclusive contexts; - allow duplicates for accessibility. check device family, context overlap, action consumption/priority, and profile slot—not only whether the raw key appears anywhere. persistence tests - relaunch and load; - different local users/profiles; - primary/secondary slots; - keyboard, mouse, gamepad, and accessibility devices; - changed/removed mapping assets after an update; - plugin context registered while not loaded; - reset to defaults; - corrupted/missing save fallback; - localized ui does not alter stable mapping identity. ue 5.8 primary sources ue 5.8 primary sources verified 2026-07-19. - enhanced input - enhanced input api - etriggerevent api - uenhancedinputcomponent api - add mapping context blueprint api - uenhancedinputusersettings api - uenhancedinputdevelopersettings api - uplayermappablekeysettings api - register input mapping context - save settings - unreal engine 5.8 release notes version note: ue 5.8 unifies enhanced input and common input/ui workflows and fixes state loss and re-firing around mapping rebuilds. epic's current apis expose uenhancedinputusersettings, player-mappable profiles, mapping rows/slots, failure reasons, apply, and save operations. the gameplay-buffer procedure in this skill is an explicit project-layer pattern, not a claim that enhanced input provides a built-in precondition buffer. triggers and modifiers triggers and modifiers processing order raw device value → mapping/action modifiers → triggers → etriggerevent callbacks. use modifiers for values and triggers for activation conditions. modifier patterns - dead zone: suppress small analog noise; choose axial or radial behavior deliberately. - scalar: sensitivity or axis gain. - negate: invert selected axes or turn positive digital keys into negative input. - swizzle input axis values: move a 1d key value to another axis. - response/dead-zone custom modifier: only when built-ins cannot express the device curve. - world-space modifier: only when the receiver truly needs world-space input. for wasd feeding axis2d, epic's documented pattern is: | key | desired value | mapping modifiers | |---|---|---| | w | +y | swizzle axis | | a | −x | negate | | s | −y | negate + swizzle axis | | d | +x | none | normalize/clamp only when the design requires it. diagonal keyboard accumulation and analog magnitude must be tested rather than assumed. trigger patterns - pressed: one trigger as actuation crosses the threshold. - released: trigger on release after actuation. - hold: trigger after held duration; can be one-shot or repeated by configuration. - hold and release: trigger on release after minimum hold. - tap: press/release within threshold. - pulse: repeated interval while actuated. - chord: requires another input action. - blocker: prevents success when its condition succeeds. event binding semantics | event | use | |---|---| | started | begin evaluation/presentation, such as charging feedback | | ongoing | show incomplete hold/tap evaluation; may fire each tick | | triggered | execute successful semantic intent; repetition depends on trigger | | completed | handle normal end after a triggered action | | canceled | handle release/interruption before success | bind only the events the design needs. a raw action with no one-shot trigger can produce triggered repeatedly while actuated; do not use it for a one-shot action without deliberate trigger/event design. trigger composition explicit triggers require at least one explicit success, implicit triggers all must succeed, and blocker success forces failure. when mixing types, write a truth table and inspect showdebug enhancedinput. do not infer and/or behavior from asset ordering. stateful custom classes ue 5.8 preserves trigger/modifier state more reliably across mapping rebuilds. stateful custom blueprint/c++ triggers and modifiers should implement the current reinstancing callbacks so state transfers when mappings are rebuilt without semantic change. troubleshooting troubleshooting action never fires - confirm the correct mapping context is applied to the correct local player. - inspect context priority/collisions with showdebug enhancedinput. - confirm value type matches mapping and callback extraction. - inspect modifier output and trigger state/threshold. - confirm action is bound after possession/input component setup. action fires every frame instead of once - raw actuation with no one-shot trigger can trigger each tick. - use pressed or another deliberate one-shot trigger, or bind the correct event. - do not patch with a gameplay bool before understanding trigger semantics. hold never completes or tap fires unexpectedly - inspect hold/tap threshold, actuation threshold, explicit/implicit/blocker composition. - handle completed and canceled separately. - test focus loss and mapping rebuild while held. - ensure two actions sharing the key have intentional chord/blocker/priority behavior. input becomes stuck after opening ui - confirm ui input routing/focus and gameplay context lifecycle. - handle flushed input and canceled/completed cleanup. - clear gameplay held state when context/pawn changes. - in ue 5.8, check custom stateful modifier/trigger reinstancing implementation. context added but wrong action wins - inspect all active contexts and their priorities. - remove mutually exclusive context instead of relying only on priority. - check whether the same key maps to the same versus different actions. - revisit consume/chord behavior and ue 5.8 common ui integration. duplicate callback after respawn - bind actions once in the correct input-component lifecycle. - check repeated bindaction calls and stale pawn/component references. - keep context management separate from pawn callback binding. rebinding appears in ui but does not work - confirm mapping context is registered with user settings. - confirm stable mapping name, slot, profile, and device data. - inspect mapplayerkey failure-reason tags. - apply/rebuild as required and save the correct local player's settings. - query the active profile, not only the default asset mapping. keyboard diagonal is too fast - inspect accumulated axis2d magnitude after negate/swizzle. - clamp/normalize in the appropriate input/gameplay layer only if the design requires equal cardinal and diagonal magnitude. - preserve analog magnitude when normalizing digital input; one rule may not fit both devices. buffered action fires in the wrong state - clear on context removal, pawn replacement, death, cancel, or expiry. - revalidate legality at consumption time. - consume exactly once and log request/consume timestamps. - decide whether direction/target is captured at press or at execution.

Enhanced Input architecture

# Enhanced Input architecture

## Asset model

| Asset/type | Owns |
|---|---|
| `UInputAction` | Semantic intent and value type; optional action-level modifiers/triggers/settings |
| `UInputMappingContext` | Key-to-action mappings for one coherent context plus mapping-level modifiers/triggers |
| `UInputModifier` | Raw value transformation before trigger evaluation |
| `UInputTrigger` | Conditions/timing that decide action state |
| `UEnhancedInputLocalPlayerSubsystem` | Applied contexts and priorities for one local player |
| `UEnhancedInputComponent` | Action-to-delegate bindings in the input stack |
| `UEnhancedInputUserSettings` | Per-user mappable keys, profiles, input/accessibility settings, registration, persistence |

## Ordered setup

1. Ensure Enhanced Input is enabled and the project uses Enhanced Player Input / Enhanced
   Input Component classes where manual project setup requires them.
2. Create Input Actions named for intent: `IA_Move`, `IA_Look`, `IA_Jump`, `IA_Interact`.
3. Choose exact value types. A 2D move action should be Axis2D; a button is usually Boolean.
4. Create small Mapping Contexts by coherent availability/lifecycle: common gameplay, on-foot,
   vehicle, menu/debug, and similar.
5. Add contexts to the owning Local Player subsystem with explicit priority.
6. Bind actions once during the Pawn/Controller input initialization lifecycle.
7. Forward intent into gameplay systems. Input code should not own authoritative outcomes.

## Intent boundary

Input says what the local player requested. The receiver decides whether it is legal:

- Character Movement consumes movement/jump requests;
- GAS attempts ability activation;
- interaction component resolves and validates targets;
- UI routing decides whether gameplay should receive input;
- server validates multiplayer outcomes.

Use Gameplay Tags for semantic input routing only when the project benefits from data-driven
ability/loadout binding. Keep input tags separate from ability identity/state tags; route tag
taxonomy to `$unreal-gameplay-tags`.

# Gameplay input buffering and coyote time

Enhanced Input determines that an action was requested. Buffering preserves that semantic
request until gameplay can accept it.

## Minimal buffer model

Store per buffered action:

- semantic action identifier or Input Action;
- local request timestamp using a consistent clock;
- optional value/target/direction snapshot;
- expiration duration;
- consumed/canceled state.

Procedure:

1. On the deliberate input event (usually `Triggered` or `Started`), record/replace the request.
2. Immediately ask the gameplay system whether it can execute.
3. Re-evaluate only on relevant state changes or a bounded update path—landing, montage window,
   cooldown end, state-tag removal—not by spawning unbounded timers.
4. If legal and unexpired, consume exactly once and execute.
5. If expired, canceled, context removed, pawn changed, or input semantics invalidate it, clear.
6. Server still validates the resulting action in multiplayer.

Pseudocode:

```text
OnJumpRequested(now):
    bufferedJump = { requestedAt: now, expiresAt: now + JumpBufferWindow }
    TryConsumeJump(now)

OnLanded(now):
    TryConsumeJump(now)

TryConsumeJump(now):
    if bufferedJump exists and now <= expiresAt and CanJump():
        clear bufferedJump
        Jump()
```

## Coyote time

Track the last valid grounded time. Permit Jump when grounded now or when
`Now - LastGroundedTime <= CoyoteWindow`. Combine with the request buffer:

- early press before landing → input buffer;
- late press just after leaving edge → coyote time.

They solve opposite timing errors and should have separate tuning variables/telemetry.

## Ability/action buffer

For attacks/abilities, store semantic intent and consume at the next legal cancel/combo window.
Do not replay raw key events. Define whether the newest request replaces the oldest, how many
requests can queue, and whether direction/target is sampled at press or execution.

## Multiplayer

Local buffering improves responsiveness but does not authorize the result. For Character
movement, integrate through the predicted movement/command path. For GAS, request ability
activation and let server validation/prediction policies decide. Do not send an expired queue
of raw inputs to the server without bounded validation.

Mapping Context ownership and lifecycle

# Mapping Context ownership and lifecycle

## Owner

Applied contexts belong to `UEnhancedInputLocalPlayerSubsystem`, so split-screen players and
local profiles remain isolated. Obtain the `ULocalPlayer` from the correct PlayerController,
then its subsystem. Never use player index 0 as a hidden assumption in reusable code.

## Context design

- Base/common context: actions valid across related gameplay modes.
- Mode context: on-foot, vehicle, swimming, build mode, spectator.
- Overlay context: temporary targeting, radial menu, photo mode, debug.
- UI/Common UI: follow the project's UI input-routing architecture and UE 5.8 unified input
  workflow; do not merely stack a high-priority gameplay context over UI focus.

Prefer mutually exclusive mode contexts over collisions resolved only by enormous priority
numbers. Priority is for intentional overlap, not lifecycle replacement.

## Add/remove procedure

1. Resolve the correct Local Player subsystem.
2. Add each required context once with a documented priority.
3. On mode transition, remove the old mutually exclusive context, then add the new one.
4. Decide whether held inputs should remain active across the rebuild. Use
   `FModifyContextOptions` where the API exposes the needed behavior.
5. Remove temporary contexts on cancel, teardown, unpossess, or UI close.
6. Log applied context, priority, owner, reason, and lifecycle in development builds.

## Possession

- PlayerController/LocalPlayer can outlive a Pawn.
- Put persistent player-wide context management on the PlayerController or LocalPlayer-facing
  service.
- Bind Pawn-specific action callbacks through `SetupPlayerInputComponent` and avoid repeated
  binding on repossession.
- When the Pawn changes, route semantic actions to the new controlled object and clear stale
  references/buffers.

## Multiplayer

Enhanced Input runs locally. It does not replicate a context, trigger, or action value. Convert
input to server-validated commands, GAS activation, or Character movement input through the
appropriate networking system. Never treat the presence of an input action as proof that an
authoritative action occurred.

Enhanced Input patterns

# Enhanced Input patterns

## Camera-relative 2D movement

- `IA_Move`: Axis2D.
- Keyboard mappings use Negate/Swizzle; gamepad stick maps directly with a dead zone.
- Bind `Triggered` for continuous movement values and handle zero/end only if receiver needs it.
- Convert input axes using controller/camera yaw basis, then call `AddMovementInput` for the
  Character.
- Do not multiply `AddMovementInput` scale by delta time; Character Movement consumes input and
  performs time integration.

## Look

- `IA_Look`: Axis2D.
- Separate mouse and gamepad mappings/modifiers when sensitivity units/acceleration differ.
- Apply inversion/sensitivity in modifiers or a centralized settings layer.
- Test time-dilation and frame-rate behavior; mouse delta and stick rate may require different
  treatment.

## Jump with forgiveness

- `IA_Jump`: Boolean + Pressed/appropriate one-shot semantics.
- Press records jump request; release calls Stop Jumping for variable height.
- Gameplay movement layer owns buffer and coyote windows.
- Clear on pawn/context changes and consume once.

## Sprint

- Hold: Started/Triggered sets request; Completed/Canceled clears it.
- Toggle: Pressed toggles local intent; gameplay/server can reject based on stamina/state.
- A context should not contain competing hold and toggle implementations simultaneously.

## Tap versus hold on one key

Prefer separate semantic actions sharing a key with Tap and Hold triggers, or one action whose
trigger-state flow is deliberately interpreted. Test quick release, exact threshold, long hold,
focus loss, mapping rebuild, and simultaneous chord conditions. Ensure tap does not fire after a
successful hold unless designed.

## Vehicle transition

1. Keep common pause/chat actions in base context.
2. Remove on-foot context.
3. Add vehicle context at documented priority.
4. Route actions to current controlled vehicle.
5. On exit/unpossess, reverse and clear held/buffered state.

## GAS ability input

- Input Action produces semantic input identifier/tag.
- Player input binding layer finds granted ability specs or sends a Gameplay Event.
- GAS owns activation legality, cost, cooldown, prediction, and cancellation.
- Keep press/release state if the ability needs held-input tasks.
- Route the ability lifecycle to `$unreal-gas-abilities`.

## Input testing/injection

Use `showdebug enhancedinput` for live actions/mappings and `showdebug devices` for devices.
Use Enhanced Input injection or `Input.+key`/`Input.-key` for deterministic test support where
appropriate. Injection tests the input pipeline; it does not prove physical-device or OS focus
behavior.

Rebinding and user settings

# Rebinding and user settings

Use UE 5.8 `UEnhancedInputUserSettings` and player-mappable key profiles for shipping remapping.

## Authoring

1. Enable Enhanced Input user settings in Enhanced Input developer/project settings.
2. Mark each remappable action mapping with Player Mappable Key Settings at the mapping or
   referenced Input Action according to its Setting Behavior.
3. Assign a stable unique mapping `Name`, localized `DisplayName`, display category, supported
   profiles, and optional metadata.
4. Use mapping slots for multiple bindings to the same semantic row, such as primary and
   secondary.
5. Register every relevant Input Mapping Context with user settings, including unloaded plugin
   contexts through the intended registration point.

Do not use localized labels or asset display names as persistent identity.

## Runtime remap

1. Obtain user settings from the correct Enhanced Input subsystem/local player.
2. Query the current key profile and mapping row/slot.
3. Capture the new `FKey`.
4. Query/report collisions according to project policy before mapping.
5. Build `FMapPlayerKeyArgs` with stable mapping name, slot, new key, and hardware/profile data
   required by the current API.
6. Call `MapPlayerKey` and inspect the returned failure-reason tag container.
7. Apply settings/rebuild UI as required.
8. Save settings asynchronously for ordinary UX unless the project has a reason to block.

Provide reset-row, reset-profile, clear-slot, cancel, and restore-default operations. Surface
failure reasons instead of silently failing.

## Conflict policy

Choose and communicate one:

- reject duplicate;
- ask to swap;
- replace old binding;
- allow duplicates only across mutually exclusive contexts;
- allow duplicates for accessibility.

Check device family, context overlap, action consumption/priority, and profile slot—not only
whether the raw key appears anywhere.

## Persistence tests

- relaunch and load;
- different local users/profiles;
- primary/secondary slots;
- keyboard, mouse, gamepad, and accessibility devices;
- changed/removed mapping assets after an update;
- plugin context registered while not loaded;
- reset to defaults;
- corrupted/missing save fallback;
- localized UI does not alter stable mapping identity.

UE 5.8 primary sources

# UE 5.8 primary sources

Verified 2026-07-19.

- [Enhanced Input](https://dev.epicgames.com/documentation/en-us/unreal-engine/enhanced-input-in-unreal-engine)
- [Enhanced Input API](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/EnhancedInput)
- [`ETriggerEvent` API](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/EnhancedInput/ETriggerEvent)
- [`UEnhancedInputComponent` API](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/EnhancedInput/UEnhancedInputComponent)
- [Add Mapping Context Blueprint API](https://dev.epicgames.com/documentation/en-us/unreal-engine/BlueprintAPI/Input/AddMappingContext)
- [`UEnhancedInputUserSettings` API](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/EnhancedInput/UEnhancedInputUserSettings)
- [`UEnhancedInputDeveloperSettings` API](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/EnhancedInput/UEnhancedInputDeveloperSettings)
- [`UPlayerMappableKeySettings` API](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Plugins/EnhancedInput/UPlayerMappableKeySettings)
- [Register Input Mapping Context](https://dev.epicgames.com/documentation/en-us/unreal-engine/BlueprintAPI/EnhancedInput/UserSettings/RegisterInputMappingContext)
- [Save Settings](https://dev.epicgames.com/documentation/en-us/unreal-engine/BlueprintAPI/EnhancedInput/UserSettings/SaveSettings)
- [Unreal Engine 5.8 Release Notes](https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-5-8-release-notes)

Version note: UE 5.8 unifies Enhanced Input and Common Input/UI workflows and fixes state loss
and re-firing around mapping rebuilds. Epic's current APIs expose `UEnhancedInputUserSettings`,
player-mappable profiles, mapping rows/slots, failure reasons, apply, and save operations. The
gameplay-buffer procedure in this skill is an explicit project-layer pattern, not a claim that
Enhanced Input provides a built-in precondition buffer.

Triggers and modifiers

# Triggers and modifiers

## Processing order

Raw device value → mapping/action modifiers → triggers → `ETriggerEvent` callbacks.

Use modifiers for values and triggers for activation conditions.

## Modifier patterns

- Dead Zone: suppress small analog noise; choose axial or radial behavior deliberately.
- Scalar: sensitivity or axis gain.
- Negate: invert selected axes or turn positive digital keys into negative input.
- Swizzle Input Axis Values: move a 1D key value to another axis.
- Response/dead-zone custom modifier: only when built-ins cannot express the device curve.
- World-space modifier: only when the receiver truly needs world-space input.

For WASD feeding Axis2D, Epic's documented pattern is:

| Key | Desired value | Mapping modifiers |
|---|---|---|
| W | +Y | Swizzle axis |
| A | −X | Negate |
| S | −Y | Negate + Swizzle axis |
| D | +X | None |

Normalize/clamp only when the design requires it. Diagonal keyboard accumulation and analog
magnitude must be tested rather than assumed.

## Trigger patterns

- Pressed: one trigger as actuation crosses the threshold.
- Released: trigger on release after actuation.
- Hold: trigger after held duration; can be one-shot or repeated by configuration.
- Hold And Release: trigger on release after minimum hold.
- Tap: press/release within threshold.
- Pulse: repeated interval while actuated.
- Chord: requires another Input Action.
- Blocker: prevents success when its condition succeeds.

## Event binding semantics

| Event | Use |
|---|---|
| `Started` | Begin evaluation/presentation, such as charging feedback |
| `Ongoing` | Show incomplete hold/tap evaluation; may fire each tick |
| `Triggered` | Execute successful semantic intent; repetition depends on trigger |
| `Completed` | Handle normal end after a triggered action |
| `Canceled` | Handle release/interruption before success |

Bind only the events the design needs. A raw action with no one-shot trigger can produce
Triggered repeatedly while actuated; do not use it for a one-shot action without deliberate
trigger/event design.

## Trigger composition

Explicit triggers require at least one explicit success, implicit triggers all must succeed,
and blocker success forces failure. When mixing types, write a truth table and inspect
`showdebug enhancedinput`. Do not infer AND/OR behavior from asset ordering.

## Stateful custom classes

UE 5.8 preserves trigger/modifier state more reliably across mapping rebuilds. Stateful custom
Blueprint/C++ triggers and modifiers should implement the current reinstancing callbacks so
state transfers when mappings are rebuilt without semantic change.

Troubleshooting

# Troubleshooting

## Action never fires

- Confirm the correct Mapping Context is applied to the correct Local Player.
- Inspect context priority/collisions with `showdebug enhancedinput`.
- Confirm value type matches mapping and callback extraction.
- Inspect modifier output and trigger state/threshold.
- Confirm action is bound after possession/input component setup.

## Action fires every frame instead of once

- Raw actuation with no one-shot trigger can Trigger each tick.
- Use Pressed or another deliberate one-shot trigger, or bind the correct event.
- Do not patch with a gameplay bool before understanding trigger semantics.

## Hold never completes or tap fires unexpectedly

- Inspect Hold/Tap threshold, actuation threshold, explicit/implicit/blocker composition.
- Handle Completed and Canceled separately.
- Test focus loss and mapping rebuild while held.
- Ensure two actions sharing the key have intentional chord/blocker/priority behavior.

## Input becomes stuck after opening UI

- Confirm UI input routing/focus and gameplay context lifecycle.
- Handle flushed input and Canceled/Completed cleanup.
- Clear gameplay held state when context/pawn changes.
- In UE 5.8, check custom stateful modifier/trigger reinstancing implementation.

## Context added but wrong action wins

- Inspect all active contexts and their priorities.
- Remove mutually exclusive context instead of relying only on priority.
- Check whether the same key maps to the same versus different actions.
- Revisit consume/chord behavior and UE 5.8 Common UI integration.

## Duplicate callback after respawn

- Bind actions once in the correct input-component lifecycle.
- Check repeated `BindAction` calls and stale Pawn/component references.
- Keep context management separate from Pawn callback binding.

## Rebinding appears in UI but does not work

- Confirm mapping context is registered with user settings.
- Confirm stable mapping name, slot, profile, and device data.
- Inspect `MapPlayerKey` failure-reason tags.
- Apply/rebuild as required and save the correct Local Player's settings.
- Query the active profile, not only the default asset mapping.

## Keyboard diagonal is too fast

- Inspect accumulated Axis2D magnitude after Negate/Swizzle.
- Clamp/normalize in the appropriate input/gameplay layer only if the design requires equal
  cardinal and diagonal magnitude.
- Preserve analog magnitude when normalizing digital input; one rule may not fit both devices.

## Buffered action fires in the wrong state

- Clear on context removal, pawn replacement, death, cancel, or expiry.
- Revalidate legality at consumption time.
- Consume exactly once and log request/consume timestamps.
- Decide whether direction/target is captured at press or at execution.


unreal-gameplay-tags

Unreal 5.8 Gameplay Tags

Design and apply governed gameplay tag systems

---
name: unreal-gameplay-tags
description: Design, govern, implement, query, replicate, and debug Gameplay Tags in Unreal Engine 5.8. Use for tag taxonomies, native or config tags, tag containers, exact versus hierarchical matching, Gameplay Tag Queries, restricted tags, state and identity tags, GAS gating, gameplay events, UI categories, migration from booleans or enums, or failures caused by missing, redirected, or mismatched tags.
---

# Unreal 5.8 Gameplay Tags

## Design the vocabulary first

Read [`references/taxonomy.md`](references/taxonomy.md).

1. State what each root means and who owns it.
2. Separate semantic roles, for example `State.*`, `Ability.*`, `Event.*`, `InputTag.*`,
   `Item.*`, `Damage.*`, and `UI.*`.
3. Use one canonical tag for one concept. Add redirects for renames; do not leave synonyms.
4. Declare stable code-facing tags natively. Use config sources for designer-managed sets.
5. Restrict editing of core roots on teams that need ownership enforcement.

## Select the operation

Read [`references/operations.md`](references/operations.md).

- Use `FGameplayTag` for one registered tag.
- Use `FGameplayTagContainer` for a set; it tracks explicitly added tags and their parents.
- Use hierarchical matching when a broad rule should include descendants.
- Use exact matching when only the literal tag is valid.
- Use `FGameplayTagQuery` for authored combinations of any/all/none expressions.
- Use a Gameplay Event tag for an occurrence with payload; use a state tag for a condition
  that remains true.

## Execute

1. Register tags before use through native definitions, config, Project Settings, or a
   Data Table source.
2. Store containers, not arrays of tag strings.
3. Choose exact or hierarchical semantics explicitly at every comparison.
4. Apply and remove runtime tags through the system that owns their lifetime—often an ASC
   effect or ability—rather than unrelated objects editing a loose container.
5. Keep input routing tags separate from gameplay state and ability identity.
6. Test parent/child direction, empty containers/queries, tag removal, redirects, cooked
   builds, replication, and save migration.

Read [`references/patterns.md`](references/patterns.md) for state, gating, events, identity,
and UI examples. Read [`references/migration-troubleshooting.md`](references/migration-troubleshooting.md)
when converting bools/enums or diagnosing invalid and non-matching tags.

## Required answer format

Return:

1. **Proposed taxonomy**, owners, and definitions.
2. **Storage type** and exact/hierarchical/query semantics.
3. **Ordered Blueprint nodes or C++ calls** using verified UE names.
4. **Lifetime and authority** for every runtime tag.
5. **Rename/save/replication consequences**.
6. **Truth-table tests** covering parent, child, exact, absent, and empty cases.

Do not invent tags, APIs, editor paths, or GAS behavior.

## Hard rules

- Never compare tag text manually.
- Never assume matching is symmetric: `A.B` matches query `A`, but `A` does not match
  query `A.B`.
- Never use exact matching accidentally when parent semantics are intended, or vice versa.
- Never use tags as an ungoverned replacement for every bool, enum, identifier, or value.
- Never make a gameplay event tag double as persistent state.
- Never rename a shipped tag without a redirect and save/content migration plan.

See [`references/sources.md`](references/sources.md) for the UE 5.8 source trail.

## Design the vocabulary first

Read [`references/taxonomy.md`](/unreal/unreal-gameplay-tags/taxonomy/).

1. State what each root means and who owns it.
2. Separate semantic roles, for example `State.*`, `Ability.*`, `Event.*`, `InputTag.*`,
   `Item.*`, `Damage.*`, and `UI.*`.
3. Use one canonical tag for one concept. Add redirects for renames; do not leave synonyms.
4. Declare stable code-facing tags natively. Use config sources for designer-managed sets.
5. Restrict editing of core roots on teams that need ownership enforcement.

## Select the operation

Read [`references/operations.md`](/unreal/unreal-gameplay-tags/operations/).

- Use `FGameplayTag` for one registered tag.
- Use `FGameplayTagContainer` for a set; it tracks explicitly added tags and their parents.
- Use hierarchical matching when a broad rule should include descendants.
- Use exact matching when only the literal tag is valid.
- Use `FGameplayTagQuery` for authored combinations of any/all/none expressions.
- Use a Gameplay Event tag for an occurrence with payload; use a state tag for a condition
  that remains true.

## Execute

1. Register tags before use through native definitions, config, Project Settings, or a
   Data Table source.
2. Store containers, not arrays of tag strings.
3. Choose exact or hierarchical semantics explicitly at every comparison.
4. Apply and remove runtime tags through the system that owns their lifetime—often an ASC
   effect or ability—rather than unrelated objects editing a loose container.
5. Keep input routing tags separate from gameplay state and ability identity.
6. Test parent/child direction, empty containers/queries, tag removal, redirects, cooked
   builds, replication, and save migration.

Read [`references/patterns.md`](/unreal/unreal-gameplay-tags/patterns/) for state, gating, events, identity,
and UI examples. Read [`references/migration-troubleshooting.md`](/unreal/unreal-gameplay-tags/migration-troubleshooting/)
when converting bools/enums or diagnosing invalid and non-matching tags.

## Required answer format

Return:

1. **Proposed taxonomy**, owners, and definitions.
2. **Storage type** and exact/hierarchical/query semantics.
3. **Ordered Blueprint nodes or C++ calls** using verified UE names.
4. **Lifetime and authority** for every runtime tag.
5. **Rename/save/replication consequences**.
6. **Truth-table tests** covering parent, child, exact, absent, and empty cases.

Do not invent tags, APIs, editor paths, or GAS behavior.

## Hard rules

- Never compare tag text manually.
- Never assume matching is symmetric: `A.B` matches query `A`, but `A` does not match
  query `A.B`.
- Never use exact matching accidentally when parent semantics are intended, or vice versa.
- Never use tags as an ungoverned replacement for every bool, enum, identifier, or value.
- Never make a gameplay event tag double as persistent state.
- Never rename a shipped tag without a redirect and save/content migration plan.

See [`references/sources.md`](/unreal/unreal-gameplay-tags/sources/) for the UE 5.8 source trail.

unreal 5.8 gameplay tags design, govern, implement, query, replicate, and debug gameplay tags in unreal engine 5.8. use for tag taxonomies, native or config tags, tag containers, exact versus hierarchical matching, gameplay tag queries, restricted tags, state and identity tags, gas gating, gameplay events, ui categories, migration from booleans or enums, or failures caused by missing, redirected, or mismatched tags. migration and troubleshooting migration and troubleshooting bool to tag convert a bool when the state is cross-system, needs gas gating, has multiple sources, or is part of a growing family. 1. define the canonical tag and its owner/lifetime. 2. replace writers with owned add/remove behavior. 3. replace readers with exact or hierarchical queries. 4. add source-count/lifetime handling if multiple systems can grant the state; do not let one source remove another source's truth. 5. remove the bool after tests prove parity. keep a private, local, performance-critical bool when a global vocabulary adds no value. enum to tags keep an enum for one mutually exclusive closed state machine. use tags when categories are open-ended, hierarchical, or multiple values can coexist. if converting: 1. state whether exclusivity still applies; 2. enforce removal of sibling state tags centrally; 3. migrate serialized enum values; 4. test no-state and invalid multi-state cases. tag is invalid - confirm it exists in the registered dictionary in the cooked build. - confirm the config/tag source is included and plugin/module loads when expected. - for native request apis, do not suppress a missing critical tag without logging. - avoid constructing/comparing raw strings. parent query fails - check direction: stored child can satisfy queried parent, not the reverse. - confirm exact variant was not used. - inspect explicit container tags and expected parents. - confirm both tags are valid and registered. tag remains after state ends - identify the granting source: loose asc tag, active effect, ability-owned tag, or custom container. - pair lifetime with that source and remove by effect/ability handle when possible. - check multiple grants/stacks; one removal may correctly leave another source active. rename breaks content or saves - add a gameplay tag redirect from old to new. - resave/migrate dependent assets and serialized data. - audit text/config/data tables and native constants. - remove the redirect only after all supported content/save versions are migrated. query permits everything - inspect empty all/no expressions and empty containers. - build truth-table tests for required present, required absent, blocker present, no tags, parent only, and child only. tag operations tag operations types - fgameplaytag: one registered hierarchical name. - fgameplaytagcontainer: explicit tags plus cached parent relationships. - fgameplaytagquery: serialized any/all/none expression tree evaluated against a container. use containers instead of tarray<fgameplaytag> for tag-set behavior. matching direction given stored tag state.movement.sprinting: | test | result | |---|---| | hierarchical hastag(state.movement) | true | | exact hastagexact(state.movement) | false | | hierarchical query for state.movement.sprinting.fast | false | | exact query for state.movement.sprinting | true | matching is directional. a child satisfies a parent query; a parent does not satisfy a more specific child query. for individual tags, matchestag includes parent matching and matchestagexact requires the literal tag. for containers, use hastag, hasany, and hasall or their exact variants. empty semantics epic documents that an empty input container returns false for hastag/any-style tests, while all-style tests return true because no required tag is missing. empty query expressions have similar logical identities. test empty authored queries; a missing requirement can otherwise silently allow everything. query selection use direct container operations for simple code-owned checks. use fgameplaytagquery when: - designers author nested any/all/none logic; - the rule is stored in a data asset/table; - multiple systems evaluate the same serialized rule. example prerequisite: all(any(state.weapon.rifle, state.weapon.pistol), none(state.disabled, state.dead)) keep queries named/documented. dense anonymous query trees become difficult to debug. blueprint implementation use gameplay tag and gameplay tag container variable types and the gameplay tags blueprint library functions shown by the context menu. confirm exact versus non-exact node choice in ue 5.8; do not compare tostring output. gameplay tag patterns gameplay tag patterns persistent state use state.stunned, state.dead, or state.movement.sprinting while the condition is true. one system owns addition/removal. in gas, prefer state granted by the active effect/ability whose lifetime creates the state so removal is deterministic. test: - tag present during condition; - parent queries succeed; - exact sibling queries fail; - tag removes on expiry, cancellation, death, and teardown. ability gating separate: - ability identity: ability.movement.dash; - state owned while active: state.movement.dashing; - activation blocker: state.stunned; - input route: inputtag.ability.dash; - activation event: event.ability.dashrequested if an event path is used. configure required/blocked/cancel relationships through gas's current tag relationship settings/components and verify with failure tags. route full ability procedure to $unreal-gas-abilities. gameplay event use an event tag for a momentary occurrence plus fgameplayeventdata, such as event.combat.hitconfirmed. do not add/remove it as though it were state. define which machine sends/handles it and validate its payload and targets. identity and categorization use tags for extensible categories and cross-system queries, for example item.weapon.ranged.bow or damage.element.fire. keep a stable primary identifier separate when save identity must distinguish two assets that share the same categories. tags classify; they are not automatically unique ids. ui categories ui can map gameplay categories to presentation, but do not let display wording become the canonical gameplay taxonomy. localize labels separately. keep ui-only navigation/action tags under a ui root. message channels tags work well as channel identifiers for a scoped message system. define payload type and network scope separately. hierarchical listener semantics must be explicit; do not assume a message bus uses the same parent matching as a tag container. ue 5.8 primary sources ue 5.8 primary sources verified 2026-07-19. - using gameplay tags - fgameplaytag api - fgameplaytagcontainer api - gameplay ability system overview - abilities in lyra version note: these epic pages currently resolve to unreal engine 5.8. the exact versus hierarchical truth tables in this skill follow epic's 5.8 fgameplaytag and fgameplaytagcontainer api descriptions, including directional parent matching and empty all-container behavior. gameplay tag taxonomy gameplay tag taxonomy root design define roots by semantic role, not by whichever feature first needs a tag. | root example | meaning | |---|---| | state. | condition currently true on an entity | | ability. | ability identity/family | | event. | occurrence or request carrying an event payload | | inputtag. | semantic input routing identifier | | item. | item identity/category | | damage. | damage type/category | | gameplaycue. | cosmetic cue identity used by gas | | ui. | ui layer/action/category identity | do not mix these roles. inputtag.ability.primary may activate ability.weapon.fire, but neither should be used as state.firing unless that is genuinely the same semantic fact. naming rules - use pascalcase or the project's chosen stable convention consistently per segment. - make parent meaning include all descendants. - prefer nouns/categories for identity and adjectives/conditions for state where readable. - avoid synonyms: choose state.stunned or status.stunned, not both. - avoid implementation names such as a blueprint class path in the taxonomy. - add developer comments describing ownership and lifetime for non-obvious tags. definition method - native tags: stable tags referenced from c++; use epic's native declaration/definition macros and inspect lyra's tag files for the 5.8 pattern. - config tags: designer-managed dictionary, optionally separated into config/tags sources for ownership and merge clarity. - data table tags: useful when an external table workflow is deliberate. - project settings: convenient management ui over configured sources. governance 1. assign an owner for every root. 2. review new parents because their semantics affect all descendants. 3. use restricted tag settings for protected roots when team scale requires it. 4. add redirects for renames and remove obsolete references through a migration pass. 5. validate assets and saves before deleting the redirect. the taxonomy is an api. version it with the same care as function names and serialized ids.

Migration and troubleshooting

# Migration and troubleshooting

## Bool to tag

Convert a bool when the state is cross-system, needs GAS gating, has multiple sources, or is
part of a growing family.

1. Define the canonical tag and its owner/lifetime.
2. Replace writers with owned add/remove behavior.
3. Replace readers with exact or hierarchical queries.
4. Add source-count/lifetime handling if multiple systems can grant the state; do not let one
   source remove another source's truth.
5. Remove the bool after tests prove parity.

Keep a private, local, performance-critical bool when a global vocabulary adds no value.

## Enum to tags

Keep an enum for one mutually exclusive closed state machine. Use tags when categories are
open-ended, hierarchical, or multiple values can coexist. If converting:

1. state whether exclusivity still applies;
2. enforce removal of sibling state tags centrally;
3. migrate serialized enum values;
4. test no-state and invalid multi-state cases.

## Tag is invalid

- Confirm it exists in the registered dictionary in the cooked build.
- Confirm the config/tag source is included and plugin/module loads when expected.
- For native request APIs, do not suppress a missing critical tag without logging.
- Avoid constructing/comparing raw strings.

## Parent query fails

- Check direction: stored child can satisfy queried parent, not the reverse.
- Confirm exact variant was not used.
- Inspect explicit container tags and expected parents.
- Confirm both tags are valid and registered.

## Tag remains after state ends

- Identify the granting source: loose ASC tag, active effect, ability-owned tag, or custom
  container.
- Pair lifetime with that source and remove by effect/ability handle when possible.
- Check multiple grants/stacks; one removal may correctly leave another source active.

## Rename breaks content or saves

- Add a Gameplay Tag redirect from old to new.
- Resave/migrate dependent assets and serialized data.
- Audit text/config/Data Tables and native constants.
- Remove the redirect only after all supported content/save versions are migrated.

## Query permits everything

- Inspect empty All/No expressions and empty containers.
- Build truth-table tests for required present, required absent, blocker present, no tags,
  parent only, and child only.

Tag operations

# Tag operations

## Types

- `FGameplayTag`: one registered hierarchical name.
- `FGameplayTagContainer`: explicit tags plus cached parent relationships.
- `FGameplayTagQuery`: serialized any/all/none expression tree evaluated against a container.

Use containers instead of `TArray<FGameplayTag>` for tag-set behavior.

## Matching direction

Given stored tag `State.Movement.Sprinting`:

| Test | Result |
|---|---|
| hierarchical `HasTag(State.Movement)` | true |
| exact `HasTagExact(State.Movement)` | false |
| hierarchical query for `State.Movement.Sprinting.Fast` | false |
| exact query for `State.Movement.Sprinting` | true |

Matching is directional. A child satisfies a parent query; a parent does not satisfy a more
specific child query.

For individual tags, `MatchesTag` includes parent matching and `MatchesTagExact` requires the
literal tag. For containers, use `HasTag`, `HasAny`, and `HasAll` or their `Exact` variants.

## Empty semantics

Epic documents that an empty input container returns false for HasTag/Any-style tests, while
All-style tests return true because no required tag is missing. Empty query expressions have
similar logical identities. Test empty authored queries; a missing requirement can otherwise
silently allow everything.

## Query selection

Use direct container operations for simple code-owned checks. Use `FGameplayTagQuery` when:

- designers author nested any/all/none logic;
- the rule is stored in a Data Asset/Table;
- multiple systems evaluate the same serialized rule.

Example prerequisite:

`ALL(ANY(State.Weapon.Rifle, State.Weapon.Pistol), NONE(State.Disabled, State.Dead))`

Keep queries named/documented. Dense anonymous query trees become difficult to debug.

## Blueprint implementation

Use Gameplay Tag and Gameplay Tag Container variable types and the Gameplay Tags Blueprint
library functions shown by the context menu. Confirm exact versus non-exact node choice in
UE 5.8; do not compare `ToString` output.

Gameplay Tag patterns

# Gameplay Tag patterns

## Persistent state

Use `State.Stunned`, `State.Dead`, or `State.Movement.Sprinting` while the condition is true.
One system owns addition/removal. In GAS, prefer state granted by the active effect/ability
whose lifetime creates the state so removal is deterministic.

Test:

- tag present during condition;
- parent queries succeed;
- exact sibling queries fail;
- tag removes on expiry, cancellation, death, and teardown.

## Ability gating

Separate:

- ability identity: `Ability.Movement.Dash`;
- state owned while active: `State.Movement.Dashing`;
- activation blocker: `State.Stunned`;
- input route: `InputTag.Ability.Dash`;
- activation event: `Event.Ability.DashRequested` if an event path is used.

Configure required/blocked/cancel relationships through GAS's current tag relationship
settings/components and verify with failure tags. Route full ability procedure to
`$unreal-gas-abilities`.

## Gameplay Event

Use an Event tag for a momentary occurrence plus `FGameplayEventData`, such as
`Event.Combat.HitConfirmed`. Do not add/remove it as though it were state. Define which
machine sends/handles it and validate its payload and targets.

## Identity and categorization

Use tags for extensible categories and cross-system queries, for example
`Item.Weapon.Ranged.Bow` or `Damage.Element.Fire`. Keep a stable primary identifier separate
when save identity must distinguish two assets that share the same categories.

Tags classify; they are not automatically unique IDs.

## UI categories

UI can map gameplay categories to presentation, but do not let display wording become the
canonical gameplay taxonomy. Localize labels separately. Keep UI-only navigation/action tags
under a UI root.

## Message channels

Tags work well as channel identifiers for a scoped message system. Define payload type and
network scope separately. Hierarchical listener semantics must be explicit; do not assume a
message bus uses the same parent matching as a tag container.

UE 5.8 primary sources

# UE 5.8 primary sources

Verified 2026-07-19.

- [Using Gameplay Tags](https://dev.epicgames.com/documentation/en-us/unreal-engine/using-gameplay-tags-in-unreal-engine)
- [`FGameplayTag` API](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/GameplayTags/FGameplayTag)
- [`FGameplayTagContainer` API](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/GameplayTags/FGameplayTagContainer)
- [Gameplay Ability System Overview](https://dev.epicgames.com/documentation/en-us/unreal-engine/understanding-the-unreal-engine-gameplay-ability-system)
- [Abilities in Lyra](https://dev.epicgames.com/documentation/en-us/unreal-engine/abilities-in-lyra-in-unreal-engine)

Version note: these Epic pages currently resolve to Unreal Engine 5.8. The exact versus
hierarchical truth tables in this skill follow Epic's 5.8 `FGameplayTag` and
`FGameplayTagContainer` API descriptions, including directional parent matching and empty
All-container behavior.

Gameplay Tag taxonomy

# Gameplay Tag taxonomy

## Root design

Define roots by semantic role, not by whichever feature first needs a tag.

| Root example | Meaning |
|---|---|
| `State.*` | Condition currently true on an entity |
| `Ability.*` | Ability identity/family |
| `Event.*` | Occurrence or request carrying an event payload |
| `InputTag.*` | Semantic input routing identifier |
| `Item.*` | Item identity/category |
| `Damage.*` | Damage type/category |
| `GameplayCue.*` | Cosmetic cue identity used by GAS |
| `UI.*` | UI layer/action/category identity |

Do not mix these roles. `InputTag.Ability.Primary` may activate `Ability.Weapon.Fire`, but
neither should be used as `State.Firing` unless that is genuinely the same semantic fact.

## Naming rules

- Use PascalCase or the project's chosen stable convention consistently per segment.
- Make parent meaning include all descendants.
- Prefer nouns/categories for identity and adjectives/conditions for state where readable.
- Avoid synonyms: choose `State.Stunned` or `Status.Stunned`, not both.
- Avoid implementation names such as a Blueprint class path in the taxonomy.
- Add developer comments describing ownership and lifetime for non-obvious tags.

## Definition method

- Native tags: stable tags referenced from C++; use Epic's native declaration/definition
  macros and inspect Lyra's tag files for the 5.8 pattern.
- Config tags: designer-managed dictionary, optionally separated into `Config/Tags` sources
  for ownership and merge clarity.
- Data Table tags: useful when an external table workflow is deliberate.
- Project Settings: convenient management UI over configured sources.

## Governance

1. Assign an owner for every root.
2. Review new parents because their semantics affect all descendants.
3. Use restricted tag settings for protected roots when team scale requires it.
4. Add redirects for renames and remove obsolete references through a migration pass.
5. Validate assets and saves before deleting the redirect.

The taxonomy is an API. Version it with the same care as function names and serialized IDs.