# 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](GAMEINDEX.md) for full game structure. See [planar-capture-system.md](../architecture/planar-capture-system.md) for architecture spec.*