fix(physics): P5 commit 3 - retire TS-35, close #167 (ConstraintManager leash)

PhysicsBody.IsFullyConstrained now reflects real ConstraintManager state
(pushed every tick by the same per-tick pumps commit 2 wired), so
jump_is_allowed's already-ported gate (WeenieError 0x47) actually fires
while an object is rubber-banding hard against a server position
correction, closing the last piece of #167.

Housekeeping:
- Delete register row TS-35 (retired: the write side is no longer stubbed).
- Rewrite the stale doc comments on PhysicsBody.IsFullyConstrained,
  ConstraintManager (class + IsFullyConstrained), PositionManager.ConstrainTo,
  EntityPhysicsHost.PositionManager, and PlayerMovementController.PositionManager
  that described the leash as permanently unarmed/stubbed.
- Close #167 in ISSUES.md citing the research doc and commits e0629145 /
  7719d25b.
- Add an "as-ported" addendum to
  docs/research/2026-07-30-constraint-leash-constants.md naming the actual
  current seam owners (the doc's own open question flagged this as
  implementer-verify-required post-J-slices).
- Update docs/plans/2026-07-29-physics-parity-campaign.md's P5 status and
  CLAUDE.md's Campaign P summary to reflect #167's closure (items #153/#72
  remain open in P5).

Verification: complete solution suite green - 9,978 tests, 5 skips, 0
failures across all 9 test projects (Core.Tests, Runtime.Tests, App.Tests,
Headless.Tests, Core.Net.Tests, Content.Tests, UI.Abstractions.Tests,
Bake.Tests, Cli.Tests).
This commit is contained in:
Erik 2026-07-30 12:12:29 +02:00
parent 7719d25bc5
commit 9e17554ed4
10 changed files with 159 additions and 48 deletions

View file

@ -4217,7 +4217,20 @@ Test: `GpuWorldStateTests.RelocateEntity_StrandedInPending_MovesToLoadedTarget`
## #167 — ConstraintManager leash unported (arming + two unknown x87 constants)
**Status:** OPEN (deferred, filed 2026-07-03 during R5-V1)
**Status:** DONE — 2026-07-30 (Campaign P Slice P5). Both blockers were
research-solved without a cdb session: the two x87-elided constants were
recovered by disassembling the matching retail binary's raw machine code
(`docs/research/2026-07-30-constraint-leash-constants.md`), and the arming
site is now every current acdream inbound-position acceptance seam. Commit
`e0629145` (constants + `ConstraintDistance`), commit `7719d25b` (arming at
`LiveEntityNetworkUpdateController` for remotes and
`PlayerMovementController.SetPosition`/`BlipPosition` for the local player,
plus the per-tick `PhysicsBody.IsFullyConstrained` push), and this commit
(TS-35 retirement + stale-comment cleanup). Register row **TS-35** is
deleted in the same session. Full Core/Runtime/App suites pass with no
regressions; new conformance tests cover leash-armed jump refusal,
teleport-vs-blip anchor/teardown behavior, taper reduction over ticks, and
the remote-tick `IsFullyConstrained` push.
**Severity:** LOW (server-position rubber-band + jump-during-rubber-band gate)
**Component:** physics, constraint
@ -4233,25 +4246,31 @@ not `SmartBox`, so nothing calls `PositionManager.ConstrainTo`, and
`IsFullyConstrained` stays false (= register **TS-35**'s current stub
behavior — jump never blocked by the leash).
**Blockers:** (1) the two distance constants are **x87 float returns BN
elided** — `GetStart/MaxConstraintDistance` decompile to a bare
**Blockers (RESOLVED):** (1) the two distance constants were **x87 float
returns BN elided** — `GetStart/MaxConstraintDistance` decompile to a bare
`this->m_position;` expression with the actual returned value lost to the
FPU-return-elision artifact. Recovering them needs a live cdb read of `st0`
after the call (retail debugger toolchain) or a Ghidra re-decompile with a
corrected float-return signature. (2) The arming site (`SmartBox`'s inbound
position-reconciliation branches A/B/C) has no acdream equivalent yet — wiring
it means teaching acdream's position path to re-anchor the leash on every
server position update, then feeding the `adjust_offset` taper into the body
integration (same chokepoint as the sticky wiring, R5-V3).
FPU-return-elision artifact. Recovered by disassembling the matching binary's
raw machine code directly (no cdb needed): outdoor start 10 / indoor 5,
outdoor max 50 / indoor 20 — ACE's start mapping is INVERTED (outdoor 5 /
indoor 10); the binary wins. (2) The arming site (`SmartBox`'s inbound
position-reconciliation branches A/B/C) had no acdream equivalent — wired at
`LiveEntityNetworkUpdateController` (remotes, anchored to the object's own
position) and `PlayerMovementController.SetPosition`/`BlipPosition` (local
player, anchored to the received position), feeding the `AdjustOffset` taper
into the body integration at the same per-tick chokepoint as the sticky
wiring (R5-V3).
**Where:** `src/AcDream.Core/Physics/Motion/ConstraintManager.cs` (class,
unarmed); the read gate is `PhysicsBody.IsFullyConstrained` (TS-35) via
`jump_is_allowed`. Decomp: `docs/research/2026-07-03-r5-managers/`.
**Where:** `src/AcDream.Core/Physics/Motion/ConstraintManager.cs` (armed),
`src/AcDream.Core/Physics/Motion/ConstraintDistance.cs` (constants); the read
gate is `PhysicsBody.IsFullyConstrained` (former TS-35) via
`jump_is_allowed`. Decomp: `docs/research/2026-07-03-r5-managers/`,
`docs/research/2026-07-30-constraint-leash-constants.md`.
**Acceptance:** the two constants are recovered (cdb/Ghidra), acdream arms the
leash on inbound server positions, `IsFullyConstrained` fires while
rubber-banding, and a jump attempt inside the tight leash is blocked
(0x47) matching retail; TS-35 + this issue retire together.
**Acceptance:** the two constants are recovered (byte-decoded from the
binary), acdream arms the leash on inbound server positions,
`IsFullyConstrained` fires while rubber-banding, and a jump attempt inside
the tight leash is blocked (0x47) matching retail; TS-35 + this issue retired
together.
## #160 — Remote moveto: run animation pace vs actual movement speed mismatch