# Planar Capture System — Implementation Checklist

**Version:** 1.0 | **Phase:** 17 | **Systems:** 136-147 (12 systems)

Use this checklist to track implementation of the Planar Capture System. Each checkbox represents a discrete task.

---

## Phase 17a — C++ Core (Systems 136-138)

### C++ Files to Create
- [ ] `Source/PG_Framework/Public/Capture/PlanarCaptureCommon.h` — enums, structs, quality profiles
- [ ] `Source/PG_Framework/Private/Capture/PlanarCaptureCommon.cpp` — compilation stub
- [ ] `Source/PG_Framework/Public/Capture/PlanarCaptureCameraUtils.h` — static math library
- [ ] `Source/PG_Framework/Private/Capture/PlanarCaptureCameraUtils.cpp` — mirror/portal/oblique math
- [ ] `Source/PG_Framework/Public/Capture/BPC_PlanarCapture.h` — component header
- [ ] `Source/PG_Framework/Private/Capture/BPC_PlanarCapture.cpp` — component implementation
- [ ] `Source/PG_Framework/Public/Capture/BP_PlanarCaptureActor.h` — actor header
- [ ] `Source/PG_Framework/Private/Capture/BP_PlanarCaptureActor.cpp` — actor implementation
- [ ] `Source/PG_Framework/Public/Capture/SS_PlanarCaptureManager.h` — subsystem header
- [ ] `Source/PG_Framework/Private/Capture/SS_PlanarCaptureManager.cpp` — subsystem implementation

### Build Configuration
- [ ] Update `PG_Framework.Build.cs` — add `"Renderer"` and `"RenderCore"` to PublicDependencyModuleNames
- [ ] Update `PG_Framework.h` — include `Capture/PlanarCaptureCommon.h`
- [ ] Compile and fix any errors
- [ ] Verify module loads in UE5 editor

### Initial Testing
- [ ] Spawn `BP_PlanarCaptureActor` in test level (use Blueprint child with mesh)
- [ ] Verify `SS_PlanarCaptureManager` is auto-created by engine
- [ ] Verify `BPC_PlanarCapture` initializes without crash
- [ ] Verify `RegisterSurface` logs to output log
- [ ] Test `CaptureNow()` — verify no crash during capture
- [ ] Test `ShutdownCapture()` — verify RT returned to pool

---

## Phase 17b — Material Foundation (Systems 144, 145, 147)

### M_CaptureSurface_Master
- [ ] Create Material: Name=`M_CaptureSurface_Master`, Domain=Surface, ShadingModel=Unlit
- [ ] Build Layer 0: Texture Sample Parameter "CaptureTexture" with UV flip branch (bIsMirror static switch)
- [ ] Build Layer 1: Condensation normal (Panner + Normal Strength driven by DistortionAmplitude MPC)
- [ ] Build Layer 2: Fresnel edge fade (CameraVector · VertexNormal)
- [ ] Build Layer 3: Dirt/scratch multiply (DirtMask × DirtOpacity, tinted by SurfaceAge)
- [ ] Build Layer 4: Steam/fog lerp (animated noise × SteamIntensity)
- [ ] Build Layer 5: Steam emissive glow (noise × SteamEmissiveIntensity → Emissive Color)
- [ ] Build Layer 6: Text reveal mask (TextRevealMask × TextRevealProgress)
- [ ] Build Layer 7: Mirror darkness (multiply by 1.0 - MirrorDarkness)
- [ ] Build Layer 8: Wrong reflection crossfade (lerp NormalRT ↔ DelayedRT by WrongReflectionBlend)
- [ ] Add bIsMirror static switch (true = UV flip)
- [ ] Add bEnableHorrorLayers static switch (false = Layers 6-8 compiled out)
- [ ] Add 10 MPC Collection Parameter nodes referencing MPC_CaptureSurface
- [ ] Compile → zero material errors

### MPC_CaptureSurface
- [ ] Create Material Parameter Collection: `MPC_CaptureSurface`
- [ ] Add 10 scalar parameters: SteamIntensity(default 0), DirtOpacity(0), CondensationFlow(0), DistortionAmplitude(0), MirrorDarkness(0), WrongReflectionBlend(0), TextRevealProgress(0), SteamEmissiveIntensity(0), DelayedReflectionBlend(0), SurfaceAge(0)
- [ ] Add 2 vector parameters: SurfaceTintColor(1,1,1,1), SteamColor(0.8,0.85,0.9,1)

### Material Instances
- [ ] Create `MI_Mirror_Clean` — bIsMirror=true, bEnableHorrorLayers=false
- [ ] Create `MI_Mirror_Dirty` — DirtOpacity=0.4, SurfaceAge=0.3
- [ ] Create `MI_Mirror_Steam` — SteamIntensity=0.6, CondensationFlow=0.5
- [ ] Create `MI_Mirror_Horror` — bEnableHorrorLayers=true
- [ ] Create `MI_Portal_Standard` — bIsMirror=false
- [ ] Create `MI_Monitor_Security` — bIsMirror=false
- [ ] Create `MI_FakeWindow_Interior` — bIsMirror=false

---

## Phase 17c — Blueprint Actors (Systems 139-143)

### BP_Mirror (139)
- [ ] Create Blueprint: Parent=`BP_PlanarCaptureActor`, Name=`BP_Mirror`
- [ ] Set `CaptureComponent.CaptureMode = Mirror` in Class Defaults
- [ ] Assign plane mesh to `SurfaceMesh`
- [ ] Assign `MI_Mirror_Clean` to SurfaceMesh Material[0]
- [ ] Set `SurfaceMPC` = `MPC_CaptureSurface`
- [ ] Add custom events: `SetMirrorDirtLevel(Float)`, `SetMirrorSteamLevel(Float)`
- [ ] Test: place in level, walk up, verify reflection renders

### BP_Portal (140)
- [ ] Create Blueprint: Parent=`BP_PlanarCaptureActor`, Name=`BP_Portal`
- [ ] Add `TeleportTrigger` BoxComponent
- [ ] Set `CaptureComponent.CaptureMode = Portal`
- [ ] Assign `MI_Portal_Standard` to SurfaceMesh
- [ ] Implement `OnPortalOverlap` event with `HasAuthority` gate
- [ ] Implement `Server_TeleportThroughPortal` RPC
- [ ] Add `LinkedTargetSurface` variable (set per instance)
- [ ] Test: place source + target portals, verify view renders and teleport works

### BP_Monitor (141)
- [ ] Create Blueprint: Parent=`BP_PlanarCaptureActor`, Name=`BP_Monitor`
- [ ] Set `CaptureComponent.CaptureMode = Monitor, CaptureFOV = 70`
- [ ] Override QualityProfiles[0].CaptureInterval = 0.2 (5fps)
- [ ] Assign `MI_Monitor_Security` to SurfaceMesh
- [ ] Add `bPoweredOn`, `StaticNoiseIntensity`, `FlickerCurve` variables
- [ ] Implement `PowerOn()`, `PowerOff()`, `SetStaticNoise()` functions
- [ ] Place CameraActor in level, assign to `FixedCameraActor`
- [ ] Test: power on/off cycle, static noise, scanline appearance

### BP_HorrorMirror (142)
- [ ] Create Blueprint: Parent=`BP_Mirror`, Name=`BP_HorrorMirror`
- [ ] Set `CaptureComponent.CaptureMode = HorrorMirror`
- [ ] Hero tier: set `DelayedFrameCount = 5`
- [ ] Place `WrongReflectionActor` (Metahuman/ghost) hidden in level
- [ ] Create Float Curves: `Curve_WrongReflectionBlend`, `Curve_MirrorDarkness`, `Curve_UVDistortion`
- [ ] Build `HorrorScareTimeline` with 4 tracks
- [ ] Implement `TriggerHorrorScare()` event
- [ ] Wire to `BPC_ScareEventSystem.TriggerScareEvent()`
- [ ] Wire audio to `SS_AudioManager.PlaySoundAtLocation()`
- [ ] Test: trigger scare, verify wrong reflection appears and fades, MPC params return to zero

### BP_FakeWindow (143)
- [ ] Create Blueprint: Parent=`BP_PlanarCaptureActor`, Name=`BP_FakeWindow`
- [ ] Set `CaptureComponent.CaptureMode = FakeWindow, CaptureFOV = 100`
- [ ] Assign `MI_FakeWindow_Interior` to SurfaceMesh
- [ ] Create sublevel with view room + SceneCaptureCamera
- [ ] Implement `CheckPlayerDistance` timer for sublevel streaming
- [ ] Implement `SetWeatherOverlay(Weather)` function
- [ ] Test: sublevel streams in/out based on distance

---

## Phase 17d — Data Asset (System 146)

### DA_PlanarCaptureProfile
- [ ] Create Data Asset: `DA_PlanarCaptureProfile` (PrimaryDataAsset or custom C++ class)
- [ ] Add variables: DefaultMode, QualityProfileOverrides, ShowOnly/Hidden actors, bStartEnabled, bDestructible, material override
- [ ] Create profile instances: `DA_HeroMirror`, `DA_SecurityMonitor`, `DA_HorrorMirror_ScareReady`
- [ ] Add `CaptureProfile` variable to `BP_PlanarCaptureActor` (Instance Editable, Expose on Spawn)
- [ ] Wire BeginPlay to apply profile

---

## Phase 17e — Integration

### Scare System Integration
- [ ] `BP_HorrorMirror.TriggerHorrorScare()` → `BPC_ScareEventSystem.TriggerScareEvent(Tag)` (101)
- [ ] Create `DA_ScareEvent` instance for mirror apparition scare (references existing 127 pattern)

### Audio Integration
- [ ] All sound triggers route through `SS_AudioManager` (132)
- [ ] Mirror shatter: `SS_AudioManager.PlaySoundAtLocation()`
- [ ] Portal whoosh: `SS_AudioManager.PlaySoundAtLocation()`
- [ ] Monitor static/hum: `SS_AudioManager.PlaySoundAtLocation()`

### State Manager Integration
- [ ] Portal teleport: `BPC_StateManager.IsActionPermitted(Teleport Tag)` (130)
- [ ] Horror scare: `BPC_StateManager.IsActionPermitted(Scare Tag)` before triggering
- [ ] Add `Framework.Action.Teleport`, `Framework.Action.Scare` tags to GameplayTag data tables

### Persistence Integration
- [ ] `BP_PlanarCaptureActor` implements `I_Persistable` (36)
- [ ] `CollectState()`: save bIsDestroyed, DirtOpacity, SteamIntensity, SurfaceAge
- [ ] `RestoreState()`: apply saved state, update MPC params

### Input Integration
- [ ] Portal transition pushes inspection input context via `SS_EnhancedInputManager` (128)

### Camera Integration
- [ ] Portal transition applies FOV animation via `BPC_CameraStateLayer` (14) (optional)

---

## Phase 17f — Polish & Performance

- [ ] Performance test: 1 mirror @ Hero → GPU profiling baseline
- [ ] Performance test: 3 mirrors @ High → verify budget enforcement
- [ ] Performance test: 10 mirrors, walk around → verify quality tiers scale correctly
- [ ] Edge case: mirror behind wall → verify frustum cull sets Off
- [ ] Edge case: player very far → verify distance sets Off
- [ ] Edge case: mirror destroyed during scene capture → no crash
- [ ] Edge case: rapid enable/disable cycle → no RT leak
- [ ] Memory test: verify RT pool releases all targets on level unload
- [ ] Multiplayer test: server destroys mirror, verify clients disable
- [ ] Multiplayer test: two players look at same mirror, verify both see correct reflection

---

## Documentation Verification

- [ ] `docs/blueprints/17-capture/` — 12 spec files created and reviewed
- [ ] `docs/blueprints/INDEX.md` — updated with 17-capture section
- [ ] `docs/developer/INDEX.md` — updated with 17-capture-systems entry
- [ ] `docs/developer/17-capture-systems.md` — developer reference created
- [ ] `CONTEXT.md` — Phase 17 added to Build Order, directory structure updated
- [ ] `UE5_Modular_Game_Framework.md` — systems 136-147 documented
- [ ] `docs/architecture/planar-capture-system.md` — architecture spec created
- [ ] `docs/architecture/blueprint-limitations-workarounds.md` — SceneCapture2D C++ workarounds added
- [ ] `docs/checklists/cpp-blueprint-status.md` — 12 new systems added to status grid

---

*Planar Capture System Checklist v1.0 — Track each checkbox as you implement.*
