feat(physics): port retail projectile integration

Add a pure Core projectile driver for retail clock quanta, final-state acceleration, 50-unit velocity clamping, world-space angular integration, full-3D AlignPath, and oriented Setup-local sphere sweeps. Preserve exact success versus set_frame-only failure semantics, independent Contact/OnWalkable state, and full-cell identity across all landblock directions.

Port OBJECTINFO::missile_ignore with explicit weenie/creature metadata, remove the invented transition-step cap, retain PathClipped without arming PerfectClip, and keep authoritative target identity optional. Add malformed-shape/clock, thin-wall, terrain, target-exclusion, frame-spike, failure-state, and boundary conformance coverage.

Retire TS-2 and synchronize the architecture, milestones, roadmap, research oracle, and durable physics memory.

Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
Erik 2026-07-14 11:43:11 +02:00
parent 542dcfc384
commit f02b995e4f
21 changed files with 1669 additions and 263 deletions

View file

@ -821,3 +821,54 @@ observable ordering without exposing a half-committed pose to modern sinks.
through normal owner teardown while retaining DAT-static/synthetic poses.
TS-11 and TS-12 are retired with the emitter-binding and
live-part mechanisms.
## 15. Step 6 implementation map (2026-07-14)
- `ProjectilePhysicsStepper` is a pure Core clock/integration/sweep owner. It
accepts an already-live `PhysicsBody`, full cell, Setup-local sphere, local
entity identity, and optional authoritative target identity; it owns no
renderer, network state, or logical lifetime. `ProjectileController` in the
next step will select records and apply authoritative corrections around it.
- The shared integrator now uses retail's 0.2-second maximum catch-up quantum
and world-space angular rotation (`Frame::grotate`, quaternion delta
pre-multiplied). Velocity is clamped to 50 world units/second before
integration, acceleration is recalculated from the final PhysicsState each
quantum, and AlignPath replaces orientation from the complete three-axis
displacement through `RetailFrameMath.SetVectorHeading`.
- Installed projectile Setup auditing proves the required arrow, bolt, and
representative spell set uses exactly one ordinary collision sphere. The
port retains the complete Setup-local origin and scales both origin and
radius; it therefore preserves Force Bolt's offset
`(0, -0.165, 0.1045)` and never derives collision size from the mesh.
- `ResolveWithTransition` accepts the sphere's local origin and begin/end
orientations, carries the resulting orientation in `ResolveResult`, skips
the moving entity's own shadow, and automatically adds PathClipped for a
Missile body. It deliberately does not add PerfectClip.
- `ObjectInfo.MissileIgnore` is the exact `0x0050CEB0` branch tree. Runtime
collision metadata now distinguishes “has a CWeenieObject” from “is a
creature”; server-created live entities set the former, while DAT landblock
geometry does not. The designated target remains zero until an
authoritative wire/runtime source supplies one.
- Transition subdivision provides the continuous sweep. Conformance covers
maximum-speed thin sphere and BSP walls, terrain floors, elastic reflection,
inelastic stopping, missiles, ethereal weenies, designated and unknown
creature targets, self exclusion, and loaded landblock crossing. Retail's
transition loop has no arbitrary step-count cap; a 50-unit/second arrow with
a 0.1-unit sphere therefore completes all 100 sweep steps in one 0.2-second
catch-up quantum. On transition failure, the integrated candidate frame is
retained in the current cell and cached velocity is zeroed without running
`SetPositionInternal` or collision response; transition-local contact,
stationary, walkable-polygon, and sliding results are discarded. Successful
`SetPositionInternal` writeback keeps Contact distinct from OnWalkable: a
steep plane can be contact while only normals with Z at or above FloorZ are
walkable. Both facts commit before collision response, so a floor impact
settles on the following tick without turning a steep hit into ground.
- The landblock-crossing test exposed and fixed a shared world-frame rebasing
defect: after the containing cell crosses a 192-metre block boundary, the
carried block origin must move by the same block delta before the next
substep. Retail gets this for free from cell-relative `Position.Frame`;
acdream now performs the equivalent rebase at the ordered containing-cell
retarget, preventing one extra landblock jump per remaining sweep substep.
Boundary conformance covers positive and negative X and Y crossings.
- TS-2 is retired. AP-83 and AP-91 remain because ordinary missiles are
PathClipped and do not arm their dormant PerfectClip time-of-impact paths.