feat(runtime): construct remote bodies at Create per retail set_description
Cutover slice C3b: residence-route remote/creature/projectile Creates now get their canonical PhysicsBody at Create time — retail's order, closing the C3 flip's Finding C (production builds bodies at first motion; retail builds them in ACCObjectMaint::CreateObject). RuntimeRemoteBodyDescription walks set_description 0x00514F40 exactly: the motion-table gate (zero id PASSES — verified at 0051871f/005127ca), the frame-vs-movement branch keyed on retail's movement_buffer != 0 (an empty-buffer movement payload takes the PLACEMENT branch and writes no autonomy — the wire-shape defect the retail review caught), set_state, the byte-certain friction gate (inclusive [0,1]; NaN deliberately skipped per the gates doc's sanctioned deviation), the set_elasticity clamp with retail's unordered-to-zero NaN routing (ACE diverges to 0.1 on that edge), the translucency gate (!= 0.0f, original always recorded), velocity via setter, omega raw, and ctor-defaults for absent wire fields (0.95f/0.05f/0 — the fresh-desc-per- message flow verified at both UnPack call sites). InWorld stays false until submission, the enter_world analog. RuntimeRemoteFirstEntryState sequences mover-prep -> body construction -> placement -> acknowledgement -> Execute with every C3a hardening inherited: exactly-once stages, the shared acknowledge-stage discriminator (extracted to RuntimeFirstEntryAcknowledgement, one body for both conductors), typed Contention against in-flight remote-motion binds, never-clobber body binding through the canonical writer (foreign body fails closed — provably safe coexistence with today's build-at-first-motion path in both directions), automatic convergence through the retirement fan-out, and the construction receipt riding the terminal Advance. Dormant: no production caller; C3c wires both hosts. Reviewed: retail-conformance PASS (the construction order, both gate boundary/NaN semantics, the motion-table and autonomy verdicts all re-derived from the pseudo-C) + architecture/adversarial PASS after one fix round. Runtime 982/982; complete Release solution 10,777 passed / 4 intentional skips. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d62b99509e
commit
0934a12111
6 changed files with 2083 additions and 41 deletions
|
|
@ -64,7 +64,13 @@ public readonly record struct RuntimeEntityObjectOwnershipSnapshot(
|
|||
/// <c>Advance</c>), but fully constructed/wired like every other owner
|
||||
/// here, so its own ownership must converge to zero the same way.
|
||||
/// </summary>
|
||||
int LocalPlayerFirstEntryActiveCount = 0)
|
||||
int LocalPlayerFirstEntryActiveCount = 0,
|
||||
/// <summary>
|
||||
/// C3b: outstanding <see cref="RuntimeRemoteFirstEntryState"/> tracked
|
||||
/// keys - the remote/projectile Create-time body-construction conductor.
|
||||
/// Dormant like its C3a sibling; converges to zero the same way.
|
||||
/// </summary>
|
||||
int RemoteFirstEntryActiveCount = 0)
|
||||
{
|
||||
public bool IsConverged =>
|
||||
IsDisposed
|
||||
|
|
@ -87,6 +93,7 @@ public readonly record struct RuntimeEntityObjectOwnershipSnapshot(
|
|||
&& InitialCreateExecutorProgressCount == 0
|
||||
&& PendingCompletionReceiptCount == 0
|
||||
&& LocalPlayerFirstEntryActiveCount == 0
|
||||
&& RemoteFirstEntryActiveCount == 0
|
||||
&& StreamSubscriberCount == 0
|
||||
&& PlacementStreamSubscriberCount == 0
|
||||
&& PendingDispatchCount == 0
|
||||
|
|
@ -176,6 +183,15 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
InitialCreateResidences,
|
||||
InitialCreateExecution,
|
||||
Physics);
|
||||
// C3b: the remote/projectile analog of the conductor above — retail
|
||||
// body construction at Create time in place of the publication
|
||||
// chain. Dormant like its sibling (no production caller of Advance);
|
||||
// constructed and wired identically so its ownership converges the
|
||||
// same way.
|
||||
RemoteFirstEntry = new RuntimeRemoteFirstEntryState(
|
||||
InitialCreateResidences,
|
||||
InitialCreateExecution,
|
||||
Physics);
|
||||
// Round 3 B3: every residence retirement path - not only the
|
||||
// executor's own DiscardProgress calls - must converge the
|
||||
// executor's progress AND its separately-tracked pending
|
||||
|
|
@ -190,6 +206,10 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
// updated doc comment for why this is now multicast.
|
||||
InitialCreateResidences.BindRetirementNotification(
|
||||
key => LocalPlayerFirstEntry.Forget(key));
|
||||
// C3b: the remote conductor joins the SAME multicast retirement
|
||||
// fan-out, third in registration order.
|
||||
InitialCreateResidences.BindRetirementNotification(
|
||||
key => RemoteFirstEntry.Forget(key));
|
||||
// F2: reaps the executor's completion-receipt correlation entry
|
||||
// exactly when a host acknowledges the ExecutorCompleted receipt it
|
||||
// correlates - mirrors the residence-retirement binding immediately
|
||||
|
|
@ -245,6 +265,15 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
InitialCreateResidences,
|
||||
InitialCreateExecution,
|
||||
Physics);
|
||||
// C3b: the remote/projectile analog of the conductor above — retail
|
||||
// body construction at Create time in place of the publication
|
||||
// chain. Dormant like its sibling (no production caller of Advance);
|
||||
// constructed and wired identically so its ownership converges the
|
||||
// same way.
|
||||
RemoteFirstEntry = new RuntimeRemoteFirstEntryState(
|
||||
InitialCreateResidences,
|
||||
InitialCreateExecution,
|
||||
Physics);
|
||||
// Round 3 B3: every residence retirement path - not only the
|
||||
// executor's own DiscardProgress calls - must converge the
|
||||
// executor's progress AND its separately-tracked pending
|
||||
|
|
@ -259,6 +288,10 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
// updated doc comment for why this is now multicast.
|
||||
InitialCreateResidences.BindRetirementNotification(
|
||||
key => LocalPlayerFirstEntry.Forget(key));
|
||||
// C3b: the remote conductor joins the SAME multicast retirement
|
||||
// fan-out, third in registration order.
|
||||
InitialCreateResidences.BindRetirementNotification(
|
||||
key => RemoteFirstEntry.Forget(key));
|
||||
// F2: reaps the executor's completion-receipt correlation entry
|
||||
// exactly when a host acknowledges the ExecutorCompleted receipt it
|
||||
// correlates - mirrors the residence-retirement binding immediately
|
||||
|
|
@ -314,6 +347,15 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
InitialCreateResidences,
|
||||
InitialCreateExecution,
|
||||
Physics);
|
||||
// C3b: the remote/projectile analog of the conductor above — retail
|
||||
// body construction at Create time in place of the publication
|
||||
// chain. Dormant like its sibling (no production caller of Advance);
|
||||
// constructed and wired identically so its ownership converges the
|
||||
// same way.
|
||||
RemoteFirstEntry = new RuntimeRemoteFirstEntryState(
|
||||
InitialCreateResidences,
|
||||
InitialCreateExecution,
|
||||
Physics);
|
||||
// Round 3 B3: every residence retirement path - not only the
|
||||
// executor's own DiscardProgress calls - must converge the
|
||||
// executor's progress AND its separately-tracked pending
|
||||
|
|
@ -328,6 +370,10 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
// updated doc comment for why this is now multicast.
|
||||
InitialCreateResidences.BindRetirementNotification(
|
||||
key => LocalPlayerFirstEntry.Forget(key));
|
||||
// C3b: the remote conductor joins the SAME multicast retirement
|
||||
// fan-out, third in registration order.
|
||||
InitialCreateResidences.BindRetirementNotification(
|
||||
key => RemoteFirstEntry.Forget(key));
|
||||
// F2: reaps the executor's completion-receipt correlation entry
|
||||
// exactly when a host acknowledges the ExecutorCompleted receipt it
|
||||
// correlates - mirrors the residence-retirement binding immediately
|
||||
|
|
@ -353,6 +399,7 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
internal RuntimeInitialCreateContinuationExecutor InitialCreateExecution
|
||||
{ get; }
|
||||
internal RuntimeLocalPlayerFirstEntryState LocalPlayerFirstEntry { get; }
|
||||
internal RuntimeRemoteFirstEntryState RemoteFirstEntry { get; }
|
||||
|
||||
public RuntimeEntityObjectOwnershipSnapshot CaptureOwnership()
|
||||
{
|
||||
|
|
@ -389,7 +436,8 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
InitialCreateExecution.ReplayFailureCount,
|
||||
InitialCreateExecution.LastReplayFailure is not null,
|
||||
InitialCreateExecution.PendingCompletionReceiptCount,
|
||||
LocalPlayerFirstEntry.CaptureOwnership().ActiveCount);
|
||||
LocalPlayerFirstEntry.CaptureOwnership().ActiveCount,
|
||||
RemoteFirstEntry.CaptureOwnership().ActiveCount);
|
||||
}
|
||||
|
||||
public void BindEventContext(
|
||||
|
|
@ -1734,6 +1782,7 @@ public sealed class RuntimeEntityObjectLifetime : IDisposable
|
|||
InitialCreateResidences.Clear();
|
||||
InitialCreateExecution.DiscardAll();
|
||||
LocalPlayerFirstEntry.DiscardAll();
|
||||
RemoteFirstEntry.DiscardAll();
|
||||
Physics.CollisionReports.LeaveWorldBatch(active);
|
||||
Physics.ResetSessionPhysics();
|
||||
Entities.BeginSessionClear();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue