After a teleport-OUT the per-frame avatar-sync (GameWindow ~:8018) called GpuWorldState.RelocateEntity with the player controller's cell — which stays the FROZEN SOURCE cell until PlaceTeleportArrival materializes the destination. So mid-transit it dragged the avatar (which the teleport's rescue/re-inject had correctly placed at the destination center) back into the now-UNLOADED source landblock's pending bucket, where nothing recovers it (RelocateEntity only scans _loaded). Net: the avatar vanished after teleporting out and stayed gone. Fix: skip the per-frame relocate while the player is in PortalSpace. The teleport machinery (DrainRescued + PlaceTeleportArrival) owns the avatar's landblock during transit; per-frame relocation resumes at FireLoginComplete (InWorld). Live-verified with a new env-gated avatar-lifecycle probe (ACDREAM_PROBE_ENT / EntityVanishProbe; [ent] draw-set transitions + [dyn] cull check): pre-fix the trace showed `[ent] APPEND lb=0x0007FFFF(source) -> PENDING -> DRAWSET ABSENT` never recovering; post-fix every teleport goes RESCUE -> ABSENT -> APPEND(destination) -> PRESENT and stays drawn (4 teleports incl. to Holtburg, session ended PRESENT). Suites green: Core 1568(+2 skip), App 468(+2 skip), UI 425, Net 317. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
49 lines
2 KiB
C#
49 lines
2 KiB
C#
using System;
|
|
|
|
namespace AcDream.App.Streaming;
|
|
|
|
/// <summary>
|
|
/// TEMP diagnostic (#138-B avatar-vanish). Env-gated (<c>ACDREAM_PROBE_ENT=1</c>)
|
|
/// trace of the persistent player entity across teleport streaming churn:
|
|
/// whether it is present in the render draw-DATA (<see cref="GpuWorldState"/>
|
|
/// flat view) and whether it survives the dynamics CULL
|
|
/// (<c>RetailPViewRenderer.DrawDynamicsLast</c>).
|
|
///
|
|
/// <para>The two halves answer the decisive question: is the avatar
|
|
/// "missing for a moment" because it is <b>absent from the draw set</b>
|
|
/// (re-injected into the pending bucket while its landblock re-streams), or
|
|
/// because it is <b>present but culled</b> (in the dynamics list, dropped by
|
|
/// the outside-stage / viewcone gate)?</para>
|
|
///
|
|
/// <para>STRIP once #138-B is root-caused (throwaway, like the dense-town FPS
|
|
/// apparatus). Observation-only — emits no behavior change.</para>
|
|
/// </summary>
|
|
internal static class EntityVanishProbe
|
|
{
|
|
public static readonly bool Enabled =
|
|
Environment.GetEnvironmentVariable("ACDREAM_PROBE_ENT") == "1";
|
|
|
|
/// <summary>Player server guid, set once at world entry so the draw-side
|
|
/// <c>[dyn]</c> line can single out the avatar without plumbing the guid
|
|
/// through the render stack.</summary>
|
|
public static uint PlayerGuid;
|
|
|
|
public static void Log(string msg)
|
|
{
|
|
if (Enabled) Console.WriteLine(msg);
|
|
}
|
|
|
|
private static string _lastPlayerDyn = "";
|
|
|
|
/// <summary>Emit a <c>[dyn] player</c> line only when the outcome string
|
|
/// changes — a stationary, drawn avatar must not spam one line per frame
|
|
/// (that console+Tee I/O would itself depress FPS and bury the signal).
|
|
/// Fires on cell change or DRAWN↔CULLED transition.</summary>
|
|
public static void LogPlayerDynOnChange(string status)
|
|
{
|
|
if (!Enabled) return;
|
|
if (status == _lastPlayerDyn) return;
|
|
_lastPlayerDyn = status;
|
|
Console.WriteLine("[dyn] player " + status);
|
|
}
|
|
}
|