fix(phys): A6.P3 slice 2 — remove L622 per-tick CP seed (issue #96)
Closes issue #96 (per-tick PhysicsEngine.ResolveWithTransition CP seed contributing 99.3% of post-slice-1 CP writes). Matches retail's CTransition::init at acclient_2013_pseudo_c.txt:271954 which explicitly clears contact_plane_valid = 0 at transition start. Cross-tick CP retention now flows entirely via retail-faithful mechanisms: - Mechanism A: BSPQuery.FindCollisions Path-6 land write - Mechanism B: Transition.ValidateTransition LKCP restore (slice 1) - Body persist at transition end (already existed) Cost (deliberate): AdjustOffset on sub-step 1 of each tick takes the 'no contact plane' path. Slope-snap loss is imperceptible (sub-steps are small, sub-steps 2+ pick up CP normally). Likely closes issue #97 (phantom collisions + fall-through) as side-effect — hypothesis was stale-CP slope-snap from body.ContactPlane of a previous cell. To be verified post-commit via re-capture + user happy-test. Verification this commit: - Test suite: 1148 pass + 8 pre-existing fail (baseline maintained) - scen3 re-capture pending (separate commit) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f04ea90050
commit
892019bc9a
1 changed files with 29 additions and 26 deletions
|
|
@ -597,33 +597,36 @@ public sealed class PhysicsEngine
|
|||
if (isOnGround)
|
||||
transition.ObjectInfo.State |= ObjectInfoState.Contact | ObjectInfoState.OnWalkable;
|
||||
|
||||
// K-fix7 (2026-04-26): only seed the contact plane when the body
|
||||
// is actually grounded. Pre-seeding while AIRBORNE caused
|
||||
// AdjustOffset's "Have a contact plane / Moving away from plane"
|
||||
// branch to fire on every jump step — which calls
|
||||
// Plane::snap_to_plane on the offset and ZEROES the Z component,
|
||||
// killing all upward jump motion (the body's Z velocity stayed
|
||||
// ~9 m/s but Position.Z never advanced because every step's
|
||||
// offset got snapped flat). Retail's CTransition::init at
|
||||
// 0x509dd0 (named-retail line 271954) explicitly clears
|
||||
// contact_plane_valid = 0 at the start of every transition
|
||||
// resolve, then ValidateWalkable re-establishes it during the
|
||||
// sweep when the sphere bottom is within EPSILON of the terrain
|
||||
// plane — so for grounded motion the plane is set fresh every
|
||||
// resolve, and for airborne motion no plane interferes.
|
||||
// A6.P3 slice 2 (2026-05-22) — DO NOT seed ContactPlane at
|
||||
// transition start. Retail's CTransition::init at 0x509dd0
|
||||
// (acclient_2013_pseudo_c.txt:271954) explicitly clears
|
||||
// contact_plane_valid = 0 — retail does NOT seed. Cross-tick
|
||||
// CP retention flows via:
|
||||
// - Mechanism A: BSPQuery.FindCollisions Path-6 land write
|
||||
// (writes ContactPlane during the sub-step loop when the
|
||||
// sphere ground-contacts a floor poly)
|
||||
// - Mechanism B: Transition.ValidateTransition LKCP restore
|
||||
// (slice 1 commit 5aba071; restores ContactPlane from
|
||||
// LastKnownContactPlane post-sub-step when sphere close to
|
||||
// LKCP)
|
||||
// - Body persist below: at transition end, body.ContactPlane
|
||||
// gets set from ci.ContactPlane OR ci.LastKnownContactPlane
|
||||
// so the NEXT tick's body state is preserved.
|
||||
//
|
||||
// We KEEP the seeding when isOnGround for slope-walking
|
||||
// continuity (the original concern that motivated the seed) —
|
||||
// walking up a hill needs the previous step's slope to project
|
||||
// movement properly. Airborne / jumping must start with no
|
||||
// plane so AdjustOffset preserves Z.
|
||||
if (isOnGround && body is not null && body.ContactPlaneValid)
|
||||
{
|
||||
transition.CollisionInfo.SetContactPlane(
|
||||
body.ContactPlane,
|
||||
body.ContactPlaneCellId,
|
||||
body.ContactPlaneIsWater);
|
||||
}
|
||||
// Cost: AdjustOffset on sub-step 1 of each tick has no CP and
|
||||
// takes the "no contact plane" path (TransitionTypes.cs:2329-2334)
|
||||
// — slide-projects only, no slope-snap. Sub-steps 2+ pick up CP
|
||||
// from Mechanism A / B as normal. Imperceptible in practice.
|
||||
//
|
||||
// Removing this seed closes issue #96 (per-tick CP-write blowup;
|
||||
// 99.3% of post-slice-1 CP writes came from the seed) and is
|
||||
// hypothesized to close issue #97 (phantom collisions +
|
||||
// fall-through; suspected stale-CP slope-snap was the cause).
|
||||
//
|
||||
// Previous K-fix7 seed (2026-04-26 to slice-1 ship) deliberately
|
||||
// diverged from retail for "slope-walking continuity" but the
|
||||
// tradeoff (per-tick CP writes, stale-CP slope-snap) was not
|
||||
// worth it.
|
||||
|
||||
// Retail CPhysicsObj::get_object_info also seeds SlidingNormal when
|
||||
// transient_state has bit 2 set. This matters for one-step/frame hits:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue