Revert "fix(world): AP-48 client-side visibility cull (FPS sink across portal-hops)"

This reverts commit e5b2d15b63.
This commit is contained in:
Erik 2026-06-22 18:58:15 +02:00
parent e5b2d15b63
commit 8fbde99441
4 changed files with 1 additions and 268 deletions

View file

@ -61,7 +61,7 @@ accepted-divergence entries (#96, #49, #50).
---
## 2. Adaptation (AD) — 32 rows
## 2. Adaptation (AD) — 31 rows
| # | Divergence | Where (file:line) | Why it is safe / justified | Risk if assumption breaks | Retail oracle |
|---|---|---|---|---|---|
@ -96,7 +96,6 @@ accepted-divergence entries (#96, #49, #50).
| AD-29 | `ClientObjectTable` fires global `ObjectAdded`/`ObjectUpdated`/`ObjectRemoved` events; consumers filter by guid on their end. Retail dispatches per-object via `NoticeRegistrar` observer dispatch — each UI cell observes only its specific object guid | `src/AcDream.Core/Items/ClientObjectTable.cs:48` (events); `src/AcDream.App/UI/Layout/ToolbarController.cs:115` (guid filter) | `NoticeRegistrar` is inside keystone.dll with no PDB/decomp; global broadcast + consumer-side filter is functionally equivalent for the current panel count and object volumes seen in practice | At high object counts (>1 000 objects), every `ObjectUpdated` wakes every subscribed consumer — O(n·m) notification cost instead of retail's O(1) per-observer dispatch; a consumer that forgets the guid filter processes all objects (a latent correctness bug) | `NoticeRegistrar` (keystone.dll, no PDB); retail per-object observer registration in `CObjectMaint` |
| AD-30 | Cell-march preserves seed landblock id when `TryGetTerrainOrigin` returns false for an outdoor seed (#145 D, 2026-06-22): `BuildCellSetAndPickContaining` returns `currentCellId` verbatim rather than marching via `blockOrigin=(0,0,0)`; retail never encounters this state (cells stored block-local, no streaming-gap concept) | `src/AcDream.Core/Physics/CellTransit.cs:765` | Equivalence argument: "preserve-verbatim when unregistered" is the same contract as `PhysicsEngine.Resolve`'s NO-LANDBLOCK branch; the player's cell stays the last known-correct cell until the landblock's terrain registers — no march, no lbX=0 wire | A body whose seed landblock is genuinely absent for >1 physics tick holds its last-known cell rather than discovering the true containing cell; transient only — corrects the instant terrain registers; an indoor seed is explicitly excluded from the guard (outdoor low < 0x100 gate) | `CObjCell::find_cell_list` + block-local storage (retail has no streaming gap); `TryGetTerrainOrigin` pc path |
| AD-31 | Teleport transit covered by a full-screen black FADE (`FadeOverlay` + `TeleportAnimSequencer`) instead of retail's 3D portal-tunnel swirl (2026-06-22, spec C). Opaque black holds through the tunnel states; the world ramps back in on `WorldFadeIn`. | `src/AcDream.App/Rendering/FadeOverlay.cs` + `GameWindow.cs` (TAS transit tick; `_teleportFadeAlpha = ShowTunnel ? 1 : FadeAlpha`) | The fade is a functional cover that hides the (now-fast) destination load + the post-materialization object flood; the TAS state machine + golden timing constants are retail-verbatim — only the tunnel *graphic* is approximated. Sibling to AP-49 (fade-curve). | Visual-only: the transit shows a black cover, not the animated swirl. Retire by porting the `gmSmartBoxUI` 3D tunnel render. | `gmSmartBoxUI::UseTime` 0x004d6e30 (tunnel render, unported); `TELEPORT_ANIM_*` golden constants (spec §2.1) |
| AD-32 | Client-side visibility cull (AP-48 fix, 2026-06-22): world entities >384m AND outside the 3×3 landblock neighborhood for 25s continuous are evicted (arm-on-leave/clear-on-return), so the entity tables don't accumulate every town's objects across portal-hops. Adaptations vs holtburger: the nearby test uses each entity's `ParentCellId`-derived landblock (vs holtburger's `scene` landblock_map), the cull runs at **1 Hz** client-side (vs per-world-tick), and the time base is wall-clock (`DateTime.UtcNow`) not server time. | `src/AcDream.App/World/EntityVisibilityCuller.cs` + `GameWindow.TickEntityCull` (wiring) + `RemoveLiveEntityByServerGuid` (Forget on remove) | Faithful port of holtburger's `liveness.rs` (`ACE_DESTRUCTION_TIMEOUT_SECS=25`, `CONSERVATIVE_VISIBILITY_DISTANCE_M=384`); the player + held/equipped/contained items are excluded (player by guid; inventory items never carry a world position so they never enter the culled map); a re-created object is rescued (deadline cleared on remove + on the next visible tick) | An object the server still tracks but that goes silent >25s while >384m away is evicted locally and re-materializes only on the next server CreateObject (matches holtburger); a coordinate-frame edge where a genuinely-near object reads >384m is covered by the landblock-neighborhood OR-term | holtburger `crates/holtburger-world/src/state/liveness.rs:11-12,145-189,294-308`; ACE `ObjectMaint`/`Player_Tracking` never clears KnownObjects on teleport |
---