fix #176 #177: the camera-capped light snapshot evicted visible cells' torches — per-cell lighting popped at seams
The probe launch discriminated it: the user reproduced the purple floor flash while [light] (ambient branch) and [pv-input] (portal flood) read provably healthy — eliminating the last CPU-side theories and exposing the one channel the probes could not see: per-cell 8-light set composition. BuildPointLightSnapshot kept the MaxGlobalLights=128 point lights nearest THE CAMERA; the Facility Hub registers 366 fixtures, so 238 were evicted per frame by camera distance. SelectForObject (faithfully camera-independent, and unit-pinned as such) could only choose from the surviving 128 — an in-range torch of a visible cell that ranked past the cap dropped out of that cell's 8-set, so per-cell Gouraud lighting flipped as the chase boom swung the camera: - #176: the flipping unit is a CELL -> discontinuity lines at exactly cell-seam granularity; a torch-losing floor drops to dim blue-grey stone at 0.2 ambient (the perceived purple), camera-angle dependent. - #177: a stair room whose torches all ranked past the cap rendered at bare 0.2 ambient (near-black = 'not visible'); approach re-admitted them ('pops into existence'); the sweeping boundary dropped the ramp's lights mid-descent ('disappears on the last step'). The geometry never vanished - its lights did. Retail's minimize_object_lighting (0x0054d480) has NO global camera-nearest pool cap (lights register per cell, insert_light 0x0054d1b0). Fix: MaxGlobalLights 128 -> 1024, a non-biting safety valve (GlobalLightPacker grows to fit; 64 B/light). Register row AP-85. TDD pin: PointSnapshot_HubScaleLightCount_ObjectSelectionIsCameraInvariant (RED at 128 with a Hub-scale 401-light layout, GREEN at 1024). The pre-existing camera-independence pin covered the SELECTOR but not the SNAPSHOT it selects from - the pop re-entered one stage upstream. Suites: Core 2588 / App 719 / UI 425 / Net 385 green. Pending user gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
b8e9e204ad
commit
4d25e04d83
5 changed files with 151 additions and 28 deletions
|
|
@ -1,6 +1,53 @@
|
|||
# #176/#177 render pair — investigation ledger (2026-07-06, session 2)
|
||||
|
||||
**Status: mechanism NOT yet pinned — but the hypothesis space is now razor-thin.**
|
||||
## ✅ OUTCOME (same day, after the probe launch): ROOT CAUSE FOUND + FIX SHIPPED
|
||||
|
||||
**The probe run discriminated it.** The user reproduced the purple floor
|
||||
flash while BOTH surviving CPU theories read provably healthy in the log —
|
||||
`[light]` insideCell/ambient rock-stable (one pre-spawn outdoor line, then
|
||||
flat 0.2 grey through 36 transits), `[pv-input]` flood stable (54k frames,
|
||||
zero collapses). That eliminated T-A and T-B and exposed the one channel
|
||||
the probes were structurally blind to: **per-cell 8-light SET COMPOSITION.**
|
||||
|
||||
The log's own headline number told the story: `registeredLights=366` —
|
||||
against `MaxGlobalLights = 128`. `BuildPointLightSnapshot` kept the 128
|
||||
lights nearest THE CAMERA and evicted 238 every frame; `SelectForObject`
|
||||
(camera-independent, faithfully retail — and unit-PINNED as such) could
|
||||
only choose from the surviving 128. An in-range torch of a VISIBLE cell
|
||||
that ranked past the cap dropped out of that cell's 8-set → the cell's
|
||||
per-vertex Gouraud lighting flipped as the camera moved (the chase boom
|
||||
swings the camera position by meters, re-ranking the 128):
|
||||
|
||||
- **#176:** the flipping unit is A CELL → discontinuity lines at exactly
|
||||
cell-seam granularity; a torch-losing floor drops to dim blue-grey
|
||||
stone (0.2 ambient × stone = the perceived purple); camera-angle
|
||||
dependent by construction.
|
||||
- **#177:** a stair room whose torches ALL ranked past the cap rendered
|
||||
at bare 0.2 ambient — near-black in a dungeon = "not visible from the
|
||||
corridor"; approaching re-admitted them = "pops into existence"; the
|
||||
boundary sweeping during the descent dropped the ramp's lights =
|
||||
"disappears on the last step". The geometry never vanished — its
|
||||
LIGHTS did.
|
||||
|
||||
Retail anchor: `minimize_object_lighting` (0x0054d480) selects from the
|
||||
cell-registered reaching set (`insert_light` 0x0054d1b0) — **no global
|
||||
camera-nearest pool cap exists in retail.**
|
||||
|
||||
**Fix:** `MaxGlobalLights` 128 → 1024 (a non-biting safety valve; the
|
||||
GPU packer grows to fit — 64 B/light). Register row **AP-85**. TDD pin:
|
||||
`LightManagerTests.PointSnapshot_HubScaleLightCount_ObjectSelectionIsCameraInvariant`
|
||||
(RED at 128 with a Hub-scale 401-light layout, GREEN at 1024). All four
|
||||
suites green. **Pending the user visual gate.**
|
||||
|
||||
Process note: the pre-existing test
|
||||
`SelectForObject_CameraIndependent_DependsOnlyOnObjectCentre` was written
|
||||
to pin "the property that kills the lights-up-as-I-approach popping" — it
|
||||
proved the SELECTOR camera-independent while the SNAPSHOT it selects from
|
||||
was camera-capped. The pop re-entered one stage upstream of the pin.
|
||||
|
||||
---
|
||||
|
||||
**Pre-launch status below (kept as the audit trail): mechanism NOT yet pinned — but the hypothesis space is now razor-thin.**
|
||||
Twelve candidate mechanisms refuted by direct evidence (dat dumps, headless
|
||||
replays, production-log analysis, code reads). Every layer that can be checked
|
||||
offline is verified HEALTHY at the anchor cells. The surviving discriminator
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue