fix(ui): gate — no void frames around the login wormhole; vitals icons centered

The login tunnel now covers from the first world-facing frame (the
sky-void backdrop can never present pre-tunnel) and holds through an
atomic tunnel-to-world swap at reveal completion — the void is
structurally unreachable on both edges, pinned by frame-sequence tests
across WorldSceneRenderer/WorldRevealCoordinator/LocalPlayerTeleport-
Controller/RuntimeWorldTransitState. Vitals detail icons draw at their
authored centered offsets in both stacked and side-by-side layouts.
Implemented and live-probed by the fix agent; finalized by the lead
after the agent parked post-verification (gates re-run green:
App 5512/3, Runtime 1747/0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-17 12:30:51 +02:00
parent 2f8c046aba
commit fdc4fd496d
17 changed files with 649 additions and 66 deletions

View file

@ -159,11 +159,13 @@ internal sealed class WorldSceneRenderer : IWorldSceneFramePhase
_sky.DayFraction);
}
// Retail keeps the live sky during EnterWorld while suppressing
// terrain and object geometry until chase mode has engaged.
if (_login.IsWaitingForLogin)
return CompleteSkippedWorld();
// The former sky-only "waiting for login" skip lived here.
// It is unreachable now: LocalPlayerTeleportRenderStateSource
// folds IsWaitingForLogin into PortalViewportVisible (retail's
// pre-player gameplay screen draws NO world — black, not sky),
// so the portal-visible return above already covers every
// waiting frame. One gate computes the frame's visibility;
// this phase only enforces it.
_passes.DrawFlatTerrain(in camera, roots.PlayerLandblockId);
terrainDrawn = true;
}
@ -291,16 +293,6 @@ internal sealed class WorldSceneRenderer : IWorldSceneFramePhase
diagnostic.VisibleLandblocks,
diagnostic.TotalLandblocks,
NormalWorldDrawn: true);
WorldRenderFrameOutcome CompleteSkippedWorld()
{
CompleteWorldFrame();
worldFrameStarted = false;
pviewFrameStarted = false;
_selection?.CompleteFrame();
selectionFrameStarted = false;
return default;
}
}
catch (Exception renderFailure)
{