fix(streaming): #138 — rescue persistent entities from the pending bucket on unload
GpuWorldState.RemoveLandblock rescued persistent entities (the player) only from the _loaded list, silently dropping one sitting in the _pendingByLandblock bucket. The player is re-injected via AppendLiveEntity every frame; right after a teleport its destination landblock has not streamed in yet, so the player lands in the pending bucket — and if that landblock is then unloaded during the streaming churn, the persistent entry was dropped, violating the "persistent therefore survives unload" contract. Leading candidate for the #138 "own avatar vanishes after a couple round-trips" symptom (cumulative; needs user visual confirm). Fix: scan the pending bucket for persistent guids and rescue them too, so DrainRescued re-parks them at the next valid landblock. Provable correctness fix with a deterministic test (rescue-from-pending plus a negative for non-persistent). Core tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bf66fb4123
commit
0a5f91b6fe
2 changed files with 67 additions and 0 deletions
|
|
@ -315,6 +315,26 @@ public sealed class GpuWorldState
|
|||
}
|
||||
}
|
||||
|
||||
// #138 (secondary): rescue persistent entities sitting in the PENDING
|
||||
// bucket too, not just the loaded list. The player is re-injected via
|
||||
// AppendLiveEntity into its current landblock every frame
|
||||
// (GameWindow's DrainRescued loop); right after a teleport that
|
||||
// landblock often hasn't streamed in yet, so the player lands in
|
||||
// _pendingByLandblock. If that same landblock is then unloaded (a
|
||||
// streaming churn / re-teleport before it finishes loading), the
|
||||
// pending entry was silently dropped here — violating the
|
||||
// "persistent ⇒ survives unload" contract and making the avatar
|
||||
// vanish after a couple round-trips. Rescue them so DrainRescued
|
||||
// re-parks them at the next valid landblock.
|
||||
if (_pendingByLandblock.TryGetValue(landblockId, out var pendingForLb))
|
||||
{
|
||||
foreach (var entity in pendingForLb)
|
||||
{
|
||||
if (entity.ServerGuid != 0 && _persistentGuids.Contains(entity.ServerGuid))
|
||||
_persistentRescued.Add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
_pendingByLandblock.Remove(landblockId);
|
||||
_aabbs.Remove(landblockId);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue