- 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.
288 lines
11 KiB
Markdown
288 lines
11 KiB
Markdown
# 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_StateGatingTable` → `DA_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](GAMEINDEX.md) for full game structure. See [bpc-statemanager.md](../architecture/bpc-statemanager.md) for full State Manager architecture. See [130_BPC_StateManager.md](../blueprints/16-state/130_BPC_StateManager.md) for State Manager spec.*
|