fix(physics): AD-25 - remote collision response through ported HandleAllCollisions
Campaign P Slice P3 item 2. CPhysicsObj::handle_all_collisions (0x00514780, pc:282647) is one uniform function retail calls unconditionally after every SetPositionInternal, player or remote. The gate is shouldReflect = !(prevOnWalkable && nowOnWalkable && !sledding). RuntimeRemotePhysicsUpdater.Tick's post-resolve reflect was still the 2026-07-05 (#173) hand-inlined block, gated on resolveResult.CollisionNormalValid and using two ad-hoc branches that diverge from retail in exactly the cases the register row named: - non-sledding: old = "!prevOnWalkable && !nowOnWalkable" (reflects ONLY airborne-before-AND-after); retail reflects on every transition except grounded-before-AND-after. - sledding: old = "!(prevOnWalkable && nowOnWalkable)" (suppresses the bounce exactly when both grounded); retail's "!sledding" term forces shouldReflect = true unconditionally when sledding, the opposite polarity. Both gaps meant a remote's post-landing reflect never ran on a grounded-transition tick at all -- the "acdream lands clean and dead" half of #166's slope-landing composite. Replace the hand-inlined block with a direct call to PhysicsObjUpdate.HandleAllCollisions -- the same verbatim port the local player and every ordinary body already use via CommitSetPositionTransition -- passing the same prevContact/prevOnWalkable/nowOnWalkable values the old code already computed. Narrower swap per the research's explicit recommendation: does not fold in CommitSetPositionTransition's HitGround/LeaveGround dispatch, leaving the remote's bespoke landing-detection block (interp-queue-clear, animation-hook-specific logic) untouched. The call is now unconditional (matching retail's own unconditional call site) rather than gated behind CollisionNormalValid, since HandleAllCollisions already no-ops the reflect step internally when no normal was found but still runs the frames-stationary-fall bleed regardless. PhysicsObjUpdate.HandleAllCollisionsTests already exhaustively pins the retail formula in isolation; this change is a mechanical wiring swap to the already-tested function using values the removed block already computed. Full regression suites (Core.Tests 3991/2 skip, Runtime.Tests 425/0, App.Tests 3968/3 skip) pass unchanged -- no existing test pinned the old broken formula. Register: AD-25 retired (both the local-player and remote halves are now the ported HandleAllCollisions); #166's reattribution note updated to reflect the closure, leaving only TS-4 as the remaining blocker on that issue's downhill-jump-glide acceptance. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
dae5b1ea68
commit
8b5425498c
3 changed files with 65 additions and 67 deletions
|
|
@ -4297,24 +4297,37 @@ now ports retail's confirmed 0.25f threshold); TS-4's removal was attempted
|
|||
per its own fixture-first requirement and reproduced the historical
|
||||
2026-04-30 wedge, so **TS-4 stays deferred** (see its register row and the
|
||||
research doc §7 item 6 for the precise mechanism and the concrete next
|
||||
step). Closure of #166 therefore pends: (a) TS-4 actually landing, and (b)
|
||||
step).
|
||||
|
||||
**AD-25 closed (2026-07-30, Campaign P Slice P3):** the remote dead-
|
||||
reckoning post-resolve now calls the exact ported
|
||||
`PhysicsObjUpdate.HandleAllCollisions` — the same function the local
|
||||
player and every ordinary body already use — instead of its own
|
||||
hand-inlined, narrower reflect gate (`RuntimeRemotePhysicsUpdater.cs`,
|
||||
`Tick`). The old gate reflected only airborne-before-AND-after and
|
||||
suppressed the sledding case backwards; the ported gate reflects on any
|
||||
transition except grounded→grounded-and-not-sledding, matching retail's
|
||||
`shouldReflect = !(prevOnWalkable && nowOnWalkable && !sledding)`. Both
|
||||
halves of AD-25 (local player and remote) are now retired.
|
||||
|
||||
Closure of #166 therefore pends only: (a) TS-4 actually landing, and (b)
|
||||
re-checking Campaign P's final visual matrix item 5 ("Downhill jump
|
||||
landing: sled glide + bounce") against a fresh capture — if the glide/
|
||||
bounce still visibly mismatches retail after AP-7 alone (with TS-4 still
|
||||
deferred), that capture, not a guess, is what should drive any further
|
||||
work here, and it should go through cdb against live retail before any
|
||||
client-side Sledding-state mechanism is written.
|
||||
bounce still visibly mismatches retail after AP-7 and AD-25 (with TS-4
|
||||
still deferred), that capture, not a guess, is what should drive any
|
||||
further work here, and it should go through cdb against live retail
|
||||
before any client-side Sledding-state mechanism is written.
|
||||
|
||||
**Where:** `PlayerMovementController.cs:874` (AD-25 suppression, remote
|
||||
half only — local half already ported via #182),
|
||||
**Where:** `src/AcDream.Runtime/Physics/RuntimeRemotePhysicsUpdater.cs`
|
||||
(remote reflect, AD-25 — DONE 2026-07-30),
|
||||
`src/AcDream.Core/Physics/PhysicsBody.cs` (`calc_friction`, AP-7 — DONE
|
||||
2026-07-30), `src/AcDream.Core/Physics/BSPQuery.cs` (Path 6 steep branches,
|
||||
TS-4 — deferred, shortcut still in place).
|
||||
|
||||
**Acceptance:** side-by-side downhill jump: acdream glides/bounces like
|
||||
retail; flat-ground landings unchanged; no micro-bounce death spiral
|
||||
(the reason AD-25 exists) reintroduced. Blocked on TS-4's eventual landing
|
||||
per the note above.
|
||||
(the reason AD-25 existed) reintroduced. Blocked on TS-4's eventual
|
||||
landing per the note above.
|
||||
|
||||
## #164 — UM action-replay dispatches drop the per-action Autonomous bit
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue