docs(runtime): close projectile ownership
This commit is contained in:
parent
2aee33569f
commit
c30a3efeb0
11 changed files with 263 additions and 35 deletions
169
docs/research/2026-07-26-slice-j5-6-projectile-ownership.md
Normal file
169
docs/research/2026-07-26-slice-j5-6-projectile-ownership.md
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
# Slice J5.6 — projectile-simulation ownership
|
||||
|
||||
Date: 2026-07-26
|
||||
Scope: ownership relocation only; no retail algorithm, packet, collision
|
||||
policy, impact authority, or presentation change
|
||||
|
||||
## Objective
|
||||
|
||||
Move the mutable projectile component, projectile workset, prediction version,
|
||||
authoritative correction, and retail projectile step into the same
|
||||
`AcDream.Runtime` physics lifetime that already owns the canonical entity
|
||||
record, body, object clock, collision engine, shadows, and full cell.
|
||||
|
||||
App remains responsible for:
|
||||
|
||||
- resolving the projectile's immutable Setup/DAT collision sphere;
|
||||
- supplying the current graphical projection validity acknowledgement;
|
||||
- rebucketing and positioning the retained render projection after a Runtime
|
||||
commit;
|
||||
- synchronizing the render shadow and effect pose;
|
||||
- drawing meshes, trails, particles, sounds, and impact effects.
|
||||
|
||||
ACE remains authoritative for targets, hits, damage, impact scripts, and
|
||||
deletion.
|
||||
|
||||
## Named-retail oracle
|
||||
|
||||
Primary source:
|
||||
`docs/research/named-retail/acclient_2013_pseudo_c.txt`.
|
||||
|
||||
- `CPhysicsObj::UpdateObjectInternal` `0x005156B0`
|
||||
- `CPhysicsObj::update_object` `0x00515D10`
|
||||
- `CPhysicsObj::SetPositionInternal(CTransition const*)` `0x00515330`
|
||||
- `CPhysicsObj::set_velocity` `0x005113F0`
|
||||
- `OBJECTINFO::missile_ignore` `0x0050CEB0`
|
||||
- `Frame::set_vector_heading` `0x00535DB0`
|
||||
|
||||
The complete translated retail projectile control flow is pinned in
|
||||
`docs/research/2026-07-13-retail-projectile-vfx-pseudocode.md`. The existing
|
||||
Core `ProjectilePhysicsStepper` and collision driver were cross-checked there
|
||||
against ACE's physics implementation and Holtburger/ACViewer's DAT
|
||||
interpretation. J5.6 reuses those algorithms unchanged.
|
||||
|
||||
## Preserved control flow
|
||||
|
||||
```text
|
||||
for each spatial projectile owned by the current incarnation:
|
||||
reject static, frozen, parented, hidden, cell-less, or inactive bodies
|
||||
advance the retained CPhysicsObj clock in retail 0.2-second quanta
|
||||
for each due quantum:
|
||||
calculate acceleration from the final PhysicsState
|
||||
clamp speed to 50 world units/second
|
||||
integrate position, velocity, omega, and AlignPath orientation
|
||||
continuously sweep the authored Setup-local collision sphere
|
||||
apply retail missile-ignore and inelastic/elastic collision rules
|
||||
commit the accepted frame and full cell to the canonical record
|
||||
stop the split prediction if any authority/incarnation token changed
|
||||
publish one immutable committed frame to the host
|
||||
```
|
||||
|
||||
The graphical host may reject the presentation acknowledgement after a
|
||||
re-entrant delete, replacement, rebucket, or session reset. That rejection
|
||||
invalidates the pending prediction; it cannot roll back or redirect a newer
|
||||
canonical owner.
|
||||
|
||||
## Previous ownership gap
|
||||
|
||||
Before J5.6:
|
||||
|
||||
- `RuntimeEntityRecord` owned identity, body, state, clocks, and cell;
|
||||
- `RuntimePhysicsState` owned the engine, shadows, remotes, and ordinary/remote
|
||||
worksets;
|
||||
- App `ProjectileController` still owned the projectile component, projectile
|
||||
workset snapshot, quantum stepping, correction, and canonical cell commit.
|
||||
|
||||
That split made a no-window Runtime unable to fly the same projectile without
|
||||
reconstructing App behavior and left projectile mutation on the wrong side of
|
||||
the presentation boundary.
|
||||
|
||||
## Implemented boundary
|
||||
|
||||
- `RuntimeEntityRecord.Projectile` is the sole mutable projectile component
|
||||
slot.
|
||||
- `RuntimeProjectile` owns the canonical body, authored collision sphere, and
|
||||
prediction-authority version.
|
||||
- `RuntimePhysicsState` owns binding, refresh, spatial membership, authoritative
|
||||
vector/state correction, and the exact-key projectile workset.
|
||||
- `RuntimeProjectilePhysicsUpdater` owns the unchanged retail quantum,
|
||||
integration, sweep, collision, cell-crossing, and split-prediction logic.
|
||||
- Runtime cell commits flow through the same typed
|
||||
`RuntimePhysicsCellCommit` used by ordinary and remote objects.
|
||||
- App `ProjectileController` resolves DAT/Setup shape data, delegates the
|
||||
simulation, and applies only retained render projection, shadow, and effect
|
||||
pose acknowledgements.
|
||||
- Delete, GUID reuse, visibility withdrawal, pending-to-loaded recovery,
|
||||
authoritative correction, and session teardown use the canonical Runtime
|
||||
record and workset; they never reconstruct from stale spawn data.
|
||||
|
||||
No gameplay outcome moved client-side. No projectile-specific render pass,
|
||||
second GUID map, body mirror, effect owner, or collision owner was introduced.
|
||||
|
||||
## Automated acceptance
|
||||
|
||||
On production commit
|
||||
`2aee33569f0268d7bc0f4f52437dfa0b405432a4`:
|
||||
|
||||
- Runtime tests: 317 passed.
|
||||
- App tests: 3,718 passed / 3 skipped.
|
||||
- Focused Core projectile tests: 47 passed.
|
||||
- Complete Release solution: 8,591 passed / 5 skipped.
|
||||
- Release solution build: zero warnings and zero errors.
|
||||
|
||||
The focused fixtures cover:
|
||||
|
||||
- canonical component/body/workset identity;
|
||||
- 0.2-second catch-up quanta and prediction invalidation;
|
||||
- clamp, gravity, omega, full 3-D AlignPath, and collision;
|
||||
- thin walls and inelastic stopping;
|
||||
- missile/ethereal/designated-target exclusion;
|
||||
- loaded, pending, landblock crossing, and hydration;
|
||||
- State/Vector/Position correction order;
|
||||
- deletion, same-GUID reuse, reset, and 96-owner lifetime stress;
|
||||
- no duplicate mesh, body, shadow, script, effect, or projectile owner.
|
||||
|
||||
## Connected acceptance
|
||||
|
||||
All connected processes used the exact embedded/source commit
|
||||
`2aee33569f0268d7bc0f4f52437dfa0b405432a4` and closed gracefully.
|
||||
|
||||
- Arrow plus representative spell projectile:
|
||||
`.test-out/j56-projectile-20260726-143256`
|
||||
recorded an authoritative missile attack, live Arrow spawn, live Acid Stream
|
||||
spawn, and matching authoritative deletes.
|
||||
- Crossbow bolt:
|
||||
`.test-out/j56-crossbow-evidence-20260726-145612`
|
||||
recorded a missile attack, live Quarrel spawn with Setup `0x0200012A`,
|
||||
authoritative ammo pickup/update, projectile delete, and target death.
|
||||
- Lifecycle/reconnect:
|
||||
`logs/connected-world-gate-20260726-145731/report.json`
|
||||
passed capped login plus fresh uncapped reconnect, all seven checkpoints,
|
||||
zero failures, and two code-zero exits.
|
||||
- Canonical nine-stop route:
|
||||
`logs/connected-r6-soak-20260726-151349.report.json`
|
||||
materialized all nine destinations, passed the Caul/Holtburg/Caul-return
|
||||
forward, jump, combat, and movement-truth exercises, matched source and
|
||||
binary, and exited with code zero and zero failures.
|
||||
|
||||
The first route attempt,
|
||||
`logs/connected-r6-soak-20260726-150347.report.json`, intentionally remains in
|
||||
the evidence trail. Its strict plateau check saw the already-known late lazy
|
||||
mesh population (`582 -> 604`) while sampled entity counts happened to match
|
||||
and therefore reported one failure. The immediate warm-machine rerun saw the
|
||||
same class of late population (`581 -> 598`) together with one changed visible
|
||||
owner and correctly classified it as workload variation. The accepted J5.5
|
||||
baseline exhibited the same late Caul behavior (`575 -> 597`), and the J5.6
|
||||
diff contains no mesh-cache, mesh-preparation, streaming, or residency change.
|
||||
This is not waived as a projectile result and no threshold was loosened.
|
||||
|
||||
## Divergence and rollback
|
||||
|
||||
J5.6 changes ownership only. The retail algorithm, constants, packet order,
|
||||
server authority, and presentation are unchanged, so it introduces no new
|
||||
retail-divergence row.
|
||||
|
||||
Exact rollback:
|
||||
|
||||
```text
|
||||
git revert 2aee33569f0268d7bc0f4f52437dfa0b405432a4
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue