# 63 — BPC_FearSystem ## Blueprint Spec — UE 5.5–5.7 --- ### Parent Class `ActorComponent` ### Dependencies - [`GI_GameFramework`](../01-core/04_GI_GameFramework.md) — Central game instance access - [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) — Player anxiety/stress metrics - [`BPC_DifficultyManager`](89_BPC_DifficultyManager.md) — Fear intensity modifier - [`BPC_StressSystem`](../02-player/10_BPC_StressSystem.md) — Player stress level - [`BPC_AtmosphereController`](64_BPC_AtmosphereController.md) — Atmosphere response - [`BPC_AudioManager`](66_BPC_AudioManager.md) — Audio feedback - [`BPC_VFXManager`](67_BPC_VFXManager.md) — Visual feedback - [`BPC_LightingManager`](65_BPC_LightingManager.md) — Lighting response - [`BPC_NarrativeStateSystem`](../07-narrative/38_BPC_NarrativeStateSystem.md) — Story-aware fear triggers ### Purpose Core fear and anxiety system that manages the player's fear level, fear sources, fear decay, and fear-induced gameplay effects. Acts as the central orchestrator for all horror-related feedback loops — audio, visual, AI behavior, and UI — driven by the player's current fear state and environmental context. ### Variables | Name | Type | Description | |------|------|-------------| | `CurrentFearLevel` | Float (0–100) | Current fear value | | `MaxFearLevel` | Float | Cap for fear (default 100) | | `FearDecayRate` | Float | Passive fear reduction per second | | `FearThresholds` | TMap\ | Threshold values for each fear tier | | `ActiveFearSources` | TArray\ | Currently contributing fear sources | | `FearMultiplier` | Float | Global multiplier (from DifficultyManager) | | `bIsInPanicState` | Bool | Overwhelmed by fear | | `PanicDuration` | Float | Seconds of panic state | | `PanicTimer` | Float | Panic countdown | | `LastIncreaseTime` | Float | When fear last increased | | `bFearDecayPaused` | Bool | Freeze decay | | `EnvironmentalFearModifier` | Float | Ambient fear from atmosphere | | `DarknessFearMultiplier` | Float | Extra fear in dark areas | | `IsolatedFearMultiplier` | Float | Extra fear when alone | | `ProximityFearMultiplier` | Float | Extra fear from nearby threats | | `bIsInSafeZone` | Bool | Safe zone overrides fear | ### Enums | Enum | Values | Description | |------|--------|-------------| | `EFearThreshold` | Calm, Uneasy, Nervous, Afraid, Terrified, Panic | Fear tiers | ### Structs | Struct | Fields | Description | |--------|--------|-------------| | `FFearSource` | SourceName: FName, BaseValue: Float, CurrentValue: Float, DecayDelay: Float, bIsDecaying: Bool, TimeSinceTrigger: Float, Tag: FGameplayTag | Active fear contributor | | `FFearEvent` | Source: FName, Value: Float, Duration: Float, bInstant: Bool, bStack: Bool, AssociatedTag: FGameplayTag | Incoming fear impulse | ### Functions | Name | Inputs | Outputs | Description | |------|--------|---------|-------------| | `Initialize` | — | — | Setup thresholds, bind events | | `AddFear` | Event: FFearEvent | — | Add fear from any source | | `RemoveFearSource` | SourceName: FName | — | Remove specific fear source | | `ClearAllFear` | — | — | Reset fear to baseline | | `GetFearLevel` | — | Float | Current fear value | | `GetFearThreshold` | — | EFearThreshold | Current fear tier | | `IsInPanic` | — | Bool | Panic state check | | `SetFearDecayRate` | NewRate: Float | — | Override decay speed | | `PauseFearDecay` | bPaused: Bool | — | Freeze/unfreeze decay | | `UpdateEnvironmentalFear` | Modifier: Float | — | Ambient fear contribution | | `CalculateFearTier` | FearValue: Float | EFearThreshold | Determine current tier | | `TriggerPanic` | Duration: Float | — | Force panic state | | `ResolvePanic` | — | — | End panic state early | | `ApplyFearEffect` | Effect: EFearEffect | — | Gameplay consequences of fear | ### Event Dispatchers | Name | Parameters | Fired When | |------|-----------|-----------| | `OnFearLevelChanged` | NewFear: Float, Threshold: EFearThreshold | Any fear change | | `OnFearThresholdReached` | Threshold: EFearThreshold | Cross a fear tier boundary | | `OnPanicStarted` | — | Panic state entered | | `OnPanicEnded` | — | Panic state ended | | `OnFearSourceAdded` | Source: FFearSource | New fear source registered | | `OnFearSourceRemoved` | SourceName: FName | Fear source expired | ### Blueprint Flow ``` [Tick — every frame] └─► If not bFearDecayPaused AND not bIsInPanicState: CurrentFearLevel -= FearDecayRate * DeltaTime Clamp CurrentFearLevel to 0..MaxFearLevel └─► Process active fear sources: For each FFearSource in ActiveFearSources: Source.TimeSinceTrigger += DeltaTime If Source.TimeSinceTrigger > Source.DecayDelay: Source.bIsDecaying = true Source.CurrentValue -= DecayRate * DeltaTime If Source.CurrentValue <= 0: Remove from ActiveFearSources Fire OnFearSourceRemoved └─► If bIsInPanicState: PanicTimer -= DeltaTime If PanicTimer <= 0: ResolvePanic() └─► CalculateFearTier(CurrentFearLevel) └─► If tier changed since last frame: Fire OnFearThresholdReached(NewThreshold) [AddFear] └─► Apply modifiers: EffectiveValue = Event.Value * FearMultiplier EffectiveValue *= EnvironmentalFearModifier EffectiveValue *= DarknessFearModifier (if in dark volume) EffectiveValue *= IsolatedFearModifier (if no allies) EffectiveValue *= ProximityFearModifier (if enemies nearby) └─► If Event.bStack: Find existing source by Event.Source If found: Stack.Value += EffectiveValue Else: Create new FFearSource └─► Else: Create new FFearSource with Event parameters └─► CurrentFearLevel += EffectiveValue └─► Clamp to MaxFearLevel └─► Check if panic threshold crossed: If CurrentFearLevel >= FearThresholds[Panic]: TriggerPanic(PanicDuration) └─► Fire OnFearLevelChanged(CurrentFearLevel, CurrentThreshold) └─► Fire OnFearSourceAdded(NewSource) [TriggerPanic] └─► bIsInPanicState = true └─► PanicTimer = Duration (or PanicDuration default) └─► ApplyFearEffect(EPanicEffects) └─► BPC_AtmosphereController.TriggerPanicMode() └─► BPC_AudioManager.PlayPanicAudio() └─► BPC_VFXManager.TriggerPanicVFX() └─► UI: Show panic overlay └─► Fire OnPanicStarted [ResolvePanic] └─► bIsInPanicState = false └─► CurrentFearLevel = FearThresholds[Terrified] * 0.8 └─► BPC_AtmosphereController.EndPanicMode() └─► BPC_AudioManager.StopPanicAudio() └─► Fire OnPanicEnded [ApplyFearEffect — based on current threshold] └─► EFearThreshold.Calm: No effects └─► EFearThreshold.Uneasy: Subtle audio cues, slight camera sway └─► EFearThreshold.Nervous: UI vignette, breathing sounds, reduced stamina regen └─► EFearThreshold.Afraid: Visibility distortion, movement speed penalty, aim shake └─► EFearThreshold.Terrified: Severe vignette, stammering audio, weapon sway └─► EFearThreshold.Panic: Tunnel vision, audio distortion, sprint penalty, AI gets buffs ``` ### Communications With | Target | Method | Why | |--------|--------|-----| | [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) | Get Owner Component | Track fear history for metrics | | [`BPC_StressSystem`](../02-player/10_BPC_StressSystem.md) | Get Owner Component | Stress/fear feedback loop | | [`BPC_DifficultyManager`](89_BPC_DifficultyManager.md) | Get Owner Component | Fear intensity modifier | | [`BPC_AtmosphereController`](64_BPC_AtmosphereController.md) | Direct call | Atmosphere panic mode | | [`BPC_AudioManager`](66_BPC_AudioManager.md) | Direct call | Panic audio, fear ambience | | [`BPC_VFXManager`](67_BPC_VFXManager.md) | Direct call | Visual effects per tier | | [`BPC_LightingManager`](65_BPC_LightingManager.md) | Direct call | Dynamic lighting response | | [`SS_UIManager`](../06-ui/32_SS_UIManager.md) | Subsystem | HUD fear indicator, panic overlay | | [`BPC_NarrativeStateSystem`](../07-narrative/38_BPC_NarrativeStateSystem.md) | Get Owner Component | Story-aware fear modifiers | | [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) | Get Owner Component | Panic damage if health low | | [`AI_EnemyControllers`](../09-ai/55_BPC_AIControllerBase.md) | Event Dispatcher | AI aggression rise with player fear | ### Reuse Notes - Single instance on player character (or PlayerController) - All fear sources are stackable and independently decayable - Thresholds are designer-configurable at runtime - Fear multiplier from DifficultyManager allows difficulty to scale horror - Safe zones (checkpoints, safe rooms) pause fear accumulation and decay - Panic state is a temporary debuff with full cleanup on resolve - UI reads OnFearLevelChanged dispatcher, never polls