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.
This commit is contained in:
Lefteris Notas
2026-05-22 15:36:08 +03:00
parent 6b6c702dd7
commit 0a2d08b2ad
34 changed files with 5245 additions and 32 deletions

View File

@@ -199,8 +199,21 @@ Content/Game/ ← ALL game content (NEVER modify Fr
│ ├── BP_LightEvent_Flicker.uasset
│ ├── BP_ScareEvent_LockerBang.uasset
│ ├── BP_ScareEvent_Mirror.uasset
│ ├── BP_HorrorMirror_Morgue.uasset ← Horror mirror (wrong reflection scare)
│ ├── BP_Mirror_NurseStation.uasset ← Standard mirror (checkpoint reflection)
│ └── BP_AtmosphereController_WardA.uasset
├── Capture/ ← Planar Capture surface actors
│ ├── BP_Mirror_NurseStation.uasset ← Standard mirror: Mode=Mirror, aged, checkpoint
│ ├── BP_HorrorMirror_Morgue.uasset ← Horror mirror: wrong reflection, steam scare
│ ├── BP_HorrorMirror_WardensOffice.uasset ← Horror mirror: final entity confrontation
│ ├── BP_Monitor_Security.uasset ← Security monitor: hallway camera feed, scanlines
│ ├── BP_Monitor_Morgue.uasset ← Morgue monitor: static noise, flicker, Shade cameo
│ ├── BP_Portal_VoidEntrance.uasset ← Void portal entrance (Basement → VoidSpace)
│ ├── BP_Portal_VoidExit.uasset ← Void portal exit (VoidSpace → Basement)
│ ├── BP_FakeWindow_WardensOffice.uasset ← Atmospheric window: rain, night, parallax
│ └── DA_PlanarCaptureProfile_Mirror.uasset← Capture profile Data Assets
├── Audio/ ← Game-specific audio assets
│ ├── DA_AudioSettings_Horror.uasset ← Audio bus config
│ ├── BP_RoomAudioZone_WardA.uasset ← Room audio zone volumes
@@ -600,6 +613,22 @@ Each game asset proves a specific framework system works. Below: every framework
| 130 | BPC_StateManager | Hiding blocks fire; death blocks interaction; cutscene blocks all |
| 131 | DA_StateGatingTable | Designer-configurable state permission rules |
### 17-capture (Planar Capture — 12 systems)
| # | Framework System | Demonstrated By |
|---|-----------------|----------------|
| 136 | BPC_PlanarCapture | All capture surfaces (component managing SceneCapture2D lifecycle) |
| 137 | BP_PlanarCaptureActor | BP_Mirror, BP_Portal, BP_Monitor, BP_HorrorMirror, BP_FakeWindow (all extend this) |
| 138 | SS_PlanarCaptureManager | Auto-created WorldSubsystem — manages quality budget across all 8 surfaces |
| 139 | BP_Mirror | BP_Mirror_NurseStation — standard reflection mirror with aging |
| 140 | BP_Portal | BP_Portal_VoidEntrance/Exit — void portal teleport with clip plane |
| 141 | BP_Monitor | BP_Monitor_Security/Morgue — security camera feeds, scanlines, static noise |
| 142 | BP_HorrorMirror | BP_HorrorMirror_Morgue/WardensOffice — wrong reflection, steam, text, scare events |
| 143 | BP_FakeWindow | BP_FakeWindow_WardensOffice — atmospheric window with weather overlay |
| 144 | M_CaptureSurface_Master | All mirror/portal/monitor surfaces (9-layer material stack) |
| 145 | MPC_CaptureSurface | All 10 MPC scalar params (SteamIntensity, DirtOpacity, MirrorDarkness, etc.) |
| 146 | DA_PlanarCaptureProfile | DA_PlanarCaptureProfile_Mirror — per-surface quality config |
| 147 | MI_MirrorInstances | MI_Mirror_Clean/Dirty/Steam/Horror, MI_Portal_Standard, MI_Monitor_Security, MI_FakeWindow_Interior |
---
## Build Order (Dependency-Safe)
@@ -625,7 +654,8 @@ Follow this order when creating uasset files in UE5:
| 14 | **Data Assets (Content)** — Encounters, Atmosphere, Scares, Puzzles, Objectives, Behaviour, Acoustic | DA_* parents | 20+ |
| 15 | **Checkpoints** — BP_Checkpoint_SafeRoom, _Mirror | BP_Checkpoint | 2 |
| 16 | **Room Audio Zones** — BP_RoomAudioZone_* | BP_RoomAudioZone | 3 |
| 17 | **Encounter Spawners** — BP_EncounterSpawner_* | BPC_ProceduralEncounter | 3 |
| 17 | **Capture Surfaces** — BP_Mirror_NurseStation, BP_HorrorMirror_Morgue/WardensOffice, BP_Monitor_Security/Morgue, BP_Portal_VoidEntrance/Exit, BP_FakeWindow_WardensOffice | BP_PlanarCaptureActor | 9 |
| 18 | **Encounter Spawners** — BP_EncounterSpawner_* | BPC_ProceduralEncounter | 3 |
| 18 | **Atmosphere Actors** — BP_LightEvent_*, BP_ScareEvent_*, BP_AtmosphereController_* | BPC_* parent | 6 |
| 19 | **Tutorial Triggers** — BP_TutorialTrigger_* | BPC_TutorialSystem | 3 |
| 20 | **Polish** — BP_CreditsSequence, dev cheats, debug menu | Framework | 3 |
@@ -657,6 +687,7 @@ Each `docs/game/` file explains how to build a specific section of the prototype
| [`enemies-index.md`](enemies-index.md) | All enemies — Patient, Shade, Orderly — AI controllers, BT, perception | 12 |
| [`narrative-progression.md`](narrative-progression.md) | Objectives, dialogue, cutscenes, ending accumulator, branching | 13 |
| [`atmosphere-audio.md`](atmosphere-audio.md) | Atmosphere profiles, scares, lighting, room audio zones, adaptive environment | 14, 16, 17, 18 |
| [`planar-capture-examples.md`](planar-capture-examples.md) | Mirrors, horror mirrors, security monitors, void portals, fake windows — all 8 capture surfaces | 17 |
| [`save-checkpoints.md`](save-checkpoints.md) | Save system, checkpoints, death loop, void space, persistence | 15 |
| [`polish-loading-credits.md`](polish-loading-credits.md) | Tutorials, loading screen, credits, debug, analytics | 19, 20 |
| [`state-gating-examples.md`](state-gating-examples.md) | DA_StateGatingTable game-specific rules | 14 |

View File

@@ -0,0 +1,409 @@
# 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.*