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:
Lefteris Notas
2026-05-21 22:27:57 +03:00
parent c515920eea
commit 040db37720
17 changed files with 6795 additions and 43 deletions

View 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 0100; fires OnSanityChanged dispatcher |
| `IncrementDeaths` | — | — | DeathsThisChapter++, fires OnDeathCountChanged |
| `GetPlaystyle` | — | GameplayTag | Returns PlaystyleTag |
| `GetSanityPercentage` | — | Float | Returns SanityTier as 0.01.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.01.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.01.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.*