Brainstorm outcome for #133/G.3. Grounds the corrected root cause (dungeon
landblock = flat terrain + EnvCells, streams via the existing pipeline; the
blocker is the teleport-arrival snap firing BEFORE the dest landblock hydrates)
against the current code (5 verified seams) and lays out Approach C:
G.3a core teleport-into-dungeon: hold-until-hydration on the arrival path
(reuse #107 IsSpawnCellReady + IsSpawnClaimUnhydratable) + #111
validated-claim EnvCell placement + dest-ready streaming query +
dest-coord validation + timeout safety + decouple EnvCell
physics/visibility hydration from the render-mesh guard. -> VISUAL GATE
G.3b #95 stab_list bounding — CONDITIONAL on the gate showing the blowup
(its repro is stale, from the T4-deleted WB path; the current flood is
landblock-confined + enqueue-once, so #95 is likely superseded).
G.3c faithful TeleportAnimState portal-tunnel FSM (decomp 004d6300 /
219405-219774); the TAS_TUNNEL hold-exit gates on G.3a's same readiness
predicate (the tunnel IS the hold's visual form).
G.3d recall game-actions (/ls etc.) — same arrival flow; doubles as the test
lever.
Supersedes the §12 port-plan of r09 (most of it already shipped); r09 stays the
wire/format/recall contract reference. Resolves the handoff's 4 open questions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
24 KiB
Phase G.3 — Dungeon Support (Design Spec)
Status: APPROVED design (brainstorm 2026-06-13). Next:
writing-plans. Milestone: M1.5 ("Indoor world feels right"). G.3 is the remaining M1.5 exit-gate. M2 (CombatMath) stays deferred until this lands. Issue: #133 (teleport-into-dungeon snaps to ocean) + #95 (dungeon portal-graph visibility blowup — re-assessed below). Supersedes the §12 port-plan ofdocs/research/deepdives/r09-dungeon-portal-space.md: most of R9's "new types" (EnvCell loader/renderer/physics, PortalVisibility BFS, multi-cell transit) already shipped and power the building/cellar demo. r09 stays the retail contract reference for the wire formats, the EnvCell/CellPortal layout, and the recall taxonomy.
0. TL;DR
Dungeons don't work because of one timing+placement gap on one code path,
not a terrain-less-pipeline rewrite. A dungeon landblock (e.g. 0x0125, the
Holtburg-area meeting hall) is a flat-terrain landblock (LandBlock
present, all-zero heights) + 71 EnvCells + no buildings — it already streams,
renders, and collides through the existing pipeline. The teleport-arrival
handler snaps the player before that landblock has streamed in, so Resolve
falls back to the resident Holtburg blocks and lands the player in ocean.
The fix is retail's own shape: hold the player in portal space until the
destination cell is hydrated, then place into the EnvCell — reusing the
#107/#111 login machinery — and then layer retail's portal-tunnel visual
(TeleportAnimState) on top. We ship it in four installments, gated by one
visual acceptance test.
1. Corrected root cause (verified)
1.1 The "terrain-less landblock" framing is WRONG (dat-verified)
A prior research pass assumed dungeon landblocks have no LandBlock record, so
LandblockLoader.Load returns null and the whole streaming/render/physics
pipeline needs terrain-less support. A direct dat probe
(DungeonLandblockDatProbeTests, committed) refutes that:
0x0125 (dungeon): LandBlock 0x0125FFFF PRESENT, Height[81] allZero=True (flat)
LandBlockInfo: NumCells=71, Buildings=0, Objects=0
EnvCells 0x0100.. present (the 71 dungeon rooms)
0xA9B4 (Holtburg): LandBlock PRESENT, heights non-zero; NumCells=123, Buildings=12, Objects=114
A dungeon landblock is a flat-terrain landblock (lowest/"ocean" terrain
height index) plus its EnvCells, no buildings/objects. LandblockLoader.Load
returns a valid flat landblock; the terrain mesh builds a flat plane;
PhysicsEngine.AddLandblock gets a valid flat TerrainSurface. The existing
pipeline already streams a dungeon landblock. This matches ACE's IsDungeon
(all heights 0 + NumCells > 0 + no buildings — Landblock.cs:575) and the
single-landblock rule (Player_Tick.cs:548-560 forbids moving between dungeon
landblocks without a teleport — so "multi-landblock dungeon LOD" is moot).
1.2 The real blocker: teleport TIMING + PLACEMENT
OnLivePositionUpdated (src/AcDream.App/Rendering/GameWindow.cs:4877-4961)
detects teleport arrival as any player position update while in PortalSpace
(correct, per #107), then unconditionally:
- Recenters streaming to the destination landblock (
_liveCenterX/Y,:4908-4925). - Immediately calls
_physicsEngine.Resolve(destPos, destCell, …)to snap the player (:4927-4931) — before the destination landblock has streamed in. - Snaps entity + controller (
:4935-4939), exits PortalSpace (:4950), sendsLoginComplete(:4953-4959).
Because the dungeon landblock isn't resident yet, Resolve can't find the
destination cell, falls back to an outdoor scan against the still-resident
Holtburg landblocks, and snaps to 0xA9B3000E (Holtburg's south edge — local
(30,−60) maps into the block south of the A9B4 spawn). Streaming then shifts
the frame out from under the player → they slide south into ocean. ACE logs the
matching failed transition for +Acdream from 0x01250126 … to 0xA9B0000E …
chain (captured in launch-dungeon-diag.log).
There is no hold-until-hydration on the teleport-arrival path. The #107
login path directly above it (GameWindow.cs:1010-1024) HAS exactly this gate;
the teleport path doesn't.
2. Grounded seam facts (the design rests on these)
All five verified against current code this session (high confidence).
2.1 Teleport-arrival + PortalSpace FSM
OnTeleportStarted(GameWindow.cs:~4971-4976) — onPlayerTeleport (0xF751)sets_playerController.State = PlayerState.PortalSpace, freezing movement.PlayerMovementController.Update(PlayerMovementController.cs:840-854) returns a zero-movement result whileState == PortalSpace— PortalSpace already doubles as the input-freeze. It can equally serve as the hydration-wait gate.- Exit is only via the arrival detection in
OnLivePositionUpdated(:4880). No timeout, no cell-hydration gate today.
2.2 #107/#111 login machinery (directly reusable)
PhysicsEngine.IsSpawnCellReady(cellId)(PhysicsEngine.cs:468-472): outdoor (cellId & 0xFFFF < 0x0100) → always ready; indoor →DataCache.GetCellStruct(cellId) is not null(the cell's physics BSP has hydrated).IsSpawnClaimUnhydratable(claim)(GameWindow.cs:11728-11748): fetches the datLandBlockInfoat(lb & 0xFFFF0000) | 0xFFFE; a claim whose low word is>= 0x0100 + NumCells(orNumCells==0) can never hydrate → reject fast (distinguishes a bogus claim from a not-yet-streamed one).- #107 login hold (
GameWindow.cs:1010-1024):isSpawnGroundReadywaits for terrain AND (claim outdoor ORIsSpawnCellReadyORIsSpawnClaimUnhydratable). No timeout today (login can afford to wait forever; teleport cannot — see §5). - #111 validated-claim placement (
PhysicsEngine.cs:626-646): whensnapDiag (zero-delta) && adjustedFound && indoor, place viaWalkableFloorZNearest(:383-406) — projects Z onto the claim cell's own physics walkable polygons (normal.Z >= PhysicsGlobals.FloorZ, 0.6642), cell-local, nearest to the reference Z. Returnsnullif the cell isn't hydrated → falls through to the legacybestCellscan (the ocean bug). - The teleport-arrival Resolve call is already the same shape as login entry. The gate only needs to sit in front of it; no change to Resolve or WalkableFloorZNearest. (Both already key on the full prefixed cell id + indoor/outdoor.)
2.3 Streaming far recenter (works as-is)
StreamingRegion.RecenterTo(StreamingRegion.cs:180-283) recomputes the near/far Chebyshev window from scratch around the new center — a 42 km jump is treated identically to a 1-step move. No incremental-movement assumption.- Drain:
StreamingControllerapplies ≤MaxCompletionsPerFrame(default 4) results/frame;ApplyLoadedTerrainLocked(GameWindow.cs:5941-6150) does GPU upload + cell-visibility registration + AABB +PhysicsEngine.AddLandblock+ EnvCell/portal registration. Estimate: ~7-8 frames (~120-130 ms) to hydrate a 5×5 near window; physics ready +1-2 frames. - Recenter keeps the old neighborhood until hysteresis unload (NearRadius+2 demote, FarRadius+2 unload), so the player isn't instantly stranded.
- New code needed: a "destination landblock applied" query + dest-coord validation (reject out-of-world coords — a malformed portal dest would otherwise leave the player in an invisible, unloadable landblock).
2.4 EnvCell hydration coupling (latent landmine — decouple)
- In
BuildInteriorEntitiesForStreaming(GameWindow.cs:5564-5651), bothBuildLoadedCell(the portal-visibility node) and_physicsDataCache.CacheCellStruct(the physics BSP) sit inside the render guardif (cellSubMeshes.Count > 0)(:5602). A cell whose render mesh is empty (CellMesh.Buildreturns nothing — e.g. all-untextured/Stippling.NoPospolys) silently gets no visibility node and no collision, even if it has walkable physics polygons.CellTransit.FindTransitCellsSpherethenGetCellStruct → null → continue(silently skips it) → fall-through-floor. - A normal dungeon room has textured walls → non-empty submeshes → the guard
passes, so this is probably not the meeting-hall blocker — but it is a real
correctness landmine for any geometry-less collision cell, and decoupling is
cheap and retail-correct (physics/visibility do not depend on visible geometry).
Fix: gate
CacheCellStructoncellStruct.PhysicsBSP != nullandBuildLoadedCelloncellStruct != null, independent of the render submesh count. (CacheCellStructalready early-returns on null BSP internally —PhysicsDataCache.cs:172— so moving it out is safe.)
2.5 #95 — dungeon portal-graph visibility blowup (RE-ASSESSED: likely superseded)
- ISSUES.md #95 (
888-913): on a 2026-05-21 A6.P1 scen5 (Town Network hub) trace,visibleCellsper cell exploded to 135-145 with spurious cells from landblocks0x020A/0x0408(other dungeons). Its "Files" point at the WBEnvCellRenderManager/VisibilityManager+ the Streaming cell-cache. - That code path was DELETED by the T1-T6 render rewrite (2026-06-11) (T4:
"per-frame ACME BFS deleted… InteriorRenderer/DrawPortal deleted"). The current
flood,
PortalVisibilityBuilder.Build, (a) confines neighbors to the camera cell's landblock (lbMask = cameraCell.CellId & 0xFFFF0000,:131) and (b) has enqueue-once termination (queuedHashSet,:165— "at most N cells are ever processed"). Since AC dungeons are single-landblock, that confinement is correct, and the cross-landblock 135-cell blowup structurally cannot reproduce: a single-landblock flood visits ≤NumCellsdistinct cells (71 for the meeting hall). - Verdict: #95's evidence is stale, from a deleted path; the current pipeline is bounded. Treat #95 as likely superseded, unverified. The meeting-hall demo (71 cells, one landblock) IS its empirical test. Do not pre-build the stab_list bounding port against a dead repro (G.3b is conditional — §3.2).
3. The plan (Approach C — phased full-G.3)
Each installment lands a complete retail behavior (the BR-2 half-port lesson). The visual gate sits as early as possible, right after the core.
3.1 G.3a — Core teleport-into-dungeon (the blocker)
Goal: teleporting into the meeting-hall dungeon lands the player standing in
the dungeon cell, on the floor, with walls blocking — no ocean, no ACE
failed transition spam.
New component — TeleportArrivalController (src/AcDream.App/World/):
- Owns a small phase:
Idle / Holding / Placing, plus_pendingArrival(destPos, destCellId, deadline). - Lives outside
GameWindow(Code Structure Rule 1: no new feature bodies in the god-object).GameWindow.OnLivePositionUpdatedhands the arrival to it and calls its per-frameTick;GameWindowkeeps only the wiring. - Unit-testable in isolation (no GL, fake readiness predicate + fake Resolve).
Control flow (replaces the unconditional snap at GameWindow.cs:4927-4950):
- On arrival update in PortalSpace: validate
destCellId's landblock coords are in-world; recenter streaming + prioritize-load the dest landblock (existing path); stash_pendingArrival; enterHolding. Re-sendLoginCompleteimmediately (holtburger-conformant —messages.rs:434; do not wait for assets to send it). - Each frame in
Holding, evaluate the readiness predicate:IsSpawnClaimUnhydratable(destCell)→ impossible claim: stop holding, place via the safety-net demote (loud log), exit PortalSpace.now > deadline(timeout, ~10 s) → force-snap via safety-net demote + loud log, exit PortalSpace. (See §5 — failure-surfacing, not symptom-masking.)IsLandblockApplied(destLb) && IsSpawnCellReady(destCell)→ ready: go to 3.- else stay frozen, retry next frame.
Placing: call the existingResolve(destPos, destCell, Vector3.Zero, …). Because the cell is now hydrated, Resolve takes the #111 validated-claim branch →WalkableFloorZNearestgrounds the player on the EnvCell floor. Snap entity- controller (existing
:4935-4939code), exit PortalSpace, resume input.
- controller (existing
New streaming query — IsLandblockApplied(uint landblockId) (on
StreamingController / GpuWorldState): true once the landblock's terrain has
been applied (AABB set in ApplyLoadedTerrainLocked) and AddLandblock has
run into physics. Gate the hold on this, not on the GPU mesh alone.
Dest-coord validation: in OnLivePositionUpdated, reject a destination whose
(lbX, lbY) is out of the world grid before recenter; log + abort the teleport
hold rather than recenter to a phantom block.
Hydration decouple (§2.4): move BuildLoadedCell + CacheCellStruct out of
the cellSubMeshes.Count > 0 guard in BuildInteriorEntitiesForStreaming. Gate
each on its own non-null precondition.
Acceptance (G.3a): the visual gate in §6. This gate also empirically settles #95 (does the flood blow up?) and the hydration coupling (does collision work?).
3.2 G.3b — #95 visibility bounding (CONDITIONAL)
Trigger: only if the G.3a visual gate shows the see-through-walls / other-dungeon-geometry blowup at the meeting hall.
If triggered: port retail CEnvCell::grab_visible_cells (:311878) — a cell
with seen_outside == 0 loads ZERO terrain and walks ONLY its stab_list of
adjacent EnvCells; the portal graph is bounded by the dungeon's own cell
adjacency, never a radius. Verify the dat carries the stab_list and acdream's
EnvCell loader parses it before relying on it.
If NOT triggered: close #95 as superseded (deleted WB path; current flood bounded) with a one-line ISSUES.md note. No speculative build.
3.3 G.3c — Portal-tunnel loading visual (faithful TeleportAnimState)
Goal: the retail portal-space transition, ported faithfully (user decision 2026-06-13). Reconciles the older r09 §6 ("there is no loading screen") with the named-retail decomp where this FSM actually lives.
Oracle: gmSmartBoxUI::BeginTeleportAnimation (004d6300, named-retail line
218888) + the per-frame FSM (219405-219774). States:
TAS_WORLD_FADE_OUT → TAS_TUNNEL_FADE_IN → TAS_TUNNEL / TAS_TUNNEL_CONTINUE → TAS_TUNNEL_FADE_OUT → TAS_WORLD_FADE_IN → (off). m_pPortalSpace is a
UIElement_Viewport rendering the tunnel scene (creature-mode objects +
DISTANT_LIGHT + smartbox FOV; SetVisible(1) on enter, SetVisible(0) on the
TAS_TUNNEL_FADE_OUT → TAS_WORLD_FADE_IN edge at 219742-219747).
Key architectural unification: the TAS_TUNNEL/TAS_TUNNEL_CONTINUE hold
state's exit gates on the same readiness predicate as G.3a — retail's loading
visual and the hold-until-hydration gate are one mechanism (the tunnel is the
visual form of the hold). G.3a ships the bare PortalSpace freeze; G.3c wraps it
in the tunnel viewport + the fade FSM, exit-gated identically.
Port workflow: grep-named → decompile BeginTeleportAnimation + the FSM →
pseudocode (durations, fade math, viewport scene construction) → port → test.
Detail deferred to the G.3c implementation phase; this spec fixes the design
(states, transitions, the readiness-gated hold) + the oracle pointers.
3.4 G.3d — Recall game-actions
Outbound zero-payload game-action builders (r09 §7.1): TeleToLifestone 0x0063, TeleToHouse 0x0262, TeleToMansion 0x0278, TeleToMarketPlace 0x028D,
RecallAllegianceHometown 0x02AB, TeleToPkArena 0x0027. The client only sends
the request; the server validates, plays the recall animation, then drives the
same PlayerTeleport → UpdatePosition arrival flow.
Value: (1) doubles as the easy test lever for G.3a/G.3c — /ls triggers a
teleport with no portal-click choreography; (2) completes the recall UX (keybinds
exist; the wire sends + return handling did not). Wire through the existing
command bus.
4. Data flow (the teleport happy path)
1. PlayerTeleport(0xF751) → OnTeleportStarted: enter PortalSpace, freeze input
[G.3c: BeginTeleportAnimation(TAS_WORLD_FADE_OUT)]
2. fake UpdatePosition(destCell) → validate dest coords → recenter streaming to dest lb
→ prioritize-load dest lb → re-send LoginComplete
3. HOLD (TeleportArrivalController.Tick, each frame in PortalSpace):
ready = IsLandblockApplied(destLb) && IsSpawnCellReady(destCell)
- not ready → stay frozen, retry [G.3c: tunnel holds in TAS_TUNNEL/_CONTINUE]
- impossible → IsSpawnClaimUnhydratable → safety-net demote + loud log
- timeout → force-snap + loud log + leave PortalSpace
4. READY → Resolve(destPos, destCell) → #111 validated-claim branch
→ WalkableFloorZNearest places on the EnvCell floor
→ SetPosition(entity + controller) → exit PortalSpace, resume input
[G.3c: TAS_TUNNEL_FADE_OUT → TAS_WORLD_FADE_IN → off]
(ACE server send-order, for reference — Player_Location.Teleport:686:
PlayerTeleport(seq) → fake UpdatePosition (start client load) →
DoTeleportPhysicsStateChanges (hidden / ignoreCollisions) → real
UpdatePosition → OnTeleportComplete after CreateWorldObjectsCompleted.)
5. Error handling
| Failure | Handling | No-workaround rationale |
|---|---|---|
Impossible / poisoned claim (cell id ∉ [0x0100, 0x0100+NumCells), or no struct + no surface) |
IsSpawnClaimUnhydratable → safety-net demote (PhysicsEngine.Resolve head, :536-570) + loud log; never hold forever |
Reuses the validated #107/#111 reject; no new masking |
| Dest LB fails to stream (worker crash / corrupt dat / OOB coords) | Timeout ceiling (~10 s) → force-snap + loud log + leave PortalSpace | Surfaces the failure (visible bad placement + log), does not freeze the client or silence the cause; gets a divergence-register row |
| Mid-hold entity-rescue race | Already serialized by _datLock during recenter (verified, seam-3) |
No change |
The timeout is the one judgment call: holding forever on a never-hydrating landblock would soft-lock the client. The chosen behavior fails loudly and visibly (force-snap + log), which is the opposite of a symptom-masking grace period — it makes a broken teleport obvious rather than hiding it. It is recorded as a deliberate adaptation (retail loads synchronously; async streaming has no direct analog).
6. Testing & acceptance
6.1 Headless / unit
TeleportArrivalControllerFSM:Idle → Holding → Placinghappy path; impossible-claim immediate reject; timeout force-snap; ready-predicate gating (fakeIsLandblockApplied/IsSpawnCellReady).- Hydration-decouple test: a geometry-less EnvCell (empty render mesh, non-empty
physics BSP) still gets
CacheCellStruct+BuildLoadedCell. TeleportFlowTests: fakePlayerTeleport+UpdatePositionwire → controller phase transitions + input-gate flips.DungeonLandblockDatProbeTests(exists): pins0x0125= flat + 71 cells.- G.3c:
TeleportAnimStateFSM transition test (state sequence + the readiness-gatedTAS_TUNNELhold-exit). - G.3d: recall-builder byte tests (opcode + empty payload, per builder).
6.2 Visual gate (the acceptance test — after G.3a)
Teleport into the meeting-hall dungeon via the portal:
- Player stands in the dungeon cell, on the floor (not ocean, not falling).
- The dungeon renders; navigate 3–5 rooms; walls block movement.
- No ocean / no ACE
failed transitionspam. - (Implicitly) the portal flood does not blow up (#95 check) and collision works in every room (hydration-coupling check).
ACDREAM_PROBE_CELL=1 + ACDREAM_PROBE_VIEWER=1 + ACDREAM_WB_DIAG=1 + the
always-on [snap] / live: teleport lines capture the chain (the
launch-dungeon-diag.log protocol from this session).
6.3 Per-installment build/test gates
Each installment: dotnet build green + dotnet test green
(App / Core / UI / Net suites) before it's "done"; G.3a additionally requires the
visual gate.
7. Retail divergence register impact
- G.3a timeout force-snap → NEW row (adaptation: async streaming hold has no
synchronous-retail analog; retail loads the cell set synchronously before
SetPositionInternal). - Hydration decouple → NO row (bug fix retiring an incidental render↔physics coupling; restores retail-correct independence).
- G.3c → only a row if a faithful asset can't be reproduced (e.g. the tunnel viewport scene) and a documented courtesy substitute is shipped.
- #95 close-as-superseded (if G.3b not triggered) → ISSUES.md note only.
8. Component boundaries (what each unit does / depends on)
| Unit | Location | Does | Depends on |
|---|---|---|---|
TeleportArrivalController |
AcDream.App/World/ |
Owns the Idle/Holding/Placing phase + _pendingArrival; decides hold-vs-place each frame |
readiness predicate (injected), Resolve (injected), PortalSpace state |
| readiness predicate | StreamingController + PhysicsEngine |
IsLandblockApplied(lb) ∧ IsSpawnCellReady(cell); IsSpawnClaimUnhydratable(cell) |
dat LandBlockInfo, DataCache |
| hydration decouple | GameWindow.BuildInteriorEntitiesForStreaming |
BuildLoadedCell + CacheCellStruct gated on cellStruct/BSP, not render mesh |
cellStruct, PhysicsBSP |
TeleportAnimState FSM (G.3c) |
AcDream.App UI/render |
Portal-tunnel fade FSM; hold-exit gated on the readiness predicate | m_pPortalSpace viewport, the readiness predicate |
| recall builders (G.3d) | AcDream.Core/Network/Actions |
Zero-payload outbound game actions | command bus |
AcDream.Core gains no GL/window dependency. The controller + FSM live in
AcDream.App; the readiness predicate's physics half lives in AcDream.Core
(pure), its streaming half in AcDream.App.
9. References cited
- Current code (verified this session):
GameWindow.cs4877-4961 (arrival), ~4971-4976 (OnTeleportStarted), 1010-1024 (#107 login gate), 11728-11748 (IsSpawnClaimUnhydratable), 5564-5651 (EnvCell hydration guard), 5941-6150 (ApplyLoadedTerrainLocked);PhysicsEngine.cs468-472 (IsSpawnCellReady), 626-646 (#111 validated claim), 383-406 (WalkableFloorZNearest), 536-570 (Resolve safety net);StreamingRegion.cs180-283 (RecenterTo);StreamingController.cs120-149 (drain);PortalVisibilityBuilder.cs131 (lbMask), 165 (enqueue-once);CellTransit.cs515-516 (null-skip);PhysicsDataCache.cs172 (null-BSP early-return). - Decomp (named-retail):
BeginTeleportAnimation004d6300(line 218888) + theTeleportAnimStateFSM 219405-219774;m_pPortalSpaceviewport 218829/219363;CEnvCell::grab_visible_cells:311878(G.3b stab_list). - holtburger:
messages.rs:434(client re-sendsLoginCompleteon teleport). - ACE:
Player_Location.Teleport:686(send order);Landblock.cs:575(IsDungeon);Player_Tick.cs:548-560(single-landblock dungeons); recall handlers +Portal.ActOnUse/AdjustDungeon. - r09 deepdive:
docs/research/deepdives/r09-dungeon-portal-space.md(EnvCell / CellPortal wire layout, recall taxonomy, the retail contract). - Issues: #133, #95.
- Digests (DO-NOT-RETRY tables apply):
project_render_pipeline_digest,project_physics_collision_digest.
10. Open questions (resolved here; revisit only if the gate disagrees)
- Loading visual now or later? Faithful
TeleportAnimStatein G.3c (user decision). Unified with the G.3a hold (the tunnel IS the hold's visual). - Hold timeout/failure? Reject impossible claims instantly
(
IsSpawnClaimUnhydratable); hold plausible-but-slow with a ~10 s ceiling; on timeout force-snap + loud log (fail visibly, never freeze). - Big-jump streaming? Verified to work (Chebyshev recenter). Add only
IsLandblockApplied+ dest-coord validation. - EnvCell placement vs flat terrain? The #111
WalkableFloorZNearestEnvCell path (identical to the cellar path that already works); the flat terrain renders below. The gate guarantees the cell is hydrated before Resolve runs. - (New, deferred to G.3b/implementation) Does the dat carry a parsed
stab_listforgrab_visible_cellsbounding? Only matters if the gate shows the #95 blowup.