feat(runtime): own SetPosition collision reports
This commit is contained in:
parent
ec627c13a2
commit
237d1184d2
19 changed files with 3744 additions and 103 deletions
|
|
@ -252,15 +252,21 @@ prepared-mover caching, and caps synchronous Scatter/RandomScatter work at 64
|
|||
attempts; this keeps valid authored retail request shapes while rejecting a
|
||||
hostile `uint.MaxValue` loop at the authority boundary.
|
||||
|
||||
Two boundaries intentionally remain open for 4B2:
|
||||
One authority boundary intentionally remains open for 4B2:
|
||||
|
||||
- `RuntimePortalPlacementAuthority` validates immutable token shape only;
|
||||
4B2 must bind it to active `RuntimeWorldTransitState` generation, teleport
|
||||
sequence, destination, and host acknowledgement before reveal.
|
||||
- Runtime applies the canonical collision-report state but fails the handler
|
||||
return closed. Retail returns report/track success, not collision presence;
|
||||
the per-object report/tracking owner required for that boolean is not yet in
|
||||
Runtime, and the former environment/object-presence guess is forbidden.
|
||||
|
||||
The former collision-report boundary is closed by
|
||||
`RuntimeCollisionReportingState`. Runtime now owns retail's exact-key object
|
||||
contact table, environment latch, strict ordinary/ethereal expiry, force-end,
|
||||
static and `ReportAsEnvironment` routing, reciprocal callback eligibility,
|
||||
missile-state clearing, ordered reentrant dispatch, and the report-result
|
||||
boolean which distinguishes placement `Collided` from `NoValidPosition`.
|
||||
Successful SetPosition commits reporting after Contact/OnWalkable and ground
|
||||
callbacks but before its single physical response and shadow reflood. See
|
||||
`docs/research/2026-07-31-runtime-set-position-collision-reporting.md`.
|
||||
|
||||
### Slice 4B2 checkpoint 1 — public dormant host seam
|
||||
|
||||
|
|
@ -284,13 +290,13 @@ preparation followed by one validated atomic body/controller publication.
|
|||
Either choice belongs to the all-route ownership cutover, not this narrow
|
||||
dormant-seam checkpoint.
|
||||
|
||||
This is still a deliberately non-activating checkpoint. Production spawn,
|
||||
This remains a deliberately non-activating checkpoint. Production spawn,
|
||||
Position, projectile, drop/pickup/parent, and portal routes do not submit to
|
||||
the dormant SetPosition owner yet. The cutover remains blocked on the real
|
||||
retail collision report/tracking return, exact ordered Setup spheres/scale/
|
||||
step heights/flags/cell-local preparation, presentation-only rebucketing, and
|
||||
placement-prefix quiescence before collision retirement. AP-1 and AD-1 remain
|
||||
open until those prerequisites and every production route land together.
|
||||
the dormant SetPosition owner yet. The cutover remains blocked on exact
|
||||
ordered Setup spheres/scale/step heights/flags/cell-local preparation,
|
||||
presentation-only rebucketing, and placement-prefix quiescence before
|
||||
collision retirement. AP-1 and AD-1 remain open until those prerequisites and
|
||||
every production route land together.
|
||||
|
||||
AD-2 remains the explicit async adaptation: collision readiness can publish in
|
||||
a different frame from retail's blocking load. A failed wake is safely re-
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
# Remaining physics-divergence campaign handoff — 2026-07-31
|
||||
|
||||
> **Checkpoint 2 update:** Slice 4B2 prerequisite A, Runtime SetPosition
|
||||
> collision-report ownership, is implemented in the next checkpoint. Continue
|
||||
> with the dedicated
|
||||
> [`runtime SetPosition collision-reporting handoff`](2026-07-31-runtime-set-position-collision-reporting-handoff.md),
|
||||
> not the prerequisite-A instructions preserved below as historical context.
|
||||
|
||||
## Purpose and stopping point
|
||||
|
||||
This is the deliberate handoff boundary requested after placement Slice 4B2
|
||||
|
|
|
|||
|
|
@ -0,0 +1,243 @@
|
|||
# Runtime SetPosition collision-report ownership handoff - 2026-07-31
|
||||
|
||||
## Purpose and exact stopping point
|
||||
|
||||
This handoff records placement Slice 4B2 checkpoint 2: the isolated Runtime
|
||||
owner for retail SetPosition collision tracking and report-result semantics.
|
||||
The checkpoint intentionally stops before authored mover preparation, shared
|
||||
local-controller body publication, graphical/headless placement projection,
|
||||
collision-prefix quiescence, or any production SetPosition route cutover.
|
||||
|
||||
Production behavior is therefore unchanged by this checkpoint. The new owner
|
||||
is populated only by the dormant `RuntimeSetPositionState` and focused tests.
|
||||
AP-1 and AD-1 remain narrowed/open; AP-22 and AD-10 remain open.
|
||||
|
||||
## Exact workspace
|
||||
|
||||
- Worktree: `C:\Users\erikn\.codex\worktrees\af5e\acdream`
|
||||
- Branch: `codex/port-claude-agents`
|
||||
- Starting checkpoint: `ec627c13`
|
||||
(`docs(physics): hand off remaining divergence campaign`)
|
||||
- This handoff belongs to the same behavior commit as the implementation.
|
||||
- No upstream is configured for this worktree branch.
|
||||
- Remotes:
|
||||
- `origin`: `https://git.snakedesert.se/erik/acdream.git`
|
||||
- `github`: `git@github.com:eriknihlen/acdream.git`
|
||||
|
||||
Continue in this worktree unless the user explicitly requests otherwise.
|
||||
`AGENTS.md` has an unrelated pre-existing content diff and must not be staged,
|
||||
restored, or rewritten as part of this checkpoint. Several other paths report
|
||||
line-ending/stat noise without a content diff; stage only the exact paths
|
||||
listed in the final commit.
|
||||
|
||||
## Retail oracle
|
||||
|
||||
The complete readable oracle is
|
||||
[`2026-07-31-runtime-set-position-collision-reporting.md`](2026-07-31-runtime-set-position-collision-reporting.md).
|
||||
The named-retail anchors are:
|
||||
|
||||
- `CPhysicsObj::report_object_collision_end` `0x00510A90`
|
||||
- `CPhysicsObj::report_environment_collision` `0x00512FC0`
|
||||
- `CPhysicsObj::report_object_collision` `0x00513060`
|
||||
- `CPhysicsObj::track_object_collision` `0x00513F10`
|
||||
- `CPhysicsObj::report_collision_start` `0x00513FD0`
|
||||
- `CPhysicsObj::report_collision_end` `0x00514620`
|
||||
- `CPhysicsObj::handle_all_collisions` `0x00514780`
|
||||
- successful `CPhysicsObj::SetPositionInternal(CTransition const*)`
|
||||
`0x00515330`
|
||||
- `CPhysicsObj::leave_world` `0x005155A0`
|
||||
- placement failure in `CPhysicsObj::SetPositionInternal` `0x00515BD0`
|
||||
|
||||
The source is `docs/research/named-retail/acclient_2013_pseudo_c.txt`; the
|
||||
struct authority is `docs/research/named-retail/acclient.h`.
|
||||
|
||||
## What this checkpoint implements
|
||||
|
||||
`RuntimeCollisionReportingState` is the sole per-session owner of:
|
||||
|
||||
- one environment-collision latch per exact `RuntimeEntityKey`;
|
||||
- one ordered object-contact table per exact owner incarnation;
|
||||
- retained peer server GUID, touch time, and ethereal-at-touch state;
|
||||
- static and `ReportAsEnvironment` routing;
|
||||
- asymmetric `IgnoreCollisions` and reciprocal `ReportCollisions` eligibility;
|
||||
- strict ordinary `age > 1.0` and ethereal `age > 0.0` expiry;
|
||||
- force-end-before-callback mutation for reentrant safety;
|
||||
- missing-peer self-only end reports without resolving a later GUID reuse;
|
||||
- exact `Missile | AlignPath | PathClipped` clearing on the canonical record,
|
||||
borrowed body, retained shadow state, and mutation version;
|
||||
- a monotonic immutable report FIFO with observer-failure isolation;
|
||||
- the retail callback-eligibility boolean used by failed placement to choose
|
||||
`Collided` versus `NoValidPosition`;
|
||||
- terminal ownership diagnostics and deterministic session/disposal cleanup.
|
||||
|
||||
Successful dormant SetPosition commits contact, water/walkable and ground
|
||||
edges first, runs reporting next, applies physical response once, and then
|
||||
refloods the shadow. An intervening Vector or Movement update suppresses only
|
||||
the stale physical response; it does not erase collision tracking or reports.
|
||||
Failed placement always supplies retail's `previousContact = false` and
|
||||
`previousOnWalkable = false`, reports once, applies its one response pass, and
|
||||
maps the report result exactly.
|
||||
|
||||
Hidden, teleport/withdrawal, deletion, session reset, and disposal use distinct
|
||||
lifetime edges. Leaving the world force-ends the departing owner's table but
|
||||
retains its environment latch and incoming peer records. Destruction then
|
||||
forgets only the departing owner state. Other owners retain exact-key contacts
|
||||
until their own expiry/force pass and can emit a missing-target end using the
|
||||
preserved server GUID. Hidden and session-clear paths force-end while the old
|
||||
report flags and bodies are still eligible, before state/reset teardown.
|
||||
|
||||
## Architectural boundaries
|
||||
|
||||
- Runtime owns all canonical collision-report state and report-result logic.
|
||||
- Core exposes only the exact successful SetPosition ordering seam and the
|
||||
retained-shadow collision identity required by Runtime.
|
||||
- App and Headless gain no report table, queue, heuristic, or production
|
||||
placement consumer.
|
||||
- Reports are presentation-free and keyed by exact Runtime identity.
|
||||
- Network/update callbacks may re-enter, but every later mutation revalidates
|
||||
current identity, body, and the relevant authority version.
|
||||
- Physical-response velocity authority is deliberately separate from report
|
||||
authority, matching retail's ordering without overwriting a newer vector.
|
||||
|
||||
## Validation and independent review
|
||||
|
||||
The saved final diff passed:
|
||||
|
||||
- combined focused Runtime collision-report and SetPosition tests: 76/76;
|
||||
- complete Runtime project: 562/562;
|
||||
- graphical/headless Runtime-physics ownership and dormancy guards: 4/4;
|
||||
- focused Core SetPosition/contact/response ordering tests: 29/29;
|
||||
- complete Core project: 4,224 passed / 1 intentional skip;
|
||||
- from-source Release solution rebuild: 0 errors and 21 pre-existing test-
|
||||
project nullable/analyzer warnings; this checkpoint introduces none;
|
||||
- complete Release solution: 10,309 passed / 4 intentional skips;
|
||||
- warmed steady-contact refresh: 0 managed bytes across 10,000 calls;
|
||||
- warmed immediate dormant SetPosition commit: still below the existing
|
||||
2,048-byte-per-operation ceiling, with no new captured-delegate cost;
|
||||
- architecture/adversarial re-review: clean after fixing Hidden/session/delete
|
||||
reentrancy, stale shadow-state authority, allocation churn, and batch cost;
|
||||
- retail-conformance re-review: clean against every named address above.
|
||||
|
||||
The final retail re-review found and closed two last ordering defects before
|
||||
sign-off: object collision now snapshots the mover's Missile bit before the
|
||||
source callback and, when that snapshot was set, unconditionally masks the
|
||||
current `Missile | AlignPath | PathClipped` bits afterward. Thus an ordinary
|
||||
callback-added Missile is retained when the mover was not previously a missile,
|
||||
but a callback which clears Missile and re-adds path bits cannot evade the
|
||||
pre-gated retail mask. Environment collision retains retail's post-callback
|
||||
current-Missile test. Successful SetPosition now
|
||||
publishes reports before installing the new stationary-fall counter, applies
|
||||
the physical response next, installs StationaryFall/Stop/Stuck transient bits
|
||||
after response, and only then refloods the shadow.
|
||||
|
||||
The host guard reads both production source trees. It proves App and Headless
|
||||
borrow `GameRuntime.EntityObjects.Physics`, declare no second collision table
|
||||
or return heuristic, and still contain no placement-channel consumer. No
|
||||
connected/live gate is required for this dormant checkpoint because no
|
||||
production route can populate or publish the new report owner.
|
||||
|
||||
## Exact implementation and test paths
|
||||
|
||||
The behavior commit containing this handoff changes exactly these ten code and
|
||||
test paths:
|
||||
|
||||
- `src/AcDream.Core/Physics/PhysicsObjUpdate.cs`
|
||||
- `src/AcDream.Core/Physics/ShadowObjectRegistry.cs`
|
||||
- `src/AcDream.Runtime/Entities/RuntimeEntityDirectory.cs`
|
||||
- `src/AcDream.Runtime/Entities/RuntimeEntityObjectLifetime.cs`
|
||||
- `src/AcDream.Runtime/Entities/RuntimeEntityRecord.cs`
|
||||
- `src/AcDream.Runtime/Physics/RuntimeCollisionReportingState.cs`
|
||||
- `src/AcDream.Runtime/Physics/RuntimePhysicsState.cs`
|
||||
- `src/AcDream.Runtime/Physics/RuntimeSetPositionState.cs`
|
||||
- `tests/AcDream.Runtime.Tests/Physics/RuntimeCollisionReportingStateTests.cs`
|
||||
- `tests/AcDream.App.Tests/Runtime/RuntimePhysicsOwnershipTests.cs`
|
||||
|
||||
The same commit synchronizes the architecture, divergence register, canonical
|
||||
SetPosition research, roadmap, milestones, project memory, prior campaign
|
||||
handoff pointer, retail-oracle note, and this detailed handoff. `AGENTS.md` and
|
||||
the pre-existing line-ending/stat-noise paths are deliberately excluded.
|
||||
|
||||
## Remaining work - required order
|
||||
|
||||
### 1. Exact authored mover preparation
|
||||
|
||||
Build every SetPosition request from Setup's ordered authored spheres, exact
|
||||
scale/presence semantics, StepUp/StepDown heights, flags, cell-local frame and
|
||||
orientation, and current position/vector/state authority versions. Do not
|
||||
synthesize a cylinder from visual radius/height or pre-mutate canonical state.
|
||||
|
||||
### 2. Atomic local-controller/body publication
|
||||
|
||||
Prepare off-canonical, then perform one Runtime-validated atomic transaction
|
||||
which publishes the exact same body to graphical and no-window controllers.
|
||||
Every body writer, remote/projectile binding, SetPosition operation, clock
|
||||
epoch, deletion, reset and disposal path must participate. Do not resurrect
|
||||
the rejected snapshot/rollback lease documented in the prior handoff.
|
||||
|
||||
### 3. Presentation-only host projection
|
||||
|
||||
Implement graphical and headless observers over the existing dormant placement
|
||||
receipt channel. Withdraw removes presentation/spatial consumers while
|
||||
retaining Runtime identity; Place projects only the immutable committed frame;
|
||||
Discard retires the older revision. Host failure retries the exact FIFO head
|
||||
and never rolls Runtime back.
|
||||
|
||||
### 4. Collision-prefix quiescence and atomic route activation
|
||||
|
||||
Park SetPosition residents before retiring their collision prefix, publish the
|
||||
complete replacement generation, wake exact matching residents, and cut every
|
||||
spawn/Position/portal/projectile/drop/pickup/parent/delete route over together.
|
||||
Only then may AP-1 and AD-1 retire.
|
||||
|
||||
### 5. Remaining campaign slices
|
||||
|
||||
- Port retail-authored object collision shape precedence and retire AP-22.
|
||||
- Remove remote terrain-normal preprojection and let the transition resolver
|
||||
use the retained contact plane, retiring AD-10.
|
||||
- Run the full automated and connected matrix, update all ledgers, and close
|
||||
the remaining physics campaign only with direct evidence.
|
||||
|
||||
## Rollback
|
||||
|
||||
This checkpoint is one bisectable commit. Revert the commit containing this
|
||||
file to remove collision-report ownership without disturbing the earlier
|
||||
SetPosition residence and receipt-channel checkpoints. Do not revive the old
|
||||
collision-presence guess or the rejected body snapshot lease.
|
||||
|
||||
Because a Git commit cannot embed its own final hash, resolve the exact
|
||||
checkpoint and revert command without ambiguity using:
|
||||
|
||||
```powershell
|
||||
$checkpoint = git log -1 --format=%H -- `
|
||||
docs/research/2026-07-31-runtime-set-position-collision-reporting-handoff.md
|
||||
git show --stat $checkpoint
|
||||
git revert $checkpoint
|
||||
```
|
||||
|
||||
Earlier rollback points remain:
|
||||
|
||||
```powershell
|
||||
git revert 270f5154 # dormant public placement receipt channel
|
||||
git revert 4c02ac42 # Runtime SetPosition/lost-cell residence owner
|
||||
git revert e84a388e # pure Core retail SetPosition transaction
|
||||
```
|
||||
|
||||
## Resume procedure
|
||||
|
||||
1. Continue in
|
||||
`C:\Users\erikn\.codex\worktrees\af5e\acdream` and verify
|
||||
`git branch --show-current` reports `codex/port-claude-agents`.
|
||||
2. Resolve the exact checkpoint with the `git log` command above and confirm
|
||||
it is the current `HEAD` before starting the next behavior slice.
|
||||
3. Read `AGENTS.md`, `docs/architecture/acdream-architecture.md`, this file,
|
||||
the collision-report oracle, the canonical SetPosition research, and the
|
||||
prior remaining-campaign handoff completely.
|
||||
4. Run `git status --short`. Preserve the unrelated `AGENTS.md` content diff
|
||||
and every documented line-ending/stat-noise path. Never stage by blanket.
|
||||
5. Begin only **Exact authored mover preparation**, the first remaining item
|
||||
above. Do not activate production routes, retire AP-1/AD-1, begin AP-22 or
|
||||
AD-10, or resurrect the rejected body snapshot/rollback lease.
|
||||
6. Use exact-path staging and rerun the matching focused projects,
|
||||
`dotnet build AcDream.slnx -c Release --nologo`, and
|
||||
`dotnet test AcDream.slnx -c Release --no-build --nologo` before the next
|
||||
reviewed checkpoint.
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
# Runtime SetPosition collision-report ownership
|
||||
|
||||
**Scope:** placement/streaming Slice 4B2 prerequisite A only. This closes the
|
||||
missing Runtime owner for retail collision tracking and the boolean returned by
|
||||
`CPhysicsObj::handle_all_collisions`. It does **not** activate any graphical or
|
||||
headless production SetPosition route.
|
||||
|
||||
## Named-retail oracle
|
||||
|
||||
Primary sources:
|
||||
|
||||
- `CPhysicsObj::report_object_collision_end` `0x00510A90`
|
||||
- `CPhysicsObj::report_environment_collision` `0x00512FC0`
|
||||
- `CPhysicsObj::report_object_collision` `0x00513060`
|
||||
- `CPhysicsObj::track_object_collision` `0x00513F10`
|
||||
- `CPhysicsObj::report_collision_start` `0x00513FD0`
|
||||
- `CPhysicsObj::report_collision_end` `0x00514620`
|
||||
- `CPhysicsObj::handle_all_collisions` `0x00514780`
|
||||
- `CPhysicsObj::SetPositionInternal(CTransition const*)` `0x00515330`
|
||||
- `CPhysicsObj::leave_world` `0x005155A0`
|
||||
- placement failure path in `CPhysicsObj::SetPositionInternal` `0x00515BD0`
|
||||
- `CPhysicsObj::CollisionRecord`, `EnvCollisionProfile`,
|
||||
`ObjCollisionProfile`, and `AtkCollisionProfile` in
|
||||
`docs/research/named-retail/acclient.h`
|
||||
|
||||
The source text is
|
||||
`docs/research/named-retail/acclient_2013_pseudo_c.txt`. The addresses above
|
||||
are the behavioral authority; the older unnamed chunks remain fallback only.
|
||||
|
||||
### Environment reporting
|
||||
|
||||
```text
|
||||
report_environment_collision(meInContact):
|
||||
reported = false
|
||||
if !colliding_with_environment:
|
||||
if self.ReportCollisions && self.weenie != null:
|
||||
DoCollision(EnvCollisionProfile(self.velocity, meInContact))
|
||||
reported = true
|
||||
colliding_with_environment = true
|
||||
if self.Missile:
|
||||
self.state &= ~(Missile | AlignPath | PathClipped)
|
||||
return reported
|
||||
```
|
||||
|
||||
The latch is independent of callback eligibility. An object with no collision
|
||||
callback still latches its environment contact, and a repeated environment hit
|
||||
returns false. Retail has no environment-end callback. `leave_world` does not
|
||||
clear this latch; the next `handle_all_collisions` call re-arms it only after a
|
||||
non-environment frame.
|
||||
|
||||
### Object reporting and tracking
|
||||
|
||||
```text
|
||||
track_object_collision(other, meInContact):
|
||||
if other.Static:
|
||||
return report_environment_collision(meInContact)
|
||||
|
||||
record = { touched_time = PhysicsTimer.curr_time,
|
||||
ethereal = other.Ethereal }
|
||||
existed = collision_table.clobber(other.id, record)
|
||||
if existed:
|
||||
return false
|
||||
return report_object_collision(other, meInContact)
|
||||
```
|
||||
|
||||
The table insert/refresh precedes callbacks. Duplicate contacts refresh their
|
||||
time but never replay a start callback. DAT/static classification and physics
|
||||
state come from the exact shadow object which produced the collision; object-ID
|
||||
presence is not a valid substitute.
|
||||
|
||||
`report_object_collision` first maps `ReportAsEnvironment` to the environment
|
||||
path. Otherwise:
|
||||
|
||||
- the mover reports only when the other object is not `IgnoreCollisions` and
|
||||
the mover has `ReportCollisions` plus a weenie;
|
||||
- a mover which had Missile set before the source callback unconditionally
|
||||
masks its current `Missile | AlignPath | PathClipped` bits after striking a
|
||||
non-ignored object, even when the callback cleared Missile but re-added path
|
||||
bits; when pre-callback Missile was clear, callback-added Missile is retained;
|
||||
- the reciprocal report occurs only when the other has `ReportCollisions`, the
|
||||
mover is not `IgnoreCollisions`, and the other has a weenie;
|
||||
- the return is true when at least one callback is attempted. It is never a
|
||||
collision-presence boolean.
|
||||
|
||||
### Expiry and end reporting
|
||||
|
||||
`report_collision_end(force)` removes records before dispatching callbacks.
|
||||
This ordering is required for safe reentrancy.
|
||||
|
||||
```text
|
||||
ordinary record: remove when age > 1.0, or force
|
||||
ethereal record: remove when age > 0.0, or force
|
||||
```
|
||||
|
||||
Equality remains alive. A still-resolvable non-`ReportAsEnvironment` peer may
|
||||
receive reciprocal collision-end callbacks. When the peer no longer resolves,
|
||||
the owner can still receive its self-only end using the stored retail object
|
||||
ID. A later incarnation must never satisfy the old contact record.
|
||||
|
||||
### `handle_all_collisions` and SetPosition ordering
|
||||
|
||||
```text
|
||||
handle_all_collisions(info, previousContact, previousOnWalkable):
|
||||
reported = false
|
||||
for other in info.collidedObjects, in encounter order:
|
||||
reported |= track_object_collision(other, previousContact)
|
||||
report_collision_end(force = false)
|
||||
|
||||
if environment latch is already set:
|
||||
latch = info.collided_with_environment
|
||||
else if info.collided_with_environment
|
||||
|| (!previousOnWalkable && self.OnWalkable):
|
||||
reported |= report_environment_collision(previousContact)
|
||||
|
||||
apply retail collision velocity/stationary response
|
||||
return reported
|
||||
```
|
||||
|
||||
Successful `SetPositionInternal(CTransition const*)` commits the resolved
|
||||
cell/frame, Contact/WaterContact/OnWalkable state, and HitGround/LeaveGround
|
||||
edge before `handle_all_collisions`; it ignores the returned boolean and only
|
||||
then replaces/refloods shadows. Collision reports observe the old stationary-
|
||||
fall state; the new counter is installed before physical response, while the
|
||||
StationaryFall/Stop/Stuck transient bits are replaced after response and before
|
||||
shadow reflood. The placement failure path calls
|
||||
`handle_all_collisions(info, false, false)` and maps true to
|
||||
`SetPositionError::Collided` (`4`) and false to `NoValidPosition` (`2`).
|
||||
|
||||
Consequently acdream must keep report/tracking separate from the physical
|
||||
response: failed placement runs both once, while successful Runtime commit
|
||||
runs reporting between the contact/ground commit and shadow reflood without
|
||||
double-applying velocity response.
|
||||
|
||||
## Runtime ownership contract
|
||||
|
||||
The implementation is presentation-free and belongs to the per-session
|
||||
`RuntimePhysicsState` graph. Its invariants are:
|
||||
|
||||
- owner and peer identities are exact `RuntimeEntityKey` values, not server
|
||||
GUID or local ID alone;
|
||||
- each tracked record retains the peer server GUID, touch time in the Runtime
|
||||
simulation-clock domain, and ethereal-at-touch bit;
|
||||
- collided IDs and authored/static ownership are admitted through the exact
|
||||
retained `ShadowObjectRegistry` registration which produced the collision;
|
||||
every dynamic Static/Ethereal/Ignore/ReportAsEnvironment decision then reads
|
||||
the current canonical `PhysicsBody.State`, never a stale shadow snapshot;
|
||||
- immutable reports preserve encounter order and dispatch through a retained,
|
||||
reentrancy-safe FIFO;
|
||||
- callback exceptions are isolated, while the retail report-result boolean is
|
||||
determined by callback eligibility and does not depend on subscribers;
|
||||
- every callback boundary revalidates the exact record/body/authority before
|
||||
any later canonical mutation;
|
||||
- force-end mutates the complete expired set before publishing ends; exact-key
|
||||
admission guards prevent callback reentry from recreating a leaving owner,
|
||||
and session teardown blocks the whole owner batch before its first callback;
|
||||
- one source lifetime token covers a complete precollected end batch, so a
|
||||
callback-accepted delete stops every later peer report even while teardown
|
||||
sidecars remain resolvable;
|
||||
- lifetime forget, session reset, and disposal cannot donate state to GUID
|
||||
reuse;
|
||||
- terminal ownership diagnostics include contact/report state and converge to
|
||||
zero;
|
||||
- graphical and no-window hosts borrow the same Runtime owner. No host owns a
|
||||
second collision table or report-result heuristic.
|
||||
|
||||
The warmed steady-contact refresh path allocates zero managed bytes. Expired
|
||||
contact storage is allocated lazily only after the first actual expiry, and
|
||||
session-batch teardown is linear in owner count.
|
||||
|
||||
## Deliberately deferred
|
||||
|
||||
The canonical SetPosition owner remains dormant in production. The following
|
||||
belong to later 4B2 commits and are not part of this checkpoint:
|
||||
|
||||
- exact ordered Setup spheres, authored scale and step-height preparation;
|
||||
- the atomic shared local-controller body transaction;
|
||||
- presentation-only rebucketing and placement-prefix quiescence;
|
||||
- graphical/headless spawn, Position, portal, projectile, drop, pickup,
|
||||
parent, and delete route cutover.
|
||||
|
||||
AP-1 and AD-1 therefore remain open, narrowed only by removal of the
|
||||
collision-report prerequisite.
|
||||
Loading…
Add table
Add a link
Reference in a new issue