fix(teleport #145): IsLandblockLoaded key mismatch — outdoor gate was permanently NotReady
The Slice 2 outdoor readiness gate queried IsLandblockLoaded(destCell & 0xFFFF0000) = e.g. 0x7D640000, but streaming stores landblocks under the EncodeLandblockId form (low 16 = 0xFFFF), e.g. 0x7D64FFFF. The raw ContainsKey never matched, so the outdoor teleport gate could NEVER flip Ready and every outdoor arrival ran to the 600-frame (~10 s) timeout and force-placed. The cascade was still prevented (the timeout force-place lands cleanly), but the gate did no work — the 10 s freeze the apparatus showed was this bug, NOT the #138 streaming stall I first suspected. Root cause found via the apparatus re-test (3-agent investigation wf_8b67a9d1-35c, all high-confidence) + verified against StreamingRegion.cs:99 (EncodeLandblockId | 0xFFFF), PhysicsEngine.cs:79 (stores as-is), GameWindow.cs:5530 (queries & 0xFFFF0000). Fix: IsLandblockLoaded normalizes its arg to the canonical 0xFFFF landblock key, so the prefix form, any contained cell id, and the dat-id form all resolve. Added the regression test the original Slice 2 test missed (it had checked the same 0xFFFF form it added; the real caller passes the 0x..0000 form). Red on the prefix/cell forms before the fix, green after. 9/9. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
589c7cfb57
commit
c8809735f3
2 changed files with 48 additions and 5 deletions
|
|
@ -32,13 +32,23 @@ public sealed class PhysicsEngine
|
|||
public int LandblockCount => _landblocks.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true iff a landblock with this id has been registered via
|
||||
/// <see cref="AddLandblock"/>. Because <see cref="AddLandblock"/> registers
|
||||
/// terrain + collision cells + portals atomically, ContainsKey implies the
|
||||
/// collision mesh is present and resolvable.
|
||||
/// Returns true iff the landblock CONTAINING the given id has been registered via
|
||||
/// <see cref="AddLandblock"/>. Because <see cref="AddLandblock"/> registers terrain +
|
||||
/// collision cells + portals atomically, a hit implies the collision mesh is present
|
||||
/// and resolvable.
|
||||
/// <para>
|
||||
/// The argument may be any id within the landblock — a full cell id (low 16 = cell
|
||||
/// index), the landblock-prefix form (low 16 = 0x0000, as the teleport gate passes via
|
||||
/// <c>destCell & 0xFFFF0000</c>), or the dat-id storage form. The low 16 bits are
|
||||
/// normalized to the canonical landblock key (<c>0xFFFF</c>) that streaming stores under
|
||||
/// (<see cref="AcDream.App.Streaming.StreamingRegion.EncodeLandblockId"/> ORs in 0xFFFF),
|
||||
/// so all three forms resolve. The earlier raw <c>ContainsKey(id & 0xFFFF0000)</c>
|
||||
/// never matched the 0xFFFF-terminated stored key, leaving the outdoor teleport gate
|
||||
/// permanently NotReady (2026-06-21 #145 apparatus re-test).
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public bool IsLandblockLoaded(uint landblockId) =>
|
||||
_landblocks.ContainsKey(landblockId);
|
||||
_landblocks.ContainsKey((landblockId & 0xFFFF0000u) | 0xFFFFu);
|
||||
|
||||
/// <summary>
|
||||
/// Cell-based spatial index for static object collision.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue