using System.Numerics; using AcDream.App.Input; using AcDream.App.Net; using AcDream.App.Physics; using AcDream.App.Rendering; using AcDream.App.Update; using AcDream.App.World; using AcDream.Core.Net.Messages; using AcDream.Core.Audio; using AcDream.Core.Physics; using AcDream.Core.Rendering; using AcDream.Core.World; using AcDream.Runtime; using AcDream.Runtime.Physics; using AcDream.Runtime.Session; using AcDream.Runtime.World; namespace AcDream.App.Streaming; internal interface ILocalPlayerTeleportNetworkSink { void OnTeleportStarted(uint sequence); void OfferDestination( RuntimeTeleportDestination destination, bool teleportTimestampAdvanced); void ResetSession(); void ResetGenerationPresentation(); } /// /// Construction-order bridge for the inbound session. It carries no teleport /// state: after binding, every packet and reset is forwarded to the one /// owner. /// internal sealed class DeferredLocalPlayerTeleportNetworkSink : ILocalPlayerTeleportNetworkSink { private ILocalPlayerTeleportNetworkSink? _inner; public void Bind(ILocalPlayerTeleportNetworkSink inner) { ArgumentNullException.ThrowIfNull(inner); if (Interlocked.CompareExchange(ref _inner, inner, null) is not null) throw new InvalidOperationException("The local teleport sink is already bound."); } public IDisposable BindOwned(ILocalPlayerTeleportNetworkSink inner) { Bind(inner); return new Binding(this, inner); } private void Unbind(ILocalPlayerTeleportNetworkSink expected) { _ = Interlocked.CompareExchange(ref _inner, null, expected); } public void OnTeleportStarted(uint sequence) => Required().OnTeleportStarted(sequence); public void OfferDestination( RuntimeTeleportDestination destination, bool teleportTimestampAdvanced) => Required().OfferDestination(destination, teleportTimestampAdvanced); public void ResetSession() => Required().ResetSession(); public void ResetGenerationPresentation() => Required().ResetGenerationPresentation(); private ILocalPlayerTeleportNetworkSink Required() => _inner ?? throw new InvalidOperationException( "The local teleport sink was used before composition completed."); private sealed class Binding : IDisposable { private DeferredLocalPlayerTeleportNetworkSink? _owner; private readonly ILocalPlayerTeleportNetworkSink _expected; public Binding( DeferredLocalPlayerTeleportNetworkSink owner, ILocalPlayerTeleportNetworkSink expected) { _owner = owner; _expected = expected; } public void Dispose() => Interlocked.Exchange(ref _owner, null)?.Unbind(_expected); } } internal interface ILocalPlayerTeleportInputLifetime { void EndMouseLook(); } internal interface ILocalPlayerTeleportModeOperations { PlayerMovementController? Controller { get; } Matrix4x4 Projection { get; } bool TryEnterPortalSpace(); void EnterWorld(); } internal interface ILocalPlayerTeleportAuthority { bool IsFreshStart(ushort sequence); } internal sealed class LiveLocalPlayerTeleportAuthority : ILocalPlayerTeleportAuthority { private readonly LiveEntityRuntime _liveEntities; private readonly ILocalPlayerIdentitySource _identity; public LiveLocalPlayerTeleportAuthority( LiveEntityRuntime liveEntities, ILocalPlayerIdentitySource identity) { _liveEntities = liveEntities ?? throw new ArgumentNullException(nameof(liveEntities)); _identity = identity ?? throw new ArgumentNullException(nameof(identity)); } public bool IsFreshStart(ushort sequence) => _liveEntities.IsFreshTeleportStart(_identity.ServerGuid, sequence); } internal interface ILocalPlayerTeleportStreamingOperations { int CenterX { get; } int CenterY { get; } bool IsRecenterPending { get; } bool BeginRecenter(int x, int y, bool isSealedDungeon); bool ResetRecenter(bool sessionEnding); bool IsSealedDungeon(uint cellId); } internal sealed class LocalPlayerTeleportStreamingOperations : ILocalPlayerTeleportStreamingOperations { private readonly LiveWorldOriginState _origin; private readonly StreamingOriginRecenterCoordinator _recenter; private readonly StreamingController _streaming; private readonly ISealedDungeonCellClassifier _sealedDungeonCells; public LocalPlayerTeleportStreamingOperations( LiveWorldOriginState origin, StreamingOriginRecenterCoordinator recenter, StreamingController streaming, ISealedDungeonCellClassifier sealedDungeonCells) { _origin = origin ?? throw new ArgumentNullException(nameof(origin)); _recenter = recenter ?? throw new ArgumentNullException(nameof(recenter)); _streaming = streaming ?? throw new ArgumentNullException(nameof(streaming)); _sealedDungeonCells = sealedDungeonCells ?? throw new ArgumentNullException(nameof(sealedDungeonCells)); } public int CenterX => _origin.CenterX; public int CenterY => _origin.CenterY; public bool IsRecenterPending => _recenter.IsPending; public bool BeginRecenter(int x, int y, bool isSealedDungeon) => _recenter.Begin(x, y, isSealedDungeon); public bool ResetRecenter(bool sessionEnding) => _recenter.Reset(sessionEnding); public bool IsSealedDungeon(uint cellId) => _sealedDungeonCells.IsSealedDungeon(cellId); } internal interface ILocalPlayerTeleportPlacement { void Place(Quaternion rotation); } /// /// C4 route 3: acknowledges the local player's deferred portal arrival — /// the canonical placement itself now runs through /// /// (a portal arm sharing route 2's Runtime SetPosition owner), retiring the /// duplicate Resolve/SetPosition authority this class used to own (D1; /// docs/research/2026-08-04-c4-route-3-contract.md D-T4). This class runs /// AFTER that commit succeeds. A10 review fix (2026-08-05): the render /// pose write and rebucket this method performs /// are REDUNDANT repeats of a mutation the canonical Place receipt already /// made — RuntimePlacementPresentationSink.TryApply → /// LiveEntityRuntime.TryApplyRuntimePlacementPlace already calls /// entity.SetPosition/sets Rotation/ParentCellId and /// rebuckets, synchronously, before TryPublishPlace's OWN snapshot /// even runs (proof obligation P2's ordering). This method's writes are /// therefore harmless-but-duplicate, not the render entity's ONLY mover as /// an earlier revision of this comment claimed; kept because they cost /// nothing extra and this is also where the retail teleport_hook tail's /// remaining local-player-visible actions run (target-watcher /// notification, camera reset, spatial reconcile). /// is the retained accepted destination's wire /// orientation — the resolved body orientation was already committed /// identically by CommitCanonical (retail's teleport branch does not /// independently reorient the mover), so re-deriving it here would only add /// a second copy of the same source of truth. /// internal sealed class LocalPlayerTeleportPlacement : ILocalPlayerTeleportPlacement { private readonly LiveEntityRuntime _liveEntities; private readonly ILocalPlayerIdentitySource _identity; private readonly IRuntimeLocalPlayerControllerSource _controller; private readonly ILocalPlayerPhysicsHostSource _host; private readonly ChaseCameraInputState _cameras; private readonly ILiveSpatialReconcilePhase _spatial; public LocalPlayerTeleportPlacement( LiveEntityRuntime liveEntities, ILocalPlayerIdentitySource identity, IRuntimeLocalPlayerControllerSource controller, ILocalPlayerPhysicsHostSource host, ChaseCameraInputState cameras, ILiveSpatialReconcilePhase spatial) { _liveEntities = liveEntities ?? throw new ArgumentNullException(nameof(liveEntities)); _identity = identity ?? throw new ArgumentNullException(nameof(identity)); _controller = controller ?? throw new ArgumentNullException(nameof(controller)); _host = host ?? throw new ArgumentNullException(nameof(host)); _cameras = cameras ?? throw new ArgumentNullException(nameof(cameras)); _spatial = spatial ?? throw new ArgumentNullException(nameof(spatial)); } public void Place(Quaternion rotation) { PlayerMovementController controller = _controller.Controller ?? throw new InvalidOperationException( "Teleport Place ran without the local player controller."); uint playerGuid = _identity.ServerGuid; if (_liveEntities.TryGetWorldEntity( playerGuid, out WorldEntity? entity)) { entity.SetPosition(controller.Position); entity.ParentCellId = controller.CellId; entity.Rotation = rotation; // Retail CPhysicsObj::enter_world installs the object in its // destination CObjCell before hidden scripts/particles resume. // The canonical commit has already advanced FullCellId, but that // fact alone does not move acdream's retained projection out of // its source/pending GPU bucket. Commit both halves of the // spatial move here, while portal space still owns the // viewport, so CPhysicsObj::update_object's cell-gated tail can // advance the Hidden/UnHide PES chain at retail's boundary. if (!_liveEntities.RebucketLiveEntity(playerGuid, controller.CellId)) { throw new InvalidOperationException( $"Teleport Place could not commit local player 0x{playerGuid:X8} " + $"to destination cell 0x{controller.CellId:X8}."); } } // Retail teleport_hook tail @ 0x00514ED0 clears the local target and // notifies every watcher that this object teleported. The body's // constraint leash re-arm and orientation are already the canonical // commit's job (RuntimeAcceptedPositionDriveController // .ReconcileAndAcknowledgePortal -> PlayerMovementController // .CommitCanonicalTeleportFrame), so this suffix only acknowledges // the result into presentation. _host.Host?.NotifyTeleported(); _cameras.Legacy?.Update(controller.Position, controller.Yaw); _cameras.Retail?.ResetViewerToPlayer(controller.Position, controller.Yaw); _spatial.Reconcile(); PhysicsDiagnostics.LogTeleport( "PLACED", controller.CellId, "readiness=complete"); Console.WriteLine( $"live: teleport materialized - snapped to {controller.Position} " + $"cell=0x{controller.CellId:X8}"); } } internal interface ILocalPlayerTeleportSession { void SendLoginComplete(); } internal sealed class LocalPlayerTeleportSession : ILocalPlayerTeleportSession { private readonly ILiveWorldSessionSource _session; public LocalPlayerTeleportSession(ILiveWorldSessionSource session) => _session = session ?? throw new ArgumentNullException(nameof(session)); public void SendLoginComplete() => _session.CurrentSession?.SendGameAction( GameActionLoginComplete.Build()); } internal interface ILocalPlayerTeleportPresentation : IDisposable { bool IsPortalViewportVisible { get; } int CurrentTunnelFrame { get; } void Begin(Matrix4x4 projection); (TeleportAnimSnapshot Snapshot, IReadOnlyList Events) Tick(float deltaSeconds, bool worldReady); void TickTunnel(float deltaSeconds); void PlayEnterCue(); void PlayExitCue(); void EnterTunnel(); void ExitTunnel(); void SetWaitCue(bool visible); void Reset(); Matrix4x4 ApplyViewPlane(Matrix4x4 projection); ICamera ApplyViewPlane(ICamera camera); void DrawPortalViewport(int width, int height, Matrix4x4 projection); } internal sealed class LocalPlayerTeleportPresentation : ILocalPlayerTeleportPresentation { private readonly TeleportAnimSequencer _animation = new(); private readonly TeleportViewPlaneController _viewPlane = new(); private readonly PortalTunnelPresentation _tunnel; public LocalPlayerTeleportPresentation(PortalTunnelPresentation tunnel) => _tunnel = tunnel ?? throw new ArgumentNullException(nameof(tunnel)); public bool IsPortalViewportVisible => _tunnel.IsVisible; public int CurrentTunnelFrame => _tunnel.CurrentAnimationFrame; public void Begin(Matrix4x4 projection) { _viewPlane.Begin(projection); _animation.Begin(TeleportEntryKind.Portal); } public (TeleportAnimSnapshot Snapshot, IReadOnlyList Events) Tick(float deltaSeconds, bool worldReady) { var (snapshot, events) = _animation.Tick( deltaSeconds, worldReady, CurrentTunnelFrame); _viewPlane.Update(snapshot); return (snapshot, events); } public void TickTunnel(float deltaSeconds) => _tunnel.Tick(deltaSeconds); /// /// Interface-sound sink for the portal cues. Retail plays these from the /// teleport-animation boundary, not from the tunnel renderer: /// PlaySoundFromCenter(Sound_UI_EnterPortal, GetUISoundTable()) at /// 0x004D638E inside gmSmartBoxUI::BeginTeleportAnimation, and /// Sound_UI_ExitPortal at 0x004D7405. Assigned at composition; /// null (and therefore silent) when audio is unavailable. /// public Action? UiSoundSink { get; set; } /// /// Sound_UI_EnterPortal, at retail's moment: the START of the /// teleport animation (gmSmartBoxUI::BeginTeleportAnimation @ /// 0x004D638E), which the sequencer marks as /// TeleportAnimEvent.PlayEnterSound — NOT when the tunnel viewport /// first appears, which is a TunnelFadeIn later. /// public void PlayEnterCue() => UiSoundSink?.Invoke(SoundId.UI_EnterPortal); /// /// Sound_UI_ExitPortal @ 0x004D7405, at the /// TunnelFadeOut to WorldFadeIn edge — the sequencer's /// TeleportAnimEvent.PlayExitSound, the same tick the world viewport /// is revealed. /// public void PlayExitCue() => UiSoundSink?.Invoke(SoundId.UI_ExitPortal); public void EnterTunnel() => _tunnel.Enter(); public void ExitTunnel() => _tunnel.Exit(); public void SetWaitCue(bool visible) => _tunnel.SetWaitCue(visible); public void Reset() { _animation.Reset(); _viewPlane.Reset(); _tunnel.Exit(); } public Matrix4x4 ApplyViewPlane(Matrix4x4 projection) => _viewPlane.Apply(projection); public ICamera ApplyViewPlane(ICamera camera) => _viewPlane.ApplyTo(camera); public void DrawPortalViewport(int width, int height, Matrix4x4 projection) => _tunnel.Draw(width, height, ApplyViewPlane(projection)); public void Dispose() => _tunnel.Dispose(); } /// /// Graphical-host orchestrator for Runtime's local F751/Position-correlated /// portal lifetime. Runtime owns sequence/destination/reveal authority; this /// update-thread adapter owns portal viewport activation, render-space aim, /// readiness preparation, placement callbacks, and LoginComplete presentation. /// internal sealed class LocalPlayerTeleportController : ILocalPlayerTeleportFramePhase, ILocalPlayerTeleportNetworkSink, AcDream.App.Interaction.ISelectionViewPlaneSource, IDisposable { private readonly RuntimeWorldTransitState _transit; private readonly ILocalPlayerTeleportAuthority _authority; private readonly ILocalPlayerTeleportInputLifetime _input; private readonly ILocalPlayerTeleportModeOperations _mode; private readonly ILocalPlayerTeleportStreamingOperations _streaming; private readonly WorldRevealCoordinator _worldReveal; private readonly ILocalPlayerTeleportPlacement _placement; private readonly ILocalPlayerTeleportSession _session; private readonly ILocalPlayerTeleportPresentation _presentation; private readonly RuntimeAcceptedPositionDriveController _acceptedPositionDrive; private uint _pendingCell; private Quaternion _pendingRotation = Quaternion.Identity; private long _pendingRevealGeneration; private RuntimeTeleportDestination _pendingDestination; private bool _hasPendingDestination; /// /// A1 review fix (2026-08-05): true once the canonical Runtime commit /// for THIS teleport lifetime has actually happened. See the class doc /// on for why this exists. /// private bool _placementCommitted; /// /// A1 review fix: true while a DeferredCell park is outstanding /// for the local player's one possible pending operation. See /// . /// private bool _awaitingDeferredWake; private float _holdSeconds; private long _lifetimeGeneration; private bool _disposed; public LocalPlayerTeleportController( ILocalPlayerTeleportAuthority authority, ILocalPlayerTeleportInputLifetime input, ILocalPlayerTeleportModeOperations mode, ILocalPlayerTeleportStreamingOperations streaming, RuntimeWorldTransitState transit, WorldRevealCoordinator worldReveal, ILocalPlayerTeleportPlacement placement, ILocalPlayerTeleportSession session, ILocalPlayerTeleportPresentation presentation, RuntimeAcceptedPositionDriveController acceptedPositionDrive) { _authority = authority ?? throw new ArgumentNullException(nameof(authority)); _input = input ?? throw new ArgumentNullException(nameof(input)); _mode = mode ?? throw new ArgumentNullException(nameof(mode)); _streaming = streaming ?? throw new ArgumentNullException(nameof(streaming)); _transit = transit ?? throw new ArgumentNullException(nameof(transit)); _worldReveal = worldReveal ?? throw new ArgumentNullException(nameof(worldReveal)); _placement = placement ?? throw new ArgumentNullException(nameof(placement)); _session = session ?? throw new ArgumentNullException(nameof(session)); _presentation = presentation ?? throw new ArgumentNullException(nameof(presentation)); _acceptedPositionDrive = acceptedPositionDrive ?? throw new ArgumentNullException(nameof(acceptedPositionDrive)); } public bool IsActive => _transit.IsTeleportActive; public bool IsPortalViewportVisible => _presentation.IsPortalViewportVisible; public uint ActiveDestinationCell => _transit.IsTeleportActive ? _pendingCell : 0u; public void OnTeleportStarted(uint sequence) { ThrowIfDisposed(); ushort teleportSequence = (ushort)sequence; if (!_authority.IsFreshStart(teleportSequence) || !_transit.CanQueueTeleportStart(teleportSequence)) { return; } long observedGeneration = _lifetimeGeneration; _input.EndMouseLook(); if (_lifetimeGeneration != observedGeneration) return; long resetGeneration = ResetTransit(clearSession: false); if (_lifetimeGeneration != resetGeneration) return; if (!_transit.TryQueueTeleportStart(teleportSequence)) return; TryActivatePendingPresentation(); Console.WriteLine($"live: teleport queued (seq={sequence})"); } public void OfferDestination( RuntimeTeleportDestination destination, bool teleportTimestampAdvanced) { ThrowIfDisposed(); _transit.OfferTeleportDestination( destination, teleportTimestampAdvanced); TryAimAcceptedDestination(); } public void Tick(float deltaSeconds) { ThrowIfDisposed(); TryActivatePendingPresentation(); TryAimAcceptedDestination(); if (!_transit.IsTeleportActive) return; long generation = _lifetimeGeneration; ushort sequence = _transit.ActiveTeleportSequence; if (!_mode.TryEnterPortalSpace() || !IsCurrentLifetime(generation, sequence) || _mode.Controller is null) { return; } bool haveDestination = _pendingCell != 0u; bool originReady = !_streaming.IsRecenterPending; bool dataReady = haveDestination && originReady && _worldReveal.Evaluate(_pendingCell).IsReady; if (!IsCurrentLifetime(generation, sequence)) return; // A1 review fix (2026-08-05, retail/architecture review): the // sequencer's Tunnel -> TunnelContinue transition // (TeleportAnimSequencer.cs:134-141) is unconditional and // irreversible the instant it observes `worldReady` true; by the // time a failed placement is discovered the stream has already left // Tunnel with no path back, and TeleportAnimSequencer itself is // untouched (stop condition 2 forbids sequencer timing changes). So // the boolean fed into the sequencer must never mean "the data is // ready" alone - it must mean "the canonical Runtime commit has // ALREADY happened", checked/attempted fresh every tick via // TryAdvancePortalCommit. This makes D-T5 row 2's "the NEXT Tick // re-attempts the Place edge" real: the sequencer simply never // leaves Tunnel while the commit keeps refusing, and by the time it // finally does leave Tunnel and fire Place, TryAdvancePortalCommit // has already made the Runtime side succeed - the Place-event // handler below only ever runs the presentation suffix. bool placementReady = dataReady && TryAdvancePortalCommit(sequence); if (!IsCurrentLifetime(generation, sequence)) return; if (haveDestination && !placementReady) _holdSeconds += deltaSeconds; _presentation.SetWaitCue( haveDestination && !placementReady && _worldReveal.ObserveWait( TimeSpan.FromSeconds(_holdSeconds))); var (_, events) = _presentation.Tick(deltaSeconds, placementReady); if (!IsCurrentLifetime(generation, sequence)) return; foreach (TeleportAnimEvent teleportEvent in events) { switch (teleportEvent) { case TeleportAnimEvent.Place: // TryAdvancePortalCommit above is the only path that // makes `placementReady` (and, with the REAL sequencer, // this event) true, so the canonical Runtime commit has // ALREADY succeeded by construction on that path - this // only runs the presentation suffix (D-T4). The // _placementCommitted re-check stays defensive: it is // the exact same shape of guard IsCurrentLifetime below // already applies to every other step of this case, for // a transit that goes stale between the gate above and // this line being reached. if (!_placementCommitted) return; // B7 review fix (2026-08-05): re-derived, not assumed - // if the reveal was cancelled/superseded in the window // between the commit above and this event being // processed, ObserveMaterialized below would refuse but // Place/the presentation suffix would already have run // against a reveal that is no longer current. Same // check TryExecuteCanonicalPortalPlacementCore itself // gates on; idempotent to repeat here. if (!_worldReveal.CanPlacePortalDestination( _pendingRevealGeneration, sequence, _pendingCell)) { return; } _placement.Place(_pendingRotation); if (!IsCurrentLifetime(generation, sequence)) return; _worldReveal.ObserveMaterialized( _pendingRevealGeneration, sequence, _pendingCell); if (!IsCurrentLifetime(generation, sequence)) return; break; case TeleportAnimEvent.PlayEnterSound: // Retail plays the enter cue as the animation BEGINS, before // the tunnel is visible. The sequencer has always emitted // this event; nothing consumed it until Campaign A. _presentation.PlayEnterCue(); if (!IsCurrentLifetime(generation, sequence)) return; break; case TeleportAnimEvent.EnterTunnel: _presentation.EnterTunnel(); if (!IsCurrentLifetime(generation, sequence)) return; break; case TeleportAnimEvent.PlayExitSound: // gmSmartBoxUI::UseTime @ 0x004D6E30 releases destination // cell blocking at the exact portal/world viewport swap. // LoginComplete remains one WorldFadeIn second later. _worldReveal.RevealWorldViewport(); if (!IsCurrentLifetime(generation, sequence)) return; _presentation.PlayExitCue(); if (!IsCurrentLifetime(generation, sequence)) return; _presentation.ExitTunnel(); if (!IsCurrentLifetime(generation, sequence)) return; break; case TeleportAnimEvent.FireLoginComplete: _mode.EnterWorld(); if (!IsCurrentLifetime(generation, sequence)) return; _session.SendLoginComplete(); if (!IsCurrentLifetime(generation, sequence)) return; _worldReveal.Complete(); if (!IsCurrentLifetime(generation, sequence)) return; ResetTransit(clearSession: false); return; default: // ClientUISystem sound-table enum playback remains outside // this already-accepted presentation extraction. break; } } _presentation.TickTunnel(deltaSeconds); } /// /// A1 review fix (2026-08-05): the one gate that decides whether the /// anim sequencer is allowed to see worldReady=true. Returns /// ONLY once the canonical Runtime commit for /// THIS teleport lifetime has actually happened — never speculatively, /// never optimistically. Three states: /// /// /// Already committed /// () — returns /// immediately, every subsequent Tick. /// A DeferredCell park is outstanding /// () — polls /// /// only to decide whether to re-attempt the Runtime call: Runtime's own /// Begin would just refuse a second overlapping attempt with /// Contention while a park is outstanding (the drive tracks at /// most one pending operation for the local player), so retrying blind /// would only add noise. B1 review fix (2026-08-05): once /// PendingCount returns to 0 the park is DONE, but "done" is not /// "committed" — the drive's own doc names a merge-time Forget /// (an ordinary ACE broadcast arriving mid-park) as the EXPECTED way a /// park resolves without committing, and A2's own abandon branches are /// a second way. The OLD code inferred commit from the empty slot /// alone; this now asks /// , /// which the drive latches ONLY inside a REAL /// ReconcileAndAcknowledgePortal call, keyed to this exact /// reveal generation/sequence. A "no" here is NOT a failure — it just /// means the park ended without placing, so /// clears and the method falls through to a fresh attempt below, /// safely (nothing is pending anymore). /// Neither — attempt the canonical placement fresh /// this tick. Committed latches /// ; DeferredCell latches /// ; every other status (Contention, /// Rejected, NotApplicable, or the transit no longer owning this /// reveal) is the D-T5 refusal shape — nothing mutates, and the SAME /// predicate retries automatically on the NEXT Tick, which is what /// makes D-T5 row 2's "the next Tick re-attempts the Place edge" /// mechanism real without ever touching /// . /// /// private bool TryAdvancePortalCommit(ushort sequence) { if (_placementCommitted) return true; if (_awaitingDeferredWake) { if (_acceptedPositionDrive.PendingCount != 0) return false; _awaitingDeferredWake = false; if (_acceptedPositionDrive.TryConsumePortalCommit( _pendingRevealGeneration, sequence)) { _placementCommitted = true; return true; } // The park ended without placing (Forgotten, or abandoned by // A2's re-validation). Fall through to the fresh-attempt path // below in this SAME call — nothing is pending, so it is safe. } if (!_worldReveal.CanPlacePortalDestination( _pendingRevealGeneration, sequence, _pendingCell)) { PhysicsDiagnostics.LogTeleport( "REFUSED", _pendingCell, "cause=stale-reveal"); // R8 residual fix (2026-08-05): this refusal previously only // logged through PhysicsDiagnostics.LogTeleport, gated by the // DIFFERENT ACDREAM_PROBE_TELEPORT flag — invisible under // ACDREAM_PROBE_LOCAL_TELEPORT, the gate the rest of this // route's arrival/commit lines use. No placement was attempted, // so there is no resolved cell/leash/autorun fact to report. PhysicsDiagnostics.LogLocalTeleportArrival( cause: "stale-reveal", placementStatus: "Refused", portalGeneration: _pendingRevealGeneration, teleportSequence: sequence, destinationCell: _pendingCell, resolvedCell: 0u, hookTailRan: false, leashArmed: false, autorunCancelled: false); return false; } RuntimeAcceptedPositionExecutionStatus status = TryExecuteCanonicalPortalPlacementCore(sequence); switch (status) { case RuntimeAcceptedPositionExecutionStatus.Committed: _placementCommitted = true; return true; case RuntimeAcceptedPositionExecutionStatus.DeferredCell: _awaitingDeferredWake = true; return false; default: return false; } } /// /// C4 route 3 (D-T1/D-T2): builds the producer's /// from live transit facts /// and drives the canonical Runtime portal arm. No new /// exposure is needed — the host /// token is RE-DERIVED through the transit owner's idempotent /// TryRegisterHostProjection (the same generation+cell returns /// the token already /// registered at Aim time; a stale generation, wrong cell, cancelled, or /// completed reveal refuses), which makes a superseded token unobtainable /// by construction. /// /// /// The destination itself is — the /// value captured at Aim time — and NOT a /// fresh _transit.TryGetAcceptedTeleportDestination read. /// atomically /// CONSUMES the transit's one accepted-destination slot the instant Aim /// claims the reveal generation (it clears /// _hasAcceptedDestination so a stale destination can never be /// re-claimed by a later portal) — by Place time that slot is already /// empty, so re-querying it here always fails. This mirrors why /// // /// are themselves Aim-time /// snapshots rather than live transit reads. /// /// /// /// A9 review fix (2026-08-05): is /// 's OWN /// , not the /// transit's separately-tracked ActiveTeleportSequence the caller /// otherwise threads through — one source for the fact this method's /// authority carries, asserted equal to the caller's copy so the two /// can never silently diverge. /// /// private RuntimeAcceptedPositionExecutionStatus TryExecuteCanonicalPortalPlacementCore(ushort sequence) { System.Diagnostics.Debug.Assert( !_hasPendingDestination || _pendingDestination.TeleportSequence == sequence, "The transit's active sequence and the Aim-time destination's " + "own sequence must never diverge (A9)."); if (!_hasPendingDestination || !_transit.TryRegisterHostProjection( _pendingRevealGeneration, _pendingCell, out RuntimeWorldHostProjectionToken hostToken)) { PhysicsDiagnostics.LogTeleport( "REFUSED", _pendingCell, "cause=host-token-unavailable"); // R8 residual fix (2026-08-05): same rationale as the // stale-reveal refusal above — route through // LogLocalTeleportArrival too, so ACDREAM_PROBE_LOCAL_TELEPORT // alone is enough to see every App-side refusal cause. PhysicsDiagnostics.LogLocalTeleportArrival( cause: "host-token-unavailable", placementStatus: "Refused", portalGeneration: _pendingRevealGeneration, teleportSequence: sequence, destinationCell: _pendingCell, resolvedCell: 0u, hookTailRan: false, leashArmed: false, autorunCancelled: false); return RuntimeAcceptedPositionExecutionStatus.Rejected; } RuntimeTeleportDestination destination = _pendingDestination; var portal = new RuntimePortalPlacementAuthority( Present: true, RevealGeneration: _pendingRevealGeneration, TeleportSequence: destination.TeleportSequence, Projection: hostToken); return _acceptedPositionDrive.TryExecuteAcceptedPortalArrival( destination, portal); } public void ResetSession() { ThrowIfDisposed(); ResetTransit( clearSession: true, resetCanonicalTransit: true); } public void ResetGenerationPresentation() { ThrowIfDisposed(); ResetTransit( clearSession: true, resetCanonicalTransit: false); } public Matrix4x4 ApplyViewPlane(Matrix4x4 projection) => _presentation.ApplyViewPlane(projection); public ICamera ApplyViewPlane(ICamera camera) => _presentation.ApplyViewPlane(camera); public void DrawPortalViewport(int width, int height, Matrix4x4 projection) => _presentation.DrawPortalViewport(width, height, projection); private void TryActivatePendingPresentation() { if (!_transit.HasPendingTeleportStart) return; long generation = _lifetimeGeneration; if (!_mode.TryEnterPortalSpace() || _lifetimeGeneration != generation || !_transit.HasPendingTeleportStart) { return; } _holdSeconds = 0f; _presentation.Begin(_mode.Projection); if (_lifetimeGeneration != generation || !_transit.HasPendingTeleportStart) { return; } if (!_transit.ActivateQueuedTeleport()) return; TryAimAcceptedDestination(); Console.WriteLine( $"live: teleport presentation started " + $"(seq={_transit.ActiveTeleportSequence})"); } private void TryAimAcceptedDestination() { if (!_transit.TryGetAcceptedTeleportDestination( out RuntimeTeleportDestination destination)) { return; } long generation = _lifetimeGeneration; ushort sequence = _transit.ActiveTeleportSequence; PlayerMovementController? controller = _mode.Controller; if (controller is null) { if (!_mode.TryEnterPortalSpace() || !IsCurrentLifetime(generation, sequence)) { return; } controller = _mode.Controller; if (controller is null) return; } if (!AimDestination(destination, controller, generation, sequence)) return; } private bool AimDestination( RuntimeTeleportDestination destination, PlayerMovementController controller, long generation, ushort sequence) { Position position = destination.Position; int landblockX = (int)((position.ObjCellId >> 24) & 0xFFu); int landblockY = (int)((position.ObjCellId >> 16) & 0xFFu); uint streamingOriginLandblockId = StreamingRegion.EncodeLandblockId( _streaming.CenterX, _streaming.CenterY); var origin = new Vector3( (landblockX - _streaming.CenterX) * 192f, (landblockY - _streaming.CenterY) * 192f, 0f); Vector3 translated = position.Frame.Origin + origin; TeleportLandblockTransition transition = TeleportLandblockTransition.Classify( controller.CellId, position.ObjCellId, streamingOriginLandblockId); int oldX = (int)((transition.SourceLandblockId >> 24) & 0xFFu); int oldY = (int)((transition.SourceLandblockId >> 16) & 0xFFu); Console.WriteLine( $"live: teleport arrival - old lb=({oldX},{oldY}) " + $"new lb=({landblockX},{landblockY}) " + $"dist={Vector3.Distance(translated, controller.Position):F1}"); // Retail SmartBox enters blocking_for_cells before old-world object, // physics, landscape, and ambient owners may advance again. Begin the // reveal generation before a recenter can start detaching that world. if (!_worldReveal.TryBeginPortal( sequence, position.ObjCellId, out long revealGeneration)) { return false; } _pendingRevealGeneration = revealGeneration; if (!IsCurrentLifetime(generation, sequence)) return false; if (transition.ChangesStreamingCenter) { bool isSealedDungeon = _streaming.IsSealedDungeon( position.ObjCellId); if (!IsCurrentLifetime(generation, sequence)) return false; _streaming.BeginRecenter( landblockX, landblockY, isSealedDungeon); if (!IsCurrentLifetime(generation, sequence)) return false; } // C4 route 3: the App-frame-translated `translated`/`worldPosition` // vector is no longer carried past this point — the canonical // portal arm resolves the placement through Runtime's OWN world // frame (resolveWorldOffsetFromRuntimeFrame: true), using the // cell-local `destination` Position captured HERE rather than an // App-translated snapshot (trap T4). It must be captured here and // NOT re-read from the transit at the Place edge: // _worldReveal.TryBeginPortal (above) drives // RuntimeWorldTransitState.TryBeginPortalReveal, which atomically // CONSUMES the transit's one accepted-destination slot the instant // it claims this reveal generation — a later // TryGetAcceptedTeleportDestination call always finds it empty. _pendingRotation = position.Frame.Orientation; _pendingCell = position.ObjCellId; _pendingDestination = destination; _hasPendingDestination = true; _holdSeconds = 0f; PhysicsDiagnostics.LogTeleport( "AIM", position.ObjCellId, $"seq={destination.TeleportSequence} lb={landblockX},{landblockY} " + $"indoor={((position.ObjCellId & 0xFFFFu) >= 0x0100u)} " + $"playerCross={transition.CrossesLandblock} " + $"centerChange={transition.ChangesStreamingCenter}"); return true; } private long ResetTransit( bool clearSession, bool resetCanonicalTransit = false) { long generation = checked(++_lifetimeGeneration); _pendingCell = 0u; _pendingRotation = Quaternion.Identity; _pendingRevealGeneration = 0; _pendingDestination = default; _hasPendingDestination = false; _placementCommitted = false; _awaitingDeferredWake = false; _holdSeconds = 0f; _streaming.ResetRecenter(clearSession); if (_lifetimeGeneration != generation) return generation; if (clearSession) { if (resetCanonicalTransit) _worldReveal.ResetSession(); else _worldReveal.ResetHostSession(); } else { _transit.EndTeleport(); _worldReveal.Cancel(); } if (_lifetimeGeneration != generation) return generation; _presentation.Reset(); if (_lifetimeGeneration != generation) return generation; return generation; } private bool IsCurrentLifetime(long generation, ushort sequence) => _lifetimeGeneration == generation && _transit.IsTeleportActive && _transit.ActiveTeleportSequence == sequence; private void ThrowIfDisposed() => ObjectDisposedException.ThrowIf(_disposed, this); public void Dispose() { if (_disposed) return; _presentation.Dispose(); _disposed = true; } }