Files
UE5-Modular-Game-Framework/docs/game/state-gating-examples.md
Lefteris Notas 040db37720 Add UI Overrides and Weapons Index documentation for Project Void
- Created ui-overrides.md detailing game-specific Widget Blueprint overrides, including purpose, widget index, visual styling, and accessibility requirements.
- Established weapons-index.md outlining all held weapon actors, including their components, logic, and comparisons for gameplay mechanics.
2026-05-21 22:27:57 +03:00

11 KiB

State Gating Examples — Game-Specific State Rules

Game: Project Void | Build Phase: 14 (Data Asset configuration) Framework Systems: 130_BPC_StateManager, 131_DA_StateGatingTable


Purpose

Defines game-specific state gating rules added to DA_StateGatingTable (131). These rules determine what actions are permitted in each game state. Designers can modify these without touching any Blueprint code.


How State Gating Works (Quick Refresher)

Any system that wants to perform an action:

   Actor → BPC_StateManager.IsActionPermitted(ActionTag)
   │
   ├─ StateManager checks DA_StateGatingTable for rule matching ActionTag
   ├─ Rule specifies which states BLOCK this action
   ├─ If current state matches blocked state:
   │    └─ Return { bPermitted = false, BlockReason = "Cannot [Action] — [Reason]" }
   └─ If current state doesn't match:
        └─ Return { bPermitted = true }

Result struct: S_ActionPermissionResult
   ├─ bPermitted: Boolean
   ├─ BlockReason: FText (shown to player via InteractionPromptDisplay)
   └─ BlockingState: GameplayTag (for debug/logging)

Framework Default Rules (from DA_StateGatingTable, 37 rules)

These come from the framework and apply to all games:

Action Blocked By
Move Death, Cutscene, Loading, Exhausted
Look Cutscene, Loading
Interact Death, Cutscene, Loading, Hiding, Reloading
Fire Death, Cutscene, Loading, Hiding, Reloading, Exhausted, Sprinting
Reload Death, Cutscene, Loading, Hiding, Exhausted
Sprint Death, Cutscene, Loading, Crouching, Exhausted
Crouch Death, Cutscene, Loading, Sprinting
Jump Death, Cutscene, Loading, Crouching
Equip Death, Cutscene, Loading, Hiding, Reloading
UseItem Death, Cutscene, Loading, Hiding
Hide Death, Cutscene, Loading, Sprinting, Exhausted, InCombat
Pause Death, Cutscene, Loading, AltDeathSpace
... (30+ more rules — see 131_DA_StateGatingTable.md)

Game-Specific Rules (Project Void)

These are added on top of the framework defaults. They represent horror-game-specific restrictions.

1. Combat Rules

Action Tag Blocked By Block Reason Notes
Fire State.InVoidSpace "Your weapon has no power here." Weapons don't work in void space
Fire State.Catatonic "Your hands shake too much to aim." Stress 100 = can't shoot
Reload State.InVoidSpace "Ammunition is meaningless in the void." Void space blocks reload
Melee State.InVoidSpace "You swing at shadows." Melee also useless in void

2. Void Space Rules

Action Tag Blocked By Block Reason Notes
Interact State.VoidShiftActive "Reality is unstable. Nothing responds correctly." During void shift events, interaction is unreliable (50% chance success)
Move State.VoidParalyzed "The void holds you still." Scripted moments where player is frozen
Pause State.AltDeathSpace "There is no escape from the void." No pause menu in void space
OpenInventory State.AltDeathSpace "Your belongings feel distant here." No inventory in void space
UseItem State.AltDeathSpace "Items from your world have no effect." Can't use consumables in void space

3. Horror-Specific Rules

Action Tag Blocked By Block Reason Notes
Sprint State.Exhausted "You're too exhausted to run." After stamina depleted for 3+ seconds
Sprint State.Catatonic "Your body won't obey." Stress 100 = no sprint
Interact State.InCombat "Too dangerous! Find cover first." Can't search drawers while enemy is attacking
Hide State.InCombat "Hide quickly before they see you!" Transition period of 2s after combat starts, then allowed
Hide State.Catatonic "You can't think clearly enough to hide." Stress 100 = can't hide
Flashlight State.Exhausted "Your arm is too weak to hold the light." Exhausted state dims flashlight to 25% instead of blocking
OpenWatch State.Hiding ALLOWED (override framework block) — can check inventory while hiding

4. Narrative/Dialogue Rules

Action Tag Blocked By Block Reason Notes
All (wildcard) State.InDialogueChoice "Make your choice." ALL actions blocked during dialogue choice
Move State.InDialogueChoice "You stand before the entity, frozen." Can't walk away mid-choice
Equip State.InCutscene Framework default already blocks
Pause State.InEndingSequence "This moment cannot be paused." Ending cutscene blocks pause

5. Death State Rules

Action Tag Blocked By Block Reason Notes
All (wildcard) State.Dead "You are dead." ALL actions blocked
Pause State.Dead "Press Continue to respawn." Pause menu blocked on death screen (death screen is the menu)
Look State.Dead ALLOWED (override) — camera still follows ragdoll briefly

DA_StateGatingTable Game-Specific Configuration

How to Add These Rules in UE5

  1. Open DA_StateGatingTable (Content/Framework/State/)
  2. Duplicate it → DA_StateGatingTable_Horror (Content/Game/DataAssets/)
  3. The framework DA_StateGatingTable has 37 base rules. The game-specific table inherits them.
  4. Add new entries for game-specific rules.

Rule: NEVER modify DA_StateGatingTable in Framework/. Use your game copy.

Rule Entry Structure

S_StateGatingRule (struct):
  ├─ ActionTag: GameplayTag              (e.g., Framework.Action.Fire)
  ├─ BlockedStateTags: Array<GameplayTag> (e.g., State.InVoidSpace)
  ├─ BlockReason: FText                  (shown to player)
  ├─ Priority: Int32                     (higher = overrides lower priority rules)
  └─ bOverrideFramework: Boolean         (true = replaces framework rule for this action)

Example Entry: Block Fire in Void Space

ActionTag:     Framework.Action.Fire
BlockedStates: [State.InVoidSpace, State.AltDeathSpace]
BlockReason:   "Your weapon has no power here."
Priority:      100
OverrideFramework: false (ADD to framework blocks, not REPLACE)

Example Entry: ALLOW Interact During Hiding (Override)

ActionTag:     Framework.Action.OpenWatch
BlockedStates: []  (empty = no blocks = ALWAYS permitted)
BlockReason:   ""
Priority:      200 (HIGHER than framework default)
OverrideFramework: true (REPLACE framework rule — framework blocks OpenWatch during Hiding)

Runtime State Management (BPC_StateManager Integration)

Force Push States (Scripted Moments)

States that are force-pushed by game systems:

  BPC_CutsceneBridge → ForcePushState(InCutscene)
    └─ Blocks: All actions except SkipCutscene
    
  BPC_DeathHandlingSystem → ForcePushState(Dead)
    └─ Blocks: All actions
    
  BPC_VoidShiftSystem → ForcePushState(VoidShiftActive)
    └─ Blocks: Fire, Reload, Melee, Interact(50%)
    
  BPC_DialogueChoiceSystem → ForcePushState(InDialogueChoice)
    └─ Blocks: All actions except dialogue input
    
  BPC_StressSystem (at Catatonic) → ForcePushState(Catatonic)
    └─ Blocks: Fire, Sprint, Hide

Overlay States (Simultaneous)

States that layer on top of base state:

  BPC_HidingSystem → SetOverlayState(Hiding)
    └─ Blocks: Fire, Reload, Sprint, Jump
    └─ Allows: Look, Interact (exit hide), Crouch
    
  BPC_EquipmentSlotSystem → SetOverlayState(Aiming)
    └─ Blocks: Sprint, Jump
    └─ Allows: Fire (with ADS bonus), Reload, Crouch
    
  BPC_StaminaSystem → SetOverlayState(Exhausted)
    └─ Blocks: Sprint, Jump
    └─ Allows: Move (walk only), Interact, Fire

Vital Signals (BPC_StateManager tracks)

BPC_StateManager.UpdateVitalSignals() is called every 0.5s:

  E_PlayerVitalSignals:
    ├─ Normal    → Health > 50 AND Stress < 50 AND Stamina > 30
    ├─ Wounded   → Health < 50
    ├─ Stressed  → Stress > 50
    ├─ Exhausted → Stamina < 20
    └─ Critical  → Health < 25 OR Stress > 90

Systems read vital signals to modify behavior:
  ├─ WBP_DiegeticHUDFrame → changes health bar color per signal
  ├─ SS_AudioManager → modifies heartbeat audio parameter
  ├─ BPC_CameraStateLayer → adjusts FOV and blur per signal
  └─ BPC_MemoryDriftSystem → increases hallucination intensity

GASP Liaison (Movement ↔ State)

Movement State → Action State Mapping

BPC_MovementStateSystem reports movement mode to BPC_StateManager:

  MovingMode.Walking   → State.Walking
  MovingMode.Sprinting → State.Sprinting
  MovingMode.Crouching → State.Crouching
  MovingMode.Falling   → State.Falling (no jump/equip actions)
  MovingMode.Swimming  → State.Swimming (if water areas added)
  MovingMode.Ladder    → State.Climbing (no fire/equip actions)

BPC_StateManager enforces:
  ├─ Can't Sprint → if State.Is(Exhausted) OR State.Is(Catatonic)
  ├─ Can't Crouch → if State.Is(Sprinting)
  └─ Can't Jump   → if State.Is(Crouching) OR State.Is(Exhausted)

Debugging State Gating

In WBP_DebugMenu → State Viewer tab:

Display:
  ├─ Current Action State: "Walking"
  ├─ Current Overlay States: ["Hiding"]
  ├─ Vital Signal: "Wounded"
  ├─ Force Stack Depth: 2
  │    ├─ [0] InCutscene (pushed by BPC_CutsceneBridge)
  │    └─ [1] Dead (pushed by BPC_DeathHandlingSystem)
  │
  ├─ Action Test:
  │    ├─ [Fire]        → BLOCKED: "Cannot Fire — you are in Hiding"
  │    ├─ [Interact]    → BLOCKED: "Cannot Interact — cutscene playing"
  │    └─ [Look]        → PERMITTED
  │
  └─ Gating Table Source: DA_StateGatingTable_Horror (Game/DataAssets/)

Blueprint Wiring Checklist

  • Duplicate DA_StateGatingTableDA_StateGatingTable_Horror in Game/DataAssets/
  • Add all 15+ game-specific gating rules
  • Configure BP_HorrorPlayerCharacter → BPC_StateManager → set GatingTable = DA_StateGatingTable_Horror
  • Wire all force-push states (cutscene, death, void shift, dialogue choice, catatonic)
  • Wire all overlay states (hiding, aiming, exhausted)
  • Wire GASP liaison: MovementState → BPC_StateManager movement update
  • Test every blocked action shows correct BlockReason in HUD
  • Verify WBP_InteractionPromptDisplay reads OnActionDenied dispatcher

Notes for Expansion

  • New states can be added by creating a new GameplayTag in DT_Tags_State.csv
  • Designers can add gating rules to DA_StateGatingTable_Horror without touching any Blueprint
  • Priority system allows game rules to override framework rules cleanly
  • Consider adding "semi-permitted" actions: permitted but with penalty (e.g., flashlight dims when exhausted)
  • Add per-state camera layers: each state automatically configures FOV, offset, blur
  • Multiplayer: state gating is server-authoritative; client requests are validated server-side

State Gating Examples for Project Void. See GAMEINDEX.md for full game structure. See bpc-statemanager.md for full State Manager architecture. See 130_BPC_StateManager.md for State Manager spec.