docs: A7.L1 session bookkeeping — close #190, update #93/#189, file #191

- #190 (interior entity id overflow) moved to Recently closed with full
  evidence trail — found + fixed same session as #189's investigation.
- #189 (missing particles) updated: root cause was #190's id aliasing,
  not the light-carrier hydration fix itself; fix shipped but the
  fountain's water spray hasn't been re-confirmed visually yet (session
  moved to an FPS question, then a movement bug, before circling back).
  The "candle" identification sub-thread stays open regardless.
- #93 (indoor lighting umbrella) updated earlier this session with the
  two A7.L1 root causes + fixes; #80/#94 still need re-verification
  before it can close.
- #191 filed: tapping W briefly glides forward without playing the step
  animation (retail: single visible step). Different subsystem
  (movement/animation, not rendering) — not investigated this session,
  filed to keep it from interrupting A7 lighting/particle work.
- Roadmap Phase A7 progress note added earlier this session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-09 12:40:42 +02:00
parent e651cb6dd1
commit 6e034ac610
2 changed files with 174 additions and 6 deletions

View file

@ -46,6 +46,102 @@ Copy this block when adding a new issue:
--- ---
## #189 — Ambient particle scripts (fountain water, possibly candle flames) don't render indoors
**Status:** 🟡 LIKELY FIXED (`e651cb6d`, #190) — pending final user visual re-confirmation
**Severity:** MEDIUM
**Filed:** 2026-07-09
**Component:** rendering — particles / PhysicsScript
**Description:** In the Town Network fountain room (`0x00070144`), the fountain
has no visible water-spray particle effect. User also reported missing candle
flames in the same area (unconfirmed which object(s) those are — see Root
cause below).
**Root cause / status:** NOT the A7.L1 mesh-empty hydration gate itself
(`EntityHydrationRules.ShouldKeepEntity`) — directly refuted via dat-truth
(`Issue93TownNetworkFountainRoomLightInspectionTests.
FountainAndCandleSetup_DefaultScriptAndMeshSurvivorCount_Dump`): the fountain's
Setup (`0x02000AA3`) has a surviving mesh part (not dropped) AND a real
`DefaultScript.DataId = 0x33000B21` (almost certainly the water-spray
PhysicsScript) — hydration itself was fine.
**Found instead (via revert-test, per user request): #190, an entity-id
overflow the light fix triggered as a SIDE EFFECT.** The mesh-carrier fix
kept ~394 more entities alive per landblock, pushing the Town Network's
interior-entity counter from 248 to 277 — past the id scheme's 8-bit budget
(`ACDREAM_DUMP_ENTITY=0x02000AA3` showed the fountain's `entity.Id` shift from
`0x400007F8` to `0x40000815`, misdecoding as landblock Y=0x08 instead of the
true Y=0x07). `EntityScriptActivator` keys script/particle tracking on
`entity.Id` directly, so the aliased id broke the fountain's script tracking.
Fixed by `#190` (widened the id counter 8→12 bits). Post-fix,
`ACDREAM_DUMP_ENTITY` confirmed the fountain's id (`0x40007115`) decodes
correctly again — **not yet re-confirmed visually by the user** (session moved
on to an FPS question, then a movement bug, before the fountain was re-checked).
The guessed "candle" objects (`0x02001967`, 16 arranged around the fountain)
turned out to have real mesh and `DefaultScript == 0` — they are NOT candles
and carry no script at all, so the actual candle-flame source objects are
still unidentified; that part of this issue stays open regardless of #190.
**Next steps:**
1. Get the user's visual confirmation that the fountain water spray is back.
2. Identify the real candle-flame source objects in this room (not
`0x02001967`) before assuming they share a root cause with the fountain.
**Files:**
- `src/AcDream.App/Rendering/Vfx/EntityScriptActivator.cs`
- `src/AcDream.Core/World/InteriorEntityIdAllocator.cs` (the #190 fix)
- `src/AcDream.App/Streaming/GpuWorldState.cs` (DefaultScript fire/stop sites)
- `src/AcDream.Core/Vfx/ParticleHookSink.cs`
- `tests/AcDream.Core.Tests/Rendering/Issue93TownNetworkFountainRoomLightInspectionTests.cs` (dat-truth apparatus, reusable)
**Acceptance:** The Town Network fountain shows a water-spray particle effect
matching retail; candle/torch flame sources in the same room are identified
and render correctly.
---
## #191 — Tapping W (brief forward press) glides forward without playing the step animation
**Status:** OPEN
**Severity:** MEDIUM (visible every time a player taps instead of holds a movement
key — likely a common input pattern)
**Filed:** 2026-07-09
**Component:** physics / animation — movement input, motion sequencing
**Description:** User-reported (live testing, unrelated to tonight's A7 lighting
work): tapping W briefly translates the player forward smoothly ("glide") without
the walk/run step animation playing. In retail, a brief tap produces a single
visible step (a short animated motion), not a silent slide. Not investigated this
session — filed to keep A7 lighting/particle work from being interrupted by an
unrelated subsystem (movement/animation, not rendering).
**Root cause / status:** UNKNOWN. Likely candidates for a future session (grep
named retail decomp FIRST, per the mandatory workflow — do not guess):
- The R5 movement-manager arc shipped 2026-07-05 (`docs/research/2026-07-03-r5-managers/`)
— check whether this is a regression from that work or a pre-existing gap it
didn't cover.
- Retail likely distinguishes a brief key tap (press+release before some
threshold) from a held key at the INPUT/COMMAND layer, producing a distinct
one-shot "step" motion command rather than the continuous Walk/RunForward
cycle — search `docs/research/named-retail/acclient_2013_pseudo_c.txt` for how
`CMotionInterp`/the movement command dispatch handles a short-duration
ForwardCommand before it's promoted to a full walk/run cycle.
- Candidate files: `src/AcDream.App/Input/PlayerMovementController.cs`
(local input → command translation), `src/AcDream.Core/Physics/MotionInterpreter.cs`
/ `AnimationSequencer.cs` (cycle selection/dispatch).
- Cross-reference `references/holtburger/crates/holtburger-core/src/client/movement/`
for what a real client sends on a brief tap vs a hold.
**Files:** Not yet identified beyond the candidates above.
**Acceptance:** A brief W tap produces a single retail-faithful step animation
(not a silent glide); holding W still transitions normally into the walk/run
cycle.
---
## #187 — [DONE 2026-07-08] Non-hinged doors (sliding doors, gates) don't play their open animation ## #187 — [DONE 2026-07-08] Non-hinged doors (sliding doors, gates) don't play their open animation
**Status:** CLOSED 2026-07-08 — user-confirmed live gate: "sliding doors now work." **Status:** CLOSED 2026-07-08 — user-confirmed live gate: "sliding doors now work."
@ -3198,22 +3294,49 @@ Retail oracle for cell-id hysteresis: `acclient_2013_pseudo_c.txt:308742-308783`
## #93 — Indoor lighting broken (M1.5 lighting umbrella) ## #93 — Indoor lighting broken (M1.5 lighting umbrella)
**Status:** OPEN — **M1.5 scope (A7 lighting fidelity, primary lighting issue)** **Status:** OPEN — **M1.5 scope (A7 lighting fidelity, primary lighting issue)**. Two real
root causes found + fixed 2026-07-09 (A7.L1), user-confirmed improvement at the Town
Network fountain room ("lightning is better"). Not closing outright — the umbrella covers
several symptom classes (#80 2nd-floor darkness, #94 held-item spotlight direction) that
weren't re-verified this session, and #189 (missing ambient particles, found in the same
room) shows there's more to the "feels right" bar than point lights alone.
**Severity:** HIGH (degrades indoor experience; M1.5 acceptance depends on it closing) **Severity:** HIGH (degrades indoor experience; M1.5 acceptance depends on it closing)
**Filed:** 2026-05-20 **Filed:** 2026-05-20
**Component:** lighting, rendering **Component:** lighting, rendering
**Description:** Interior cells (inn, cottages, dungeons — anywhere with `cellLow >= 0x0100`) render with lighting that doesn't match retail. Specific symptoms include #80 (2nd floor goes dark), wrong per-cell ambient, missing cell-internal light sources (torches/lanterns), and outdoor day-cycle bleeding into indoor cells. Umbrella issue covering the family; sub-issues to be filed during A7.L1 probe spike. **Description:** Interior cells (inn, cottages, dungeons — anywhere with `cellLow >= 0x0100`) render with lighting that doesn't match retail. Specific symptoms include #80 (2nd floor goes dark), wrong per-cell ambient, missing cell-internal light sources (torches/lanterns), and outdoor day-cycle bleeding into indoor cells. Umbrella issue covering the family; sub-issues to be filed during A7.L1 probe spike.
**Root cause / status:** Suspected family of bugs in (a) per-cell environment-light tag parsing from the dat (we may not parse `cell.envLightInfo` correctly), (b) cell-light association (which lights belong to which cell), (c) indoor visibility culling for lights, (d) the indoor branch of `GameWindow.UpdateSunFromSky` which uses a flat ambient. Investigation deferred to A7.L1. **Root cause / status:** Two DISTINCT root causes confirmed + fixed 2026-07-09 for the
Town Network "fountain room too dark" symptom (#79/#176/#177's deferred light-cap arc):
1. **Candidate-pool starvation in dense hubs** (`d275ed55`): `LightManager.BuildPointLightSnapshot`
sorted ALL registered lights by raw player-distance with no visibility filter — in a
463+ fixture hub, geometrically-closer-but-wall-disconnected fixtures could out-rank a
visible room's own (farther) torches for the 128-cap. Fixed by scoping candidacy to
last frame's rendered visible-cell set (`RetailPViewFrameResult.DrawableCells`, one
frame of latency — see AP-85 in the divergence register for why this specific approach
was chosen over re-threading a mid-`DrawInside` callback, the exact mechanism that
caused the earlier c500912b #176 regression).
2. **THE actual fountain-room darkness (`9ebb2060`, the bigger fix):** the mesh-empty
hydration gate (`GameWindow.cs` ~7324) dropped an entity's WHOLE registration — including
its `Setup.Lights` — whenever its visual mesh flattened to zero parts (a common dat
pattern: a "light attach point" Setup whose sole visual part is a legitimately
runtime-hidden marker, #136-class). Confirmed via direct dat-truth inspection
(`Issue93TownNetworkFountainRoomLightInspectionTests`): the fountain room's ONE
dat-authored light (a ceiling fixture, Setup 0x02000365) was silently dropped this way —
the room registered ZERO lights of its own, so scoping fix #1 alone had no local light
to redistribute. Fixed via `EntityHydrationRules.ShouldKeepEntity` — an entity survives
hydration if it has mesh OR lights, not just mesh. Dungeon-wide effect: registered
lights jumped 498→892 on the same launch.
**Files:** **Files:**
- `src/AcDream.App/Rendering/GameWindow.cs:8330+` (`UpdateSunFromSky`, indoor branch with flat ambient) - `src/AcDream.Core/Lighting/LightManager.cs` (`BuildPointLightSnapshot` visible-cell scoping)
- `src/AcDream.App/Rendering/GameWindow.cs` (hydration gate, `_lightPoolVisibleCells`)
- `src/AcDream.Core/Meshing/EntityHydrationRules.cs` (the mesh-empty-but-has-lights predicate)
- `src/AcDream.App/Rendering/GameWindow.cs:8330+` (`UpdateSunFromSky`, indoor branch with flat ambient — unrelated, unchanged)
- `src/AcDream.App/Rendering/Shaders/mesh_modern.frag` (per-pixel light evaluation) - `src/AcDream.App/Rendering/Shaders/mesh_modern.frag` (per-pixel light evaluation)
- `references/WorldBuilder/...` (any WB lighting helpers we inherit) - Retail oracle: grep `Render::lighting_*` / `add_light` in `acclient_2013_pseudo_c.txt`
- Retail oracle: grep `Render::lighting_*` in `acclient_2013_pseudo_c.txt`
**Acceptance:** Holtburg inn interior lighting matches retail at the same character position. Holtburg Sewer dungeon torchlight reads correctly per-room. 2nd-floor cells brightness matches ground floor. **Acceptance:** Holtburg inn interior lighting matches retail at the same character position. Holtburg Sewer dungeon torchlight reads correctly per-room. 2nd-floor cells brightness matches ground floor. **Remaining before this can close:** re-verify #80 (2nd floor) and #94 (held-item spotlight direction) specifically — neither was re-checked this session; the Town Network fix targeted the starvation/hydration-drop symptom, not every #93 sub-symptom.
--- ---
@ -7278,6 +7401,34 @@ outdoors at the angle that previously erased it.
# Recently closed # Recently closed
## #190 — Interior entity id counter overflowed past its 8-bit budget, aliasing into the next landblock
**Status:** DONE (2026-07-09, `e651cb6d`). Found while investigating #189
(missing fountain particle): a user-requested revert-test of the A7.L1 light
fix (9ebb2060) made the fountain work again, which didn't fit the earlier
dat-truth finding that the fountain's own entity was untouched by that fix.
Traced with `ACDREAM_DUMP_ENTITY`: the fountain's hydrated `entity.Id` shifted
between reverted (`0x400007F8`) and fixed (`0x40000815`) builds — the extra
mesh-less light carriers the A7.L1 fix now keeps alive earlier in the same
landblock's hydration pass shifted `localCounter`. `0x40000815` decodes as
landblock Y=0x08 — NOT the Town Network's true Y=0x07 — the exact `#119`
cross-landblock id-aliasing bug, reincarnated by entity COUNT (277, past the
8-bit/256 budget) rather than a computation bug; the `#119` fix's own comment
had explicitly flagged this as a residual risk ("counter overflow past 0xFF
still bleeds into the lbY byte"). `EntityScriptActivator` keys particle-script
instances by `entity.Id` directly (no landblock-hint disambiguation, unlike
`#119`'s Tier-1 batch cache), so the aliased id silently broke the fountain's
script tracking. Fix: `AcDream.Core.World.InteriorEntityIdAllocator` widens the
counter 8→12 bits (256→4096) by shrinking the fixed class-prefix from a full
byte (`0x40`) to its top nibble (`0x4_`) — verified safe against every
`entity.Id` classification check in `GameWindow.cs` (none decode X/Y back out,
only threshold/prefix checks). Added a loud one-time `[id-overflow]` log if a
landblock ever exceeds the new budget. Post-fix: fountain's id (`0x40007115`)
decodes correctly (Y=7, counter=277, safely under 4095). Core 2675+2skip /
App 741+2skip / UI 425 / Net 385 green.
---
## #170 — Remote creature chase+attack renders wrong vs retail (glide, run not sustained) ## #170 — Remote creature chase+attack renders wrong vs retail (glide, run not sustained)
**Status:** DONE (2026-07-04, user visual gate passed — "as close to retail now as **Status:** DONE (2026-07-04, user visual gate passed — "as close to retail now as

View file

@ -293,6 +293,23 @@ successfully 2026-04-30 for the steep-roof case. Matching binaries
#### Phase A7 — Indoor lighting fidelity (RenderDoc + retail-decomp driven) #### Phase A7 — Indoor lighting fidelity (RenderDoc + retail-decomp driven)
**A7.L1 progress (2026-07-09, `d275ed55` + `9ebb2060`):** the Town Network
"fountain room too dark" report (#79/#93 umbrella) is root-caused to TWO
distinct bugs, both fixed and user-confirmed improved ("lightning is
better"): (1) `BuildPointLightSnapshot`'s player-nearest cap had no
visibility filter — in a 463+ fixture hub, wall-disconnected-but-Euclidean-
closer fixtures could out-rank a visible room's own torches; scoped
candidacy to last frame's rendered visible-cell set. (2) THE bigger fix: the
mesh-empty hydration gate dropped an entity's ENTIRE registration — Setup
Lights included — whenever its visual mesh flattened to zero parts (a
mesh-less "light attach point" carrying only a Light, common dat pattern);
fixed via `EntityHydrationRules.ShouldKeepEntity`. Dungeon-wide effect:
registered lights 498→892 on the same launch. NOT closing A7 yet — #80
(2nd floor) and #94 (held-item spotlight) weren't re-verified this session,
and #189 (missing fountain/candle particles, found in the same room,
confirmed NOT the same root cause) is a fresh open thread. Full detail in
ISSUES.md #93 + AP-85 in the divergence register.
**Now also owns #176/#177 (2026-07-06):** the Facility Hub purple seam **Now also owns #176/#177 (2026-07-06):** the Facility Hub purple seam
flash + stair-room light pop-in are ROOT-CAUSED to this phase's "light flash + stair-room light pop-in are ROOT-CAUSED to this phase's "light
visibility culling" layer — a camera-nearest `MaxGlobalLights=128` visibility culling" layer — a camera-nearest `MaxGlobalLights=128`