Detach old-world spatial ownership atomically, prioritize destination retirement dependencies, and reveal the viewport at the retail transition edge. Give private paperdoll views independent mesh ownership and retain dormant ACE entities so portal revisits preserve server objects without extending active GPU lifetimes.
105 lines
4.8 KiB
Markdown
105 lines
4.8 KiB
Markdown
# Portal regression closeout — 2026-07-25
|
|
|
|
## Scope
|
|
|
|
The first connected retained-scene visual pass reported:
|
|
|
|
1. portal transit remained in the tunnel too long;
|
|
2. a clear/void interval appeared between tunnel exit and destination world;
|
|
3. the inventory paperdoll disappeared and rebuilt during transit;
|
|
4. doors, signs, portals, NPCs, and other server-spawned objects disappeared
|
|
after repeated portal travel.
|
|
|
|
This note records the root causes and the accepted correction. It does not
|
|
reduce world radius, texture quality, particles, readiness, or retail
|
|
presentation.
|
|
|
|
## Retail and protocol anchors
|
|
|
|
- `gmSmartBoxUI::UseTime @ 0x004D6E30`: the
|
|
`TunnelFadeOut -> WorldFadeIn` edge hides the portal viewport, shows the
|
|
world viewport, releases cell blocking, and starts the final one-second
|
|
WorldFadeIn state.
|
|
- The later WorldFadeIn completion sends LoginComplete and ends logical
|
|
teleport state. Viewport release and protocol completion are distinct.
|
|
- `gmPaperDollUI::RedressCreature @ 0x004A3BC0` creates the private inventory
|
|
object only when absent and a SmartBox player is available; temporary player
|
|
absence does not delete an existing private object.
|
|
- `gmPaperDollUI::~gmPaperDollUI @ 0x004A3590` owns final private-object
|
|
destruction.
|
|
- `CPhysicsObj::prepare_to_leave_visibility @ 0x00511F40`,
|
|
`CObjectMaint::AddObjectToBeDestroyed @ 0x00508F70`, and
|
|
`CObjectMaint::UseTime @ 0x005089B0` define retail's delayed active-object
|
|
destruction.
|
|
- `CPhysicsObj::set_hidden @ 0x00514C60` plays typed UnHide at intensity 1
|
|
when materializing. The destination purple/pink effect is DAT-driven retail
|
|
behavior, not a generic exit effect to suppress.
|
|
|
|
## Root causes and corrections
|
|
|
|
### Shared-origin retirement head-of-line blocking
|
|
|
|
The 25x25 old spatial window was detached as hundreds of independently metered
|
|
operations. No intermediate subset was observable because the complete old
|
|
generation was already quiesced, but the shared origin could not change until
|
|
all admissions finished.
|
|
|
|
`GpuWorldState.DetachAllForOriginRecenter` now performs one atomic spatial
|
|
generation swap and returns exact per-landblock teardown receipts. Deferred
|
|
resource release remains budgeted. A destination publication waits only on an
|
|
older receipt for that same landblock; that exact receipt may advance ahead of
|
|
unrelated cleanup while the remaining retirement FIFO order stays unchanged.
|
|
|
|
### Destination scheduling and upload utilization
|
|
|
|
Near worker jobs, retained publication receipts, mesh uploads, and composite
|
|
uploads could each serialize destination work behind unrelated work. The
|
|
destination neighborhood is now ordered first at worker and publication
|
|
boundaries. When a destination completion actually exists, ordinary
|
|
publication is temporarily preempted; when it does not exist or failed,
|
|
ordinary Near/Far work continues under the same budget.
|
|
|
|
`WorldRevealRenderResourceScheduler` owns an exact reveal-generation profile:
|
|
|
|
- mesh item count: 8 -> 64;
|
|
- composite item count: 16 -> 64;
|
|
- upload bytes: unchanged at 8 MiB;
|
|
- array allocation, mipmap, buffer upload/allocation/copy, and new-resource
|
|
ceilings: unchanged.
|
|
|
|
The profile ends at the portal/world viewport swap. The complete canonical
|
|
render/composite/collision readiness predicate remains mandatory.
|
|
|
|
### Private retained-UI ownership
|
|
|
|
The paperdoll and creature appraisal used shared mesh data without independent
|
|
references, so old-world retirement could evict their meshes. Both now use
|
|
`SyntheticEntityMeshReferenceOwner`, with transactional acquisition and
|
|
retryable release. `PaperdollFramePresenter` retains the last successful
|
|
private object across temporary SmartBox unavailability and equivalent
|
|
appearance refreshes; character-session reset is the explicit clear edge.
|
|
|
|
### ACE KnownObjects revisit
|
|
|
|
The active 25-second liveness teardown was correct for resource reclamation,
|
|
but ACE may keep the GUID in `KnownObjects` and omit CreateObject when the
|
|
client revisits that landblock. Deleting acdream's final accepted spawn
|
|
snapshot therefore made the object permanently absent.
|
|
|
|
`DormantLiveEntityStore` retains only the accepted data snapshot after every
|
|
active owner is destroyed. Landblock residency re-enters ordinary hydration
|
|
with the retained timestamp gate. Exact F747, a newer instance generation, and
|
|
session reset remove the dormant snapshot. Dormant objects own no physics,
|
|
animation, script, effect, light, audio, render, collision, or per-frame work.
|
|
This ACE adaptation remains explicit in divergence AP-69.
|
|
|
|
## Gates
|
|
|
|
- Focused portal/retirement/reveal/private-viewport/dormant tests: green.
|
|
- Complete App Release suite: 3,813 passed / 3 skipped.
|
|
- Release solution build: green with zero warnings.
|
|
- Complete Release solution suite: 8,322 passed / 5 skipped.
|
|
- User connected visual gate:
|
|
- paperdoll remains visible;
|
|
- portal transit is materially faster;
|
|
- server-spawned objects remain after repeated travel.
|