# 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.*
