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

@ -136,13 +136,35 @@ internal sealed class LocalPlayerTeleportRenderStateSource
: IRenderFramePortalStateSource
{
private readonly LocalPlayerTeleportController _teleport;
private readonly IRenderLoginStateSource _login;
public LocalPlayerTeleportRenderStateSource(LocalPlayerTeleportController teleport)
public LocalPlayerTeleportRenderStateSource(
LocalPlayerTeleportController teleport,
IRenderLoginStateSource login)
{
_teleport = teleport ?? throw new ArgumentNullException(nameof(teleport));
_login = login ?? throw new ArgumentNullException(nameof(login));
}
public bool IsPortalViewportVisible => _teleport.IsPortalViewportVisible;
/// <summary>
/// The frame presents the portal-viewport shape (opaque black clear, no
/// world draw, retained UI on top) when the tunnel scene is visible OR
/// while a live login is still pre-world. The second arm is retail's
/// pre-player gameplay screen: after char-select Enter queues UI mode
/// 0x10000008 (<c>CM_Login::SendNotice_BeginEnterWorld @ 0x006AD810</c>
/// from <c>CPlayerSystem::LogOnCharacter @ 0x0055F890</c>), the SmartBox
/// has no player and draws NO world — the screen behind the UI is black
/// until <c>SmartBox::teleport_in_progress @ 0x00451C20</c> goes high at
/// CreatePlayer and <c>gmSmartBoxUI::UseTime @ 0x004D6EAB</c> begins the
/// tunnel in the same tick. The former sky-only "waiting for login"
/// backdrop had no retail counterpart and presented as the gate's
/// entry-edge VOID (2026-08-17). Both flags flip on the update thread
/// (the login activation tick flips ChaseModeEverEntered AND makes the
/// tunnel visible before the next render), so the black → tunnel → world
/// sequence swaps atomically per frame.
/// </summary>
public bool IsPortalViewportVisible =>
_teleport.IsPortalViewportVisible || _login.IsWaitingForLogin;
public uint ActiveDestinationCell => _teleport.ActiveDestinationCell;
}