- 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.
16 KiB
Atmosphere & Audio — Horror Environment Systems
Game: Project Void | Build Phases: 14, 16, 17, 18 Framework Systems: 89-101 (adaptive) + 132-135 (MetaSounds audio), 96_BPC_LightEventController, 97_BPC_MemoryDriftSystem, 98_BPC_PacingDirector, 101_BPC_ScareEventSystem
Purpose
Defines every atmosphere profile, scare event, light event, room audio zone, and adaptive environment system used to create the horror experience. This is where the game's "feel" comes from.
Atmosphere Profiles (DA_AtmosphereProfile)
Each area has a Data Asset that defines its default audio, lighting, fog, and post-process settings:
| Profile | Area | Tension | Lighting | Audio Bus | Fog |
|---|---|---|---|---|---|
DA_Atmosphere_WardA_Standard |
WardA | 0.3 | Dim overheads, cool blue | WardA reverb | Light volumetric |
DA_Atmosphere_WardB_Dark |
WardB | 0.6 | Flickering, warm amber | WardB echo | Medium volumetric |
DA_Atmosphere_Basement_Dark |
Basement | 0.9 | NONE (player-provided) | Heavy reverb, drips | Heavy fog |
DA_Atmosphere_VoidSpace |
Void | 1.0 | Inverted (dark fog, white shadows) | Reversed whispers | Black fog |
DA_Atmosphere_WardensOffice |
WardensOffice | 0.7 | Single desk lamp, moonlight | Quiet, ticking clock | None |
DA_Atmosphere_SafeRoom |
Safe Rooms | 0.0 | Warm, steady lamp light | Soft hum, safe | None |
Profile Properties
DA_AtmosphereProfile Structure:
├─ ProfileTag (GameplayTag)
├─ TensionLevel (Float 0.0-1.0)
├─ LightingSettings (struct)
│ ├─ bOverrideLights (Bool)
│ ├─ LightColorTint (LinearColor)
│ ├─ LightIntensityMultiplier (Float)
│ └─ bEnableFlicker (Bool)
├─ FogSettings (struct)
│ ├─ FogDensity (Float)
│ ├─ FogColor (LinearColor)
│ └─ bVolumetricFogEnabled (Bool)
├─ PostProcessSettings
│ ├─ ColorGradingIntensity (Float)
│ ├─ Saturation (Float 0.0-2.0)
│ ├─ Contrast (Float 0.0-2.0)
│ └─ VignetteIntensity (Float)
├─ AudioSettings
│ ├─ RoomAcousticPreset (DA_RoomAcousticPreset*)
│ ├─ AmbientLoop (SoundBase*)
│ ├─ MusicTrack (SoundBase*)
│ └─ BusVolumeOverrides (Map<BusTag, Float>)
└─ ScareEventPool (Array<DA_ScareEvent*>)
Audio Architecture (MetaSounds)
Mix Bus Hierarchy
┌─────────────┐
│ MS_MasterBus │
└──────┬──────┘
┌─────────┬───────┼───────┬─────────┐
▼ ▼ ▼ ▼ ▼
┌────────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌────────┐
│MS_SFXBus│ │MS_Amb│ │MS_Mus│ │MS_Dia│ │(Future)│
│ │ │Bus │ │Bus │ │Bus │ │ │
└────────┘ └──────┘ └──────┘ └──────┘ └────────┘
SFX Ambience Music Dialogue
Bus Configuration (DA_AudioSettings_Horror)
| Bus | Default Volume | Ducking Target | Ducking Amount | Purpose |
|---|---|---|---|---|
MS_SFXBus |
1.0 | MS_DialogueBus | -6dB | Gunshots, footsteps, scares, UI |
MS_AmbientBus |
0.8 | MS_DialogueBus | -3dB | Wind, creaks, drips, whispers |
MS_MusicBus |
0.7 | MS_DialogueBus | -8dB | Tension drones, combat music, theme |
MS_DialogueBus |
1.0 | None | — | VO, subtitles, entity speech |
Gameplay Parameters (Pushed via SS_AudioManager)
SS_AudioManager.SetFloatParameter(ParamName, Value):
"PlayerHealthPercent" → 0.0–1.0 (BPC_HealthSystem)
└─ MS_SFXBus: heartbeat loudness, breathing intensity
"StressTier" → 0–4 (BPC_StressSystem)
└─ MS_AmbientBus: whisper density, drone intensity
└─ MS_MusicBus: tension layer volume
"HeartRate" → 60–180 (BPC_StateManager)
└─ MS_SFXBus: heartbeat speed, pulse intensity
"FearIntensity" → 0.0–1.0 (GI_HorrorGame)
└─ MS_MusicBus: orchestral intensity, dissonance level
"TensionLevel" → 0.0–1.0 (BPC_AtmosphereStateController)
└─ MS_AmbientBus: ambient layer crossfade
└─ MS_MusicBus: music layer selection
"PlayerSpeed" → 0–600 (BPC_MovementStateSystem)
└─ MS_SFXBus: footstep volume and frequency
"IsHiding" → 0/1 (BPC_HidingSystem)
└─ MS_AmbientBus: muffled external sounds
└─ MS_SFXBus: heartbeat + breath prominence increase
"VoidActive" → 0/1 (GS_HorrorGameState)
└─ ALL buses: spectral reverb, reversed samples, pitch shift
Room Audio Zones (BP_RoomAudioZone)
Each zone is a TriggerVolume that switches acoustic preset on overlap:
| Zone | Preset | Location |
|---|---|---|
BP_RoomAudioZone_WardA |
DA_RoomAcoustic_WardA |
All WardA rooms |
BP_RoomAudioZone_WardB |
DA_RoomAcoustic_WardB |
All WardB rooms |
BP_RoomAudioZone_Basement |
DA_RoomAcoustic_Basement |
Basement corridors |
BP_RoomAudioZone_Void |
DA_RoomAcoustic_Void |
Void space |
BP_RoomAudioZone_Courtyard |
DA_RoomAcoustic_Outdoor |
WardB courtyard |
BP_RoomAudioZone_SafeRoom |
DA_RoomAcoustic_SmallRoom |
All safe rooms |
Acoustic Presets
| Preset | Reverb Time | Early Reflections | Occlusion | EQ |
|---|---|---|---|---|
DA_RoomAcoustic_WardA |
1.2s (medium hall) | Moderate | Low | Flat |
DA_RoomAcoustic_WardB |
2.0s (large echo) | Heavy | Medium | Boost 200Hz |
DA_RoomAcoustic_Basement |
3.5s (cathedral) | Heavy wet | High | Cut highs above 4kHz |
DA_RoomAcoustic_Void |
8.0s (infinite) | Spectral | Full | Reverse delay |
DA_RoomAcoustic_Outdoor |
0.3s (open) | None | None | Wind filter |
DA_RoomAcoustic_SmallRoom |
0.5s (office) | Light | Low | Warm boost |
Scare Event System (BPC_ScareEventSystem)
Scare Event Data Assets
| DA_ScareEvent | Type | Trigger | Anticipation | Payoff |
|---|---|---|---|---|
DA_Scare_LockerJumpscare |
Proximity | Player within 200u of locker | 3s (rattling sound) | Locker door BANG open |
DA_Scare_MirrorApparition |
Look-at | Player looks at mirror > 2s | 5s (reflection distorts) | Face appears behind player |
DA_Scare_WindowFace |
Proximity | Player walks past window | 2s (breath fog on glass) | Hand SLAMS from outside |
DA_Scare_VoidWhisper |
Random timer | 5-15 min intervals | None (sudden) | Loud whisper in player's ear |
DA_Scare_CeilingThump |
Proximity | Player in basement corridor | 4s (distant footsteps above) | Loud THUMP directly above |
DA_Scare_BreathingBehind |
Stress trigger | Stress > 70 | 6s (breathing fades in behind) | Nothing there — just audio |
Scare Event Flow
BPC_ScareEventSystem.TriggerScare(DA_ScareEvent)
│
├─ [Cooldown Check]
│ └─ Was a scare triggered in last 15 seconds? → Return (no spam)
│
├─ [Eligibility Check]
│ ├─ Player state allows scare? (Not dead, not cutscene)
│ ├─ Accessibility: "reduce_jumpscares" setting? → use soft variant
│ └─ Difficulty: scale intensity by difficulty scalar
│
├─ [Anticipation Phase] (duration from DA_ScareEvent.AnticipationTime)
│ ├─ Audio: fade in tension sound (creaking, breathing, footsteps)
│ ├─ BPC_StressSystem.AddStress(+5) during anticipation
│ ├─ WBP_ScreenEffectController: subtle vignette darkening
│ └─ (Player is tense — they know something is coming)
│
├─ [Payoff Phase] (instant)
│ ├─ Audio: scare sting (loud sound per scare type)
│ ├─ Visual: screen shake, flash, or particle burst
│ ├─ BPC_StressSystem.AddStress(+15) — spike
│ ├─ SS_AudioManager.PlaySFX(ScareSting)
│ └─ BPC_PlayerMetricsTracker.RecordScare(ScareType)
│
├─ [Recovery Phase] (3-5 seconds)
│ ├─ Audio: fade scare sting, return to ambient
│ ├─ Visual: vignette fades back
│ ├─ BPC_StressSystem.StartDecay() (5 seconds of rapid decay)
│ └─ WBP_HUDController: subtle "heartbeat" indicator pulse
│
└─ Record scare in PS_HorrorPlayerState.FearHistory
Light Events (BPC_LightEventController)
| Light Event | Trigger | Effect | Duration |
|---|---|---|---|
Flicker |
Random (5-15 min intervals) | All lights flicker 3-5 times | 1-2s |
BulbExplosion |
Scripted (basement morgue) | Light bulb bursts → sparks → darkness | Permanent |
EmergencyRed |
Void shift active | All lights tint red, strobe effect | 30s |
ShadowPass |
Random (3-8 min intervals) | Shadow passes across lights (like something walked past) | 0.5s |
TotalBlackout |
Scripted (basement entry) | All lights off. Flashlight-only. | Until generator puzzle solved |
GhostLight |
Rare event | Blue-white orb floats down hallway → vanishes | 5s |
Light Event Flow
BPC_LightEventController.TriggerLightEvent(LightEventTag)
│
├─ [Flicker]
│ ├─ For each PointLight in tagged group:
│ │ └─ Random Delay(0.1-0.4s) → ToggleVisibility × 4 iterations
│ └─ SS_AudioManager.PlaySFX("light_flicker")
│
├─ [BulbExplosion]
│ ├─ Target Light → SetIntensity(0) + Play spark particle
│ ├─ SS_AudioManager.PlaySFX("glass_shatter")
│ └─ Room now darker → update atmosphere profile
│
├─ [TotalBlackout]
│ ├─ All lights → SetIntensity(0) over 1s (smooth dim)
│ ├─ SS_AudioManager.CrossfadeAmbient("basement_dark")
│ └─ BPC_StressSystem.StartContinuousStress(+2/sec, "Darkness")
│
└─ [ShadowPass]
├─ Spawn invisible actor moving across lights
└─ Light shafts briefly occluded
Memory Drift System (BPC_MemoryDriftSystem)
Hallucinations triggered by high stress. Intensity scaled by stress tier:
BPC_MemoryDriftSystem.SetIntensity(Tier: 0-4)
│
├─ Tier 0 (Calm): No effects
│
├─ Tier 1 (Uneasy): Very rare whisper audio cues
│
├─ Tier 2 (Disturbed): Peripheral vision flickers
│ Occasional false sound cues
│ Text in journal shifts subtly
│
├─ Tier 3 (Breaking): Tunnel vision + desaturation
│ False enemy movement (corner of eye)
│ Dialogue lines sometimes echo/repeat
│ Environment "breathes" (wall textures warp)
│
└─ Tier 4 (Catatonic): Near-black peripheral vision
False enemies appear (visual only)
Player name whispered in audio
Doors appear where none exist (can't walk through)
Text unreadable (shifts rapidly)
Pacing Director (BPC_PacingDirector)
Manages the rhythm of horror: exploration → tension → encounter → recovery.
Intensity Bands:
├─ Band 0: RECOVERY (Safe rooms, after encounter ends)
│ └─ Atmosphere: Calm, music: soft, enemies: none
│
├─ Band 1: EXPLORATION (Default, new areas)
│ └─ Atmosphere: Light tension, music: low drone, enemies: patrol only
│
├─ Band 2: TENSION (Near objectives, dark areas)
│ └─ Atmosphere: Moderate tension, music: building, enemies: searching
│
├─ Band 3: ENCOUNTER (Enemy sighted, combat)
│ └─ Atmosphere: High tension, music: combat layer, enemies: hostile
│
└─ Band 4: CLIMAX (Void shift, Shade pursuit, ending)
└─ Atmosphere: Maximum, music: full orchestral, enemies: relentless
Transition Triggers:
├─ Recovery → Exploration: Player leaves safe room
├─ Exploration → Tension: Player enters dark area OR finds key item
├─ Tension → Encounter: Enemy spots player
├─ Encounter → Recovery: Enemy killed/evaded + 10 seconds passed
└─ Recovery → Climax: Entering void space or ending sequence
Adaptive Environment Director (BPC_AdaptiveEnvironmentDirector)
Handles room mutations and dynamic level changes:
TriggerRoomMutation(MutationTag)
│
├─ "VoidShift" → WardB Morgue
│ ├─ Walls: temporary overlay material (bleeding concrete)
│ ├─ Corridors: loop — walking forward returns to same room
│ ├─ Doors: random open/close cycle
│ ├─ Audio: crossfade to void ambience
│ └─ Duration: 30 seconds, then revert
│
├─ "BasementMaze" → Basement
│ ├─ Doors randomize their locked/unlocked state every 60s
│ └─ Player must navigate changing maze
│
└─ "VoidSpaces" → Void level
├─ Rooms rearrange via data layers (swap layout presets)
├─ Triggered on player entering new room
└─ Creates non-Euclidean navigation
Blueprint Wiring Checklist
Atmosphere
- Create all 6
DA_AtmosphereProfileData Assets - Wire
BPC_AtmosphereStateController.LoadProfile()to apply on level load - Add
BP_AtmosphereController_WardAactor to WardA level
Audio
- Create
DA_AudioSettings_Horror— bus volumes, ducking rules - Create all 6
DA_RoomAcousticPresetData Assets - Create
BP_RoomAudioZone_*TriggerVolumes for each area - Wire gameplay parameters: BPC_HealthSystem → "PlayerHealthPercent", etc.
- Set up
SS_AudioManagerwith 4 MetaSound buses
Scares
- Create 6
DA_ScareEventData Assets - Wire
BPC_ScareEventSystem.TriggerScare()with cooldown + eligibility checks - Create
BP_ScareEvent_LockerBangandBP_ScareEvent_Mirroractors
Lights
- Wire
BPC_LightEventControllerwith 6 light event types - Create
BP_LightEvent_Flickeractor for placed flicker points
Memory Drift
- Wire
BPC_MemoryDriftSystem.SetIntensity()to stress tier changes - Add visual effects for each tier (vignette, texture warp, false actors)
Pacing
- Wire
BPC_PacingDirectorwith 5 intensity bands - Add transitions: area entry/exit, enemy detection, safe room entry
Adaptive Environment
- Wire
BPC_AdaptiveEnvironmentDirectorfor void shift + basement maze - Create data layers for swappable room layouts in void space
Notes for Expansion
- Add dynamic music system: adaptive music that layers stems based on tension/pacing band
- Add environmental storytelling through audio: ghostly voices re-enacting past events
- Add weather system: external rain sounds through windows (only in courtyard-facing rooms)
- Add binaural audio (3D sound) support for headphones — whispers sound like they're behind you
- Add haptic profile (DA_HapticProfile) for DualSense: heartbeat pulse, gunshot kick, floor rumble
- Add room mutation presets as
DA_RoomMutationData Assets for designers to configure - Consider performance scaling of audio: fewer simultaneous voices on lower-end hardware
Atmosphere & Audio for Project Void. See GAMEINDEX.md for full game structure. See metasounds-audio-system.md for audio architecture. See sound-catalog.md for full sound trigger list.