Files
UE5-Modular-Game-Framework/docs/game/core-controller-state.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

13 KiB
Raw Permalink Blame History

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 for full game structure. See 05_GM_CoreGameMode.md and 06_GS_CoreGameState.md for parent specs.