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.
This commit is contained in:
308
docs/game/core-controller-state.md
Normal file
308
docs/game/core-controller-state.md
Normal file
@@ -0,0 +1,308 @@
|
||||
# Game Core — PC_HorrorController, PS_HorrorPlayerState, GS_HorrorGameState
|
||||
|
||||
**Game:** Project Void | **Build Phase:** 1
|
||||
|
||||
---
|
||||
|
||||
This document covers the 3 remaining Core class children:
|
||||
|
||||
| Asset | Parent | Purpose |
|
||||
|-------|--------|---------|
|
||||
| `PC_HorrorController` | `PC_CoreController` (or `PlayerController`) | Horror-specific input routing, camera, UI injection |
|
||||
| `PS_HorrorPlayerState` | `PS_CorePlayerState` (or `PlayerState`) | Horror player data: fear history, deaths, sanity |
|
||||
| `GS_HorrorGameState` | `GS_CoreGameState` (or `GameStateBase`) | Shared session data: global flags, void state, timer |
|
||||
|
||||
---
|
||||
|
||||
## PC_HorrorController — Player Controller
|
||||
|
||||
**Asset Path:** `Content/Game/Core/PC_HorrorController.uasset`
|
||||
|
||||
### Purpose
|
||||
|
||||
Routes player input through `SS_EnhancedInputManager`, manages camera shake, hit feedback, and UI injection for horror-specific screen effects.
|
||||
|
||||
### Creation Steps
|
||||
|
||||
#### Step 1 — Create Blueprint
|
||||
|
||||
```
|
||||
Content Browser → Game/Core/
|
||||
Right-click → Blueprint Class
|
||||
Parent Class: PlayerController (or PC_CoreController if it exists in framework)
|
||||
Name: PC_HorrorController
|
||||
```
|
||||
|
||||
#### Step 2 — Variables
|
||||
|
||||
| Variable | Type | Default | Category | Purpose |
|
||||
|----------|------|---------|----------|---------|
|
||||
| `bGameInputEnabled` | Boolean | `true` | `Input` | Master input toggle (off during cutscenes/death) |
|
||||
| `CameraShakeIntensity` | Float | `1.0` | `Camera` | Global scalar for camera shake effects |
|
||||
| `bHeartbeatEnabled` | Boolean | `true` | `UI` | Toggle diegetic heartbeat indicator |
|
||||
|
||||
#### Step 3 — Wire Event BeginPlay
|
||||
|
||||
```
|
||||
Event BeginPlay
|
||||
│
|
||||
├─ Set Input Mode Game Only (mouse captured, no cursor)
|
||||
├─ Set Show Mouse Cursor → false
|
||||
│
|
||||
├─ [Get Enhanced Input Subsystem]
|
||||
│ └─ Get Engine Subsystem → UEnhancedInputLocalPlayerSubsystem
|
||||
│
|
||||
├─ [Bind to Game Phase Changes]
|
||||
│ ├─ Get GI_HorrorGame → Bind to OnGamePhaseChanged
|
||||
│ │ └─ On Paused/Cutscene/DeathLoop → Set bGameInputEnabled = false
|
||||
│ │ └─ On InGame → Set bGameInputEnabled = true
|
||||
│ │
|
||||
│ └─ SS_UIManager → Bind to OnInputModeChanged
|
||||
│ └─ Update input mode + cursor visibility
|
||||
│
|
||||
└─ [Start Heartbeat Effect]
|
||||
└─ (Timer: every 0.5s) Get BPC_StateManager → GetHeartRate()
|
||||
├─ Normal (60-80) → slight controller pulse
|
||||
├─ Elevated (80-110) → stronger pulse
|
||||
└─ Critical (110+) → rapid, intense pulse + screen edge red
|
||||
```
|
||||
|
||||
#### Step 4 — Override: Setup Input Component
|
||||
|
||||
```
|
||||
Setup Input Component
|
||||
│
|
||||
├─ Parent: Setup Input Component
|
||||
│
|
||||
└─ (Input actions are mapped via SS_EnhancedInputManager and IMC_ contexts
|
||||
— no manual binding needed here. The subsystem handles context pushes.)
|
||||
```
|
||||
|
||||
#### Step 5 — Functions
|
||||
|
||||
| Function | Inputs | Outputs | Description |
|
||||
|----------|--------|---------|-------------|
|
||||
| `PlayCameraShake` | ShakeClass, Scale: Float | — | `ClientStartCameraShake(ShakeClass, Scale × CameraShakeIntensity)` |
|
||||
| `SetGameInputEnabled` | bEnabled: Boolean | — | Master toggle — disables all input processing |
|
||||
| `OpenPauseMenu` | — | — | `SS_UIManager.PushMenu(PauseMenu)` — bound to IA_PauseMenu |
|
||||
| `GetInteractionSystem` | — | `BPC_InteractionDetector*` | Quick access to interaction component on pawn |
|
||||
|
||||
### Communications With
|
||||
|
||||
| Target | Method | Why |
|
||||
|--------|--------|-----|
|
||||
| `SS_EnhancedInputManager` | Direct | Context management, input state queries |
|
||||
| `SS_UIManager` | Direct + Dispatcher | Input mode coordination |
|
||||
| `GI_HorrorGame` | Dispatcher | Phase change response |
|
||||
| `BPC_StateManager` | Direct (on pawn) | Heart rate for haptic feedback |
|
||||
| `BP_HorrorPlayerCharacter` | Owned Pawn | Camera shake routing |
|
||||
|
||||
---
|
||||
|
||||
## PS_HorrorPlayerState — Player State
|
||||
|
||||
**Asset Path:** `Content/Game/Core/PS_HorrorPlayerState.uasset`
|
||||
|
||||
### Purpose
|
||||
|
||||
Tracks player-specific data that persists across level transitions and death/respawn. Custom data: fear history, death count per chapter, sanity tier.
|
||||
|
||||
### Creation Steps
|
||||
|
||||
#### Step 1 — Create Blueprint
|
||||
|
||||
```
|
||||
Content Browser → Game/Core/
|
||||
Right-click → Blueprint Class
|
||||
Parent Class: PlayerState (or PS_CorePlayerState if it exists in framework)
|
||||
Name: PS_HorrorPlayerState
|
||||
```
|
||||
|
||||
#### Step 2 — Variables
|
||||
|
||||
| Variable | Type | Default | Category | Purpose |
|
||||
|----------|------|---------|----------|---------|
|
||||
| `SanityTier` | Integer | `100` | `Player` | 100=Calm, 75=Uneasy, 50=Disturbed, 25=Breaking, 0=Catatonic |
|
||||
| `FearHistory` | Array\<GameplayTag\> | Empty | `Player` | Tracks fear triggers experienced (for ending calculation) |
|
||||
| `DeathsThisChapter` | Integer | `0` | `Player` | Resets per chapter; used for difficulty scaling |
|
||||
| `TotalCollectiblesFound` | Integer | `0` | `Player` | Across all levels |
|
||||
| `PlaystyleTag` | GameplayTag | `Framework.Playstyle.Balanced` | `Player` | Aggressive / Stealthy / Explorer / Balanced |
|
||||
| `PlayerName` | Text | "Dr. Eliza Vance" | `Player` | Display name (set by GM on spawn) |
|
||||
|
||||
#### Step 3 — Functions
|
||||
|
||||
| Function | Inputs | Outputs | Description |
|
||||
|----------|--------|---------|-------------|
|
||||
| `RecordFearTrigger` | TriggerTag: GameplayTag | — | Adds tag to FearHistory, notifies BPC_EndingAccumulator |
|
||||
| `SetSanityTier` | NewTier: Int | — | Updates sanity; clamps 0–100; fires OnSanityChanged dispatcher |
|
||||
| `IncrementDeaths` | — | — | DeathsThisChapter++, fires OnDeathCountChanged |
|
||||
| `GetPlaystyle` | — | GameplayTag | Returns PlaystyleTag |
|
||||
| `GetSanityPercentage` | — | Float | Returns SanityTier as 0.0–1.0 float |
|
||||
|
||||
### Replication Notes (Multiplayer)
|
||||
|
||||
All variables should be marked `Replicated` with `ReplicatedUsing = OnRep_`.
|
||||
|
||||
---
|
||||
|
||||
## GS_HorrorGameState — Game State
|
||||
|
||||
**Asset Path:** `Content/Game/Core/GS_HorrorGameState.uasset`
|
||||
|
||||
### Purpose
|
||||
|
||||
Shared session state visible to all players (server + all clients in multiplayer). In single-player, serves as the authoritative session data store.
|
||||
|
||||
### Creation Steps
|
||||
|
||||
#### Step 1 — Create Blueprint
|
||||
|
||||
```
|
||||
Content Browser → Game/Core/
|
||||
Right-click → Blueprint Class
|
||||
Parent Class: GameStateBase (or GS_CoreGameState if it exists in framework)
|
||||
Name: GS_HorrorGameState
|
||||
```
|
||||
|
||||
#### Step 2 — Variables
|
||||
|
||||
| Variable | Type | Default | Category | Purpose |
|
||||
|----------|------|---------|----------|---------|
|
||||
| `ActiveChapterTag` | GameplayTag | — | `Session` | Current chapter/level identifier |
|
||||
| `bIsVoidActive` | Boolean | `false` | `Session` | True when any player is in void space |
|
||||
| `GlobalFearLevel` | Float | `0.0` | `Session` | 0.0–1.0 — ambient fear level affecting all systems |
|
||||
| `SessionPlaytime` | Float | `0.0` | `Session` | Accumulated playtime in seconds |
|
||||
| `bEndingSequenceActive` | Boolean | `false` | `Session` | True during ending cutscene (blocks all gameplay) |
|
||||
| `GlobalFlags` | Map\<GameplayTag, Boolean\> | Empty | `Session` | Chapter-complete flags, puzzle-solved flags, etc. |
|
||||
|
||||
#### Step 3 — Event Graph
|
||||
|
||||
```
|
||||
Event BeginPlay
|
||||
│
|
||||
├─ Set GlobalFearLevel = 0.0
|
||||
│
|
||||
└─ [Start Playtime Timer]
|
||||
└─ Set Timer (1.0s, Looping) → SessionPlaytime += 1.0
|
||||
└─ Only increment when GamePhase == InGame
|
||||
|
||||
Event Tick (or Timer)
|
||||
│
|
||||
├─ Get GI_HorrorGame → CurrentGamePhase
|
||||
│ └─ If InGame: SessionPlaytime += DeltaTime
|
||||
│ └─ Else: don't accumulate
|
||||
│
|
||||
└─ [Fear Decay]
|
||||
├─ GlobalFearLevel > 0.0?
|
||||
│ └─ True: GlobalFearLevel -= 0.001 per second (slow decay)
|
||||
│ └─ Clamp to 0.0 minimum
|
||||
└─ Broadcast OnGlobalFearChanged(GlobalFearLevel)
|
||||
```
|
||||
|
||||
#### Step 4 — Functions
|
||||
|
||||
| Function | Inputs | Outputs | Description |
|
||||
|----------|--------|---------|-------------|
|
||||
| `SetGlobalFlag` | FlagTag: GameplayTag, Value: Boolean | — | Sets session flag + broadcasts OnFlagChanged |
|
||||
| `GetGlobalFlag` | FlagTag: GameplayTag | Boolean | Returns flag value (false if not found) |
|
||||
| `AddFearLevel` | Amount: Float | — | GlobalFearLevel += Amount, clamped 0.0–1.0 |
|
||||
| `SetVoidActive` | bActive: Boolean | — | Sets bIsVoidActive, broadcasts OnVoidStateChanged |
|
||||
| `GetSessionTimeFormatted` | — | Text | Returns "HH:MM:SS" formatted playtime |
|
||||
| `ResetSession` | — | — | Resets all variables (called by New Game) |
|
||||
|
||||
#### Step 5 — Event Dispatchers
|
||||
|
||||
| Dispatcher | Parameters | Fired When |
|
||||
|------------|-----------|------------|
|
||||
| `OnFlagChanged` | FlagTag: GameplayTag, Value: Boolean | Any global flag changes |
|
||||
| `OnGlobalFearChanged` | FearLevel: Float | GlobalFearLevel updates |
|
||||
| `OnVoidStateChanged` | bIsVoidActive: Boolean | Void space active/inactive |
|
||||
| `OnChapterChanged` | ChapterTag: GameplayTag | Active chapter changes |
|
||||
| `OnSessionReset` | — | Session data wiped (New Game) |
|
||||
|
||||
---
|
||||
|
||||
## Combined Wiring — All Core Classes Together
|
||||
|
||||
```
|
||||
[GI_HorrorGame.Init]
|
||||
│
|
||||
├─ Initialize subsystems (Audio, Settings, Input)
|
||||
└─ OpenLevel → L_SplashScreen
|
||||
│
|
||||
└─ L_SplashScreen → auto-advance → L_MainMenu
|
||||
│
|
||||
└─ [Player clicks New Game]
|
||||
│
|
||||
└─ GM_HorrorGameMode starts new session
|
||||
│
|
||||
├─ Spawn PS_HorrorPlayerState (fresh data)
|
||||
├─ Spawn GS_HorrorGameState (fresh session)
|
||||
│
|
||||
├─ Spawn BP_HorrorPlayerCharacter (pawn)
|
||||
│ └─ Auto-added components:
|
||||
│ ├─ BPC_HealthSystem (100 HP)
|
||||
│ ├─ BPC_StaminaSystem (100 stam)
|
||||
│ ├─ BPC_StressSystem (0 stress)
|
||||
│ ├─ BPC_MovementStateSystem
|
||||
│ ├─ BPC_HidingSystem
|
||||
│ ├─ BPC_EmbodimentSystem
|
||||
│ ├─ BPC_CameraStateLayer
|
||||
│ ├─ BPC_PlayerMetricsTracker
|
||||
│ ├─ BPC_InteractionDetector
|
||||
│ ├─ BPC_InventorySystem
|
||||
│ ├─ BPC_EquipmentSlotSystem
|
||||
│ ├─ BPC_ActiveItemSystem
|
||||
│ ├─ BPC_ConsumableSystem
|
||||
│ ├─ BPC_StateManager
|
||||
│ └─ [others as needed]
|
||||
│
|
||||
├─ Spawn PC_HorrorController
|
||||
│ ├─ Bind input contexts
|
||||
│ └─ Set Input Mode Game Only
|
||||
│
|
||||
└─ Create WBP_GameHUDController
|
||||
├─ WBP_DiegeticHUDFrame (health, stress, stamina)
|
||||
├─ WBP_InteractionPromptDisplay
|
||||
├─ WBP_ObjectiveDisplay
|
||||
├─ WBP_NotificationToast
|
||||
├─ WBP_ScreenEffectController
|
||||
└─ WBP_AccessibilityUI (subtitles)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Blueprint Wiring Checklist
|
||||
|
||||
### PC_HorrorController
|
||||
- [ ] Create BP child of PlayerController named `PC_HorrorController`
|
||||
- [ ] Add 3 variables (bGameInputEnabled, CameraShakeIntensity, bHeartbeatEnabled)
|
||||
- [ ] Wire `Event BeginPlay` — input mode, phase bindings, heartbeat timer
|
||||
- [ ] Add `PlayCameraShake`, `SetGameInputEnabled`, `OpenPauseMenu`, `GetInteractionSystem`
|
||||
|
||||
### PS_HorrorPlayerState
|
||||
- [ ] Create BP child of PlayerState named `PS_HorrorPlayerState`
|
||||
- [ ] Add 5 variables (SanityTier, FearHistory, DeathsThisChapter, TotalCollectiblesFound, PlaystyleTag)
|
||||
- [ ] Add `RecordFearTrigger`, `SetSanityTier`, `IncrementDeaths`, `GetPlaystyle`, `GetSanityPercentage`
|
||||
- [ ] Mark variables Replicated for multiplayer
|
||||
|
||||
### GS_HorrorGameState
|
||||
- [ ] Create BP child of GameStateBase named `GS_HorrorGameState`
|
||||
- [ ] Add 6 variables (ActiveChapterTag, bIsVoidActive, GlobalFearLevel, SessionPlaytime, bEndingSequenceActive, GlobalFlags)
|
||||
- [ ] Add 4 event dispatchers (OnFlagChanged, OnGlobalFearChanged, OnVoidStateChanged, OnChapterChanged, OnSessionReset)
|
||||
- [ ] Wire `Event BeginPlay` — fear decay timer
|
||||
- [ ] Add `SetGlobalFlag`, `GetGlobalFlag`, `AddFearLevel`, `SetVoidActive`, `GetSessionTimeFormatted`, `ResetSession`
|
||||
|
||||
---
|
||||
|
||||
## Notes for Expansion
|
||||
|
||||
- The `PS_HorrorPlayerState.SanityTier` maps directly to `BPC_StressSystem` — they should sync via dispatcher
|
||||
- `GS_HorrorGameState.GlobalFearLevel` could drive `BPC_PacingDirector` to spawn more/less enemies
|
||||
- In a multiplayer game, `GS_HorrorGameState` is the server-authoritative source for all session data
|
||||
- Consider adding `PS_HorrorPlayerState.FearHistory` as a debug visualization in `WBP_DebugMenu`
|
||||
- The heartbeat haptic effect in `PC_HorrorController` requires gamepad support — add a fallback for KB+M
|
||||
|
||||
---
|
||||
|
||||
*Core controller + state classes for Project Void. See [GAMEINDEX.md](GAMEINDEX.md) for full game structure. See [05_GM_CoreGameMode.md](../blueprints/01-core/05_GM_CoreGameMode.md) and [06_GS_CoreGameState.md](../blueprints/01-core/06_GS_CoreGameState.md) for parent specs.*
|
||||
Reference in New Issue
Block a user