Files
UE5-Modular-Game-Framework/docs/game/planar-capture-examples.md
Lefteris Notas 0a2d08b2ad Add Planar Capture System implementation checklist and developer reference
- Created a comprehensive implementation checklist for the Planar Capture System (Systems 136-147) detailing tasks across multiple phases including C++ core, material foundation, Blueprint actors, data assets, integration, and performance testing.
- Added a developer reference document outlining the architecture, data flow, state machine, budget enforcement, render target pooling, horror features, integration points, multiplayer networking, performance characteristics, debugging methods, and build order for the capture systems.
- Introduced examples of capture surface usage in the Project Void horror game, including specific implementations for mirrors, monitors, portals, and fake windows, along with a checklist for integration tasks.
2026-05-22 15:36:08 +03:00

16 KiB
Raw Permalink Blame History

Planar Capture System Examples — Project Void Horror Game

Game: Project Void | Build Phase: 17e (Capture System Integration) Framework Systems: 136-147 (12 Planar Capture systems)


Purpose

Defines how the Planar Capture System is used in the Project Void horror game — mirrors that show wrong reflections, security monitors that display camera feeds, and void portals that warp reality. Every capture surface mode is demonstrated.


Capture Surface Placement Map

Surface Level Location Mode Purpose
BP_Mirror_NurseStation WardA Nurses Station Mirror Checkpoint mirror, also shows player reflection
BP_HorrorMirror_Morgue WardB Morgue HorrorMirror Wrong reflection scare (face appears behind player)
BP_HorrorMirror_WardensOffice WardensOffice Above desk HorrorMirror Final confrontation — entity speaks through mirror
BP_Monitor_Security WardA Security Office Monitor Shows hallway camera feed (live)
BP_Monitor_Morgue WardB Morgue office Monitor Shows morgue interior (static noise, flicker)
BP_Portal_VoidEntrance Basement Crematorium Portal Void portal — links to BP_Portal_VoidExit in VoidSpace
BP_Portal_VoidExit VoidSpace Memory Shrine 3 Portal Exit portal back to Basement
BP_FakeWindow_WardensOffice WardensOffice Window behind desk FakeWindow Shows "outside" view (rain, night, distant asylum)

1. BP_Mirror_NurseStation — Standard Mirror

Asset Path: Content/Game/Actors/BP_Mirror_NurseStation.uasset Parent: BP_Mirror (139) Framework Systems: 136-139, 144-147

Level Placement

L_Asylum_WardA → Nurses Station
  ├─ BP_Mirror_NurseStation (640×320 plane, wall-mounted)
  ├─ Position: Above sink counter, eye-level
  ├─ Material: MI_Mirror_Dirty (aged, slight oxidation)
  ├─ MPC params: DirtOpacity=0.3, SurfaceAge=0.2
  └─ ProximityTrigger: 1000uu radius

Gameplay Integration

  • Checkpoint: This mirror doubles as BP_Checkpoint_Mirror — player touches it to save
  • Reflection quality: Player is in a small room → mirror stays at High/Medium tier (close proximity)
  • No horror features — this is a normal mirror at this point in the game
  • Easter egg: Player's reflection blinks slightly out of sync (1 in 100 chance, very subtle)

Blueprint Setup

BP_Mirror_NurseStation (child of BP_Mirror)
  │
  ├─ Class Defaults:
  │    ├─ CaptureComponent.CaptureMode = Mirror
  │    ├─ CaptureComponent.QualityProfiles[1] = Medium (512px, 15fps, shadows)
  │    ├─ CaptureComponent.QualityProfiles[2] = High (1024px, 30fps, Lumen)
  │    ├─ SurfaceMesh → SM_WallMirror_640x320
  │    └─ SurfaceMaterial → MI_Mirror_Dirty
  │
  └─ Event BeginPlay:
       ├─ SetSurfaceMPCParameter("DirtOpacity", 0.3)
       ├─ SetSurfaceMPCParameter("SurfaceAge", 0.2)
       └─ EnableSurface()

2. BP_HorrorMirror_Morgue — Wrong Reflection Scare

Asset Path: Content/Game/Actors/BP_HorrorMirror_Morgue.uasset Parent: BP_HorrorMirror (142) Framework Systems: 136-138, 142, 144-147 + 101_BPC_ScareEventSystem

Level Placement

L_Asylum_WardB → Morgue
  ├─ BP_HorrorMirror_Morgue (800×600 plane)
  ├─ Position: On morgue wall, facing dissection table
  ├─ Material: MI_Mirror_Horror (horror layers enabled)
  ├─ WrongReflectionActor: BP_Enemy_Shade placed behind camera (hidden)
  └─ Trigger: Player looks at mirror > 2 seconds

Scare Sequence

Trigger: BPC_InteractionDetector focus remains on mirror for 2+ seconds
   │
   ├─ [Anticipation Phase] (5 seconds)
   │    ├─ Steam slowly fogs mirror:
   │    │    └─ Timeline: SteamIntensity MPC 0.0 → 0.4 over 3s
   │    ├─ Audio: SS_AudioManager.PlaySFX("mirror_steam_hiss")
   │    ├─ BPC_StressSystem.AddStress(+3) — subtle unease
   │    └─ Player is still watching their reflection
   │
   ├─ [Payoff Phase] (3 seconds)
   │    ├─ BPC_ScareEventSystem.TriggerScareEvent("MirrorApparition")
   │    │    └─ Coordinates with lights (flicker), audio (stinger)
   │    │
   │    ├─ CaptureComponent.ActivateHorrorReflection()
   │    │    └─ Swaps ShowOnly list from Self to WrongReflectionActor
   │    │    └─ Next capture frame: Shade appears in mirror instead of player
   │    │
   │    ├─ Timeline: WrongReflectionBlend MPC 0.0 → 1.0 over 0.5s (instant crossfade)
   │    ├─ Timeline: MirrorDarkness MPC 0.0 → 0.6 (mirror darkens)
   │    ├─ Timeline: DistortionAmplitude MPC 0.0 → 0.3 (mirror "breathes")
   │    │
   │    ├─ Steam text reveal: TextRevealProgress MPC 0.0 → 1.0
   │    │    └─ Text "JOIN ME" appears in steam on mirror surface
   │    │
   │    └─ Audio: SS_AudioManager.PlaySFX("mirror_scare_stinger")
   │         └─ Loud glass crack + whisper voice
   │
   └─ [Recovery Phase] (3 seconds)
        ├─ CaptureComponent.DeactivateHorrorReflection()
        │    └─ Restores player's reflection
        ├─ All MPC params return to 0.0 over 1.5s
        ├─ BPC_StressSystem.AddStress(+15) — spike
        └─ Mirror returns to normal (player can continue)

Blueprint Setup

BP_HorrorMirror_Morgue (child of BP_HorrorMirror)
  │
  ├─ Class Defaults:
  │    ├─ CaptureComponent.CaptureMode = HorrorMirror
  │    ├─ CaptureComponent.WrongReflectionActor = BP_Enemy_Shade_Reflection
  │    │    └─ (This Shade instance is placed behind a wall — invisible to player
  │    │       but visible to the capture camera due to ShowOnly list)
  │    ├─ CaptureComponent.QualityProfiles[2].DelayedFrameCount = 3
  │    │    └─ Reflection lags 3 frames at High tier
  │    ├─ ScareEventTag = "Game.Environment.Scare.MirrorApparition"
  │    └─ ScareDuration = 8.0
  │
  ├─ Curves:
  │    ├─ Curve_WrongReflectionBlend: (0,0) → (0.5,1.0) → (2.5,1.0) → (3.0,0)
  │    ├─ Curve_MirrorDarkness: (0,0) → (0.5,0.6) → (2.0,0.4) → (3.0,0)
  │    ├─ Curve_UVDistortion: (0,0) → (0.5,0.3) → (1.5,0.15) → (3.0,0)
  │    └─ Curve_SteamTextReveal: (1.0,0) → (2.0,1.0) → (3.0,1.0)
  │
  └─ Event Graph:
       ├─ Bind to BPC_InteractionDetector.OnFocusGained
       │    └─ If FocusedActor == Self → Start LookTimer (2.0s)
       │         └─ On Timer Complete → TriggerHorrorScare()
       │
       └─ TriggerHorrorScare() (implemented as described above)

3. BP_Monitor_Security — Security Camera Display

Asset Path: Content/Game/Actors/BP_Monitor_Security.uasset Parent: BP_Monitor (141) Framework Systems: 136-138, 141, 144-147

Level Placement

L_Asylum_WardA → Security Office
  ├─ BP_Monitor_Security (screen quad on desk)
  ├─ FixedCameraActor: SecurityCamera_HallwayA (placed in hallway)
  ├─ Shows live feed of hallway → player can see enemies patrolling
  └─ Power: ON by default

Monitor Behavior

BP_Monitor_Security
  │
  ├─ Class Defaults:
  │    ├─ CaptureComponent.CaptureMode = Monitor
  │    ├─ CaptureComponent.CaptureFOV = 70
  │    ├─ CaptureComponent.QualityProfiles[0].CaptureInterval = 0.2 (5fps)
  │    │    └─ Security monitors don't need high FPS
  │    ├─ CaptureComponent.FixedCameraActor = SecurityCamera_HallwayA
  │    └─ SurfaceMaterial → MI_Monitor_Security
  │
  ├─ Features:
  │    ├─ Static noise overlay: StaticNoiseIntensity = 0.1 (subtle grain)
  │    ├─ Scanline effect: bShowScanlines = true (CRT-like lines)
  │    └─ Power state reacts to fusebox puzzle:
  │         ├─ Fusebox power OFF → Monitor flickers and dies (PowerOff)
  │         └─ Fusebox power ON → Monitor boots up with flicker (PowerOn)
  │
  └─ Narrative hook:
       └─ At specific narrative flag ("ShadeEncountered"):
            └─ Shade briefly appears on monitor for 1 frame (rare event)
                 └─ BPC_RareEventSystem check every 30s, 2% chance

Blueprint Setup

BP_Monitor_Security (child of BP_Monitor)
  │
  ├─ Class Defaults:
  │    ├─ CaptureComponent.CaptureMode = Monitor
  │    ├─ CaptureComponent.CaptureFOV = 70
  │    ├─ bPoweredOn = true
  │    ├─ bShowScanlines = true
  │    ├─ StaticNoiseIntensity = 0.1
  │    └─ SurfaceMaterial = MI_Monitor_Security
  │
  └─ Event Graph:
       ├─ Event BeginPlay → EnableSurface
       │
       ├─ [Bind to fusebox puzzle]
       │    ├─ Listen for BPC_UsableWorldObjectSystem.OnActivated (fusebox power)
       │    │    └─ PowerOn() (with 1s flicker delay)
       │    └─ Listen for BPC_UsableWorldObjectSystem.OnDeactivated
       │         └─ PowerOff() (immediate)
       │
       └─ [Rare event: Shade on monitor]
            └─ Timer (30s loop) → Check narrative flag "ShadeEncountered"
                 └─ If true → Random Float 0-1 < 0.02
                      └─ True: Show Shade frame (capture swap to Shade actor for 0.2s)

4. BP_Portal_VoidEntrance / BP_Portal_VoidExit — Void Portal

Asset Path: Content/Game/Actors/BP_Portal_VoidEntrance.uasset Parent: BP_Portal (140) Framework Systems: 136-138, 140, 144-147 + 130_BPC_StateManager

Level Placement

L_Asylum_Basement → Crematorium
  ├─ BP_Portal_VoidEntrance (wall-mounted portal frame)
  ├─ LinkedTargetSurface: BP_Portal_VoidExit in L_Asylum_VoidSpace
  ├─ TeleportOnOverlap: true
  ├─ Appearance: Shimmering purple-black void surface
  └─ Trigger: Player walks into it
L_Asylum_VoidSpace → Exit Chamber (behind Memory Shrine 3)
  ├─ BP_Portal_VoidExit (floating portal in void)
  ├─ LinkedTargetSurface: BP_Portal_VoidEntrance (back to Basement)
  ├─ Shows: Basement Crematorium view (player's return destination)
  └─ Only visible after all 3 Memory Shrines activated

Portal Teleport Flow

Player overlaps BP_Portal_VoidEntrance.TeleportTrigger
   │
   ├─ [Server-authoritative check]
   │    └─ Switch HasAuthority
   │         ├─ Authority:
   │         │    ├─ BPC_StateManager.IsActionPermitted(Framework.Action.Teleport)?
   │         │    │    └─ True → proceed
   │         │    │    └─ False → Show blocked feedback, return
   │         │    │
   │         │    ├─ Get LinkedTargetSurface → Get ActorTransform
   │         │    ├─ Teleport player: SetActorLocation + SetActorRotation
   │         │    │    └─ Offset: targetForward * 300 (spawn 3m in front of exit)
   │         │    │
   │         │    ├─ [Transition Effects]
   │         │    │    ├─ WBP_ScreenEffectController.Flash(purple, 0.5s)
   │         │    │    ├─ BPC_CameraStateLayer.PushLayer("PortalTransition", 1.0s)
   │         │    │    │    └─ FOV 120 → 90 over 1s, chromatic aberration
   │         │    │    └─ SS_AudioManager.PlaySFX("portal_travel")
   │         │    │
   │         │    └─ Multicast_OnPlayerTeleported (visual feedback for all clients)
   │         │
   │         └─ Remote (client):
   │              └─ Call Server_TeleportThroughPortal RPC
   └─

Blueprint Setup

BP_Portal_VoidEntrance (child of BP_Portal)
  │
  ├─ Class Defaults:
  │    ├─ CaptureComponent.CaptureMode = Portal
  │    ├─ bTeleportOnOverlap = true
  │    ├─ bOneWay = false (two-way — player can return)
  │    ├─ SurfaceMaterial = MI_Portal_Standard
  │    └─ CaptureComponent.QualityProfiles[2].bEnableClipPlane = true
  │         └─ Clip plane prevents geometry behind portal from clipping in
  │
  ├─ Components:
  │    ├─ SurfaceMesh (portal plane)
  │    ├─ ProximityTrigger (quality scoring, large: 2000uu)
  │    └─ TeleportTrigger (overlap detection, same size as surface)
  │
  └─ Event Graph:
       ├─ BeginPlay → EnableSurface → RegisterWithManager
       │
       ├─ TeleportTrigger.OnComponentBeginOverlap
       │    └─ Cast to PlayerCharacter → If valid:
       │         └─ HasAuthority → Teleport player
       │         └─ Client → Server_TeleportThroughPortal RPC
       │
       └─ Server_TeleportThroughPortal (RPC, Reliable, Server)
            ├─ Validate portal still active
            ├─ Get LinkedTargetSurface
            ├─ Teleport player to exit location
            └─ Multicast_OnPlayerTeleported (play FX on all clients)

5. BP_FakeWindow_WardensOffice — Atmospheric Window

Asset Path: Content/Game/Actors/BP_FakeWindow_WardensOffice.uasset Parent: BP_FakeWindow (143) Framework Systems: 136-138, 143, 144-147

Level Placement

L_Asylum_WardensOffice → Behind Warden's desk
  ├─ BP_FakeWindow_WardensOffice (large window frame)
  ├─ Shows: "Outside" view — rain, night sky, distant asylum building
  ├─ Weather: Rain overlay based on game state
  └─ Parallax: Slight depth effect when player moves

Behavior

BP_FakeWindow_WardensOffice
  │
  ├─ Class Defaults:
  │    ├─ CaptureComponent.CaptureMode = FakeWindow
  │    ├─ CaptureComponent.CaptureFOV = 100 (wide window view)
  │    ├─ CaptureComponent.QualityProfiles[0] = Low (256px, 4fps)
  │    │    └─ Window is far from action — low priority
  │    └─ SurfaceMaterial → MI_FakeWindow_Interior
  │
  ├─ Weather Integration:
  │    └─ Listen to GS_HorrorGameState.OnGlobalFearChanged
  │         ├─ Fear < 0.3: Clear night, distant lights
  │         ├─ Fear 0.3-0.6: Light rain, overcast
  │         └─ Fear > 0.6: Heavy rain, lightning flashes, dark
  │
  └─ Sublevel Streaming:
       └─ bStreamSublevelOnProximity = true
            ├─ Stream in when player within 3000uu
            └─ Stream out when player beyond 4000uu

Capture Integration Checklist (for Project Void)

Mirrors

  • Create BP_Mirror_NurseStation in WardA Nurses Station
  • Create BP_HorrorMirror_Morgue in WardB Morgue
  • Create BP_HorrorMirror_WardensOffice in WardensOffice
  • Place BP_Enemy_Shade_Reflection (hidden) for morgue horror mirror
  • Create DA_Scare_MirrorApparition Data Asset (references BPC_ScareEventSystem)
  • Wire morgue mirror scare to BPC_ScareEventSystem.TriggerScareEvent()
  • Wire audio through SS_AudioManager for mirror crack/steam/whisper sounds

Monitors

  • Create BP_Monitor_Security in WardA Security Office
  • Create BP_Monitor_Morgue in WardB Morgue office
  • Place SecurityCamera_HallwayA CameraActor in WardA hallway
  • Wire monitor power to fusebox puzzle completion

Portals

  • Create BP_Portal_VoidEntrance in Basement Crematorium
  • Create BP_Portal_VoidExit in VoidSpace (behind Memory Shrine 3)
  • Wire portal visibility to Memory Shrine 3 completion
  • Add BPC_StateManager.IsActionPermitted(Teleport) check before teleport

Fake Windows

  • Create BP_FakeWindow_WardensOffice in WardensOffice
  • Create sublevel with window view room + camera
  • Wire weather overlay to GS_HorrorGameState.GlobalFearLevel

Quality & Performance

  • Test 8 capture surfaces active simultaneously → verify budget enforcement
  • Monitor GPU cost with stat GPU in PIE
  • Verify mirrors go Off when player is far away
  • Verify Hero tier assigned to mirror player is looking directly at

Notes for Expansion

  • Add mirror puzzle: player must look at specific angle in mirror to see hidden key reflected
  • Add portal network: multiple interconnected portals create non-Euclidean maze
  • Add monitor hacking: player can switch security cameras to find hidden items
  • Add weather system: fake windows sync weather with game narrative progression
  • Add mirror memory: some mirrors show "echoes" of past events (scripted timeline sequences)
  • Multiplayer: portals teleport all players; mirrors render each client's own reflection

Planar Capture Examples for Project Void. See GAMEINDEX.md for full game structure. See planar-capture-system.md for architecture spec.