feat(vfx): port retail hidden and teleport presentation
Preserve canonical live-object ownership across Hidden transitions and remote teleport placement so effects, collision, streaming, and targeting remain synchronized.
This commit is contained in:
parent
a51ebc66e9
commit
1e98d81448
46 changed files with 4883 additions and 127 deletions
|
|
@ -181,6 +181,14 @@ src/
|
|||
AcDream.App/ Layer 1 + Layer 4 wiring
|
||||
Physics/
|
||||
ProjectileController.cs -> live-record projectile orchestration/corrections
|
||||
RemotePhysicsUpdater.cs -> ordinary/Hidden remote narrow-tick integration
|
||||
RemoteTeleportController.cs -> incarnation-scoped loaded/pending placement owner
|
||||
RemoteTeleportHook.cs -> ordered retail teleport teardown seam
|
||||
RemoteTeleportPlacement.cs -> collision-seated SetPosition transition commit
|
||||
World/
|
||||
LiveEntityRuntime.cs -> canonical logical identity/state/spatial ownership
|
||||
LiveEntityPresentationController.cs -> Hidden/NoDraw/effect/collision presentation
|
||||
LiveEntityTeardown.cs -> failure-isolated multi-owner lifecycle drain
|
||||
Rendering/
|
||||
GameWindow.cs -> still owns too much runtime wiring
|
||||
TerrainRenderer.cs -> done
|
||||
|
|
@ -248,6 +256,36 @@ What exists and is active:
|
|||
owns the frame;
|
||||
delete, generation replacement, pickup/parent leave-world, and session reset
|
||||
use `LiveEntityRuntime`'s normal lifecycle and never create a second GUID map.
|
||||
- `RemoteTeleportController` owns the placement half of a fresh remote
|
||||
teleport after `RemoteTeleportHook` has torn down movement/target state. It
|
||||
collision-seats loaded destinations through `RemoteTeleportPlacement`; an
|
||||
unloaded destination retains one generation- and PositionSequence-scoped
|
||||
pending placement and resolves the latest accepted frame when that same
|
||||
projection becomes visible. It neither owns GUID identity nor reconstructs
|
||||
an entity. A placement failure after hydration restores the captured source
|
||||
frame/cell/contact rather than leaving a visible collisionless projection;
|
||||
source-resident shadows restore immediately, while an unloaded source
|
||||
delegates one incarnation-scoped restore to
|
||||
`LiveEntityPresentationController`, shared with Hidden/UnHide. A newer
|
||||
placement transfers that marker into an explicit active-placement generation
|
||||
before rebucketing even while Hidden. That generation suppresses every
|
||||
intervening Hidden/UnHide and projection restore until the controller reaches
|
||||
a stable result, then it either restores after collision seating, re-defers
|
||||
its rollback source, or hands a Hidden result back for UnHide. The typed
|
||||
`ILiveEntityRemotePlacementRuntime` seam permits a same-incarnation wrapper
|
||||
rebind only around the canonical body; pending placement adopts that wrapper
|
||||
before hydration and cannot silently lose ownership. Clearing a motion or
|
||||
projectile component retains the incarnation's body/contract identity until
|
||||
logical teardown. The production wrapper exposes an immutable body, while
|
||||
hydration defensively validates arbitrary implementations against the record
|
||||
and rolls the retained body back on mismatch. Runtime binding snapshots the
|
||||
interface Body getter once for validation, assignment, and state mutation.
|
||||
`GpuWorldState`
|
||||
rebuckets atomically and commits spatial visibility before draining its
|
||||
transition FIFO; `LiveEntityRuntime` rejects delayed duplicate edges. A
|
||||
rollback/rebucket inside a visibility observer therefore cannot expose a
|
||||
remove/add pulse, leave stale final visibility, or reorder the final
|
||||
presentation edge.
|
||||
- `BSPQuery` contains the partial retail-style BSP collision dispatcher used by
|
||||
the transition path.
|
||||
- `TransitionTypes` carries `SpherePath`, `CollisionInfo`, `ObjectInfo`,
|
||||
|
|
@ -296,7 +334,15 @@ owns spatial buckets only: register/rebucket/unregister are separate operations,
|
|||
and landblock reloads reuse the same `WorldEntity` without replaying renderer or
|
||||
script creation. Its canonical materialized view remains stable across pending
|
||||
landblocks, while a separate visible-only view feeds radar, picking, status, and
|
||||
targeting. Pickup/parent leave-world clears cell membership and pauses root
|
||||
targeting. Raw server PhysicsState and the final state produced by retail's
|
||||
ordered Lighting/NoDraw/Hidden side effects are stored separately.
|
||||
`LiveEntityPresentationController` drains those accepted transitions only after
|
||||
the renderer/effect owner is ready: Hidden suppresses the retained root's mesh,
|
||||
collision, interaction, radar, and target eligibility while preserving the
|
||||
logical record, scripts, particles, lights, full cell, and local identity.
|
||||
Direct attached children receive retail's NoDraw mutation, and typed
|
||||
Hidden/UnHide effects resolve through the live PhysicsScriptTable.
|
||||
Pickup/parent leave-world clears cell membership and pauses root
|
||||
movement/animation without destroying retained owners. `GameWindow` retains
|
||||
storage-free typed views while its large feature loops are extracted.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue