From 5f2e2e28ff9bfd8e945cba0263cb07f6dec10f61 Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 5 May 2026 21:51:12 +0200 Subject: [PATCH] docs(issues): close #42 (self-skip ec59a08), file + close #43 staircase (9e4772a) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #42 — moved from OPEN to DONE in place (rich investigation log preserved below the new Resolution block). The originally-listed mechanisms (H1 slope-driven AdjustOffset projection, H2 step-down probe, H3 EdgeSlide) were all RULED OUT by the first evidence run; root cause was self- collision in FindObjCollisions, not in-sweep mechanism choice. Added forward-pointer to retail's CObjCell::find_obj_collisions self-skip (named-retail acclient_2013_pseudo_c.txt:308931). #43 — new entry in Recently closed for the slope staircase on grounded player remotes. Diagnosis: PositionManager.ComputeOffset's seqVel-only fallback returned flat-Z motion because anim cycles bake Z=0 body-local, producing visible 5 Hz Z stepping at the server-UP cadence. Fix: project the fallback onto the local terrain plane (mirrors retail's CTransition::adjust_offset contact-plane projection at the queue-empty boundary). Verified via 9193 queue-empty-with-non-zero-offset.Z ticks across a 34m vertical traversal. Both diagnostic env-vars kept in tree for future regression hunts: ACDREAM_AIRBORNE_DIAG=1 and ACDREAM_SLOPE_DIAG=1. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/ISSUES.md | 93 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 3 deletions(-) diff --git a/docs/ISSUES.md b/docs/ISSUES.md index bdce230..11173ad 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -124,12 +124,52 @@ the same direction. Add a `LastUMUpdateTime` grace window (e.g. - No spurious cycle thrashing during turning while running (ObservedOmega doesn't trigger velocity-bucket changes). -## #42 — Airborne XY drift on observed player remote jumps (~1 m horizontal offset over arc) +## #42 — [DONE 2026-05-05 · ec59a08] Airborne XY drift on observed player remote jumps (~1 m horizontal offset over arc) -**Status:** OPEN +**Status:** DONE **Severity:** MEDIUM (pre-existing PhysicsEngine bug; exposed by L.3 M2 airborne UP no-op + M4 CellId fix) **Filed:** 2026-05-05 (root cause confirmed same day) -**Component:** physics (`PhysicsEngine.ResolveWithTransition` airborne behavior) +**Closed:** 2026-05-05 +**Commit:** `ec59a08` +**Component:** physics (`PhysicsEngine.ResolveWithTransition` → `FindObjCollisions` self-skip) + +**Resolution (2026-05-05):** Self-collision in `FindObjCollisions`, not +any of the three originally-hypothesised mechanisms below. Live +entities (local player, remotes) register a Cylinder in +`ShadowObjectRegistry` at spawn (`GameWindow.cs:2545`) which +`UpdatePosition` keeps tracking the entity's live world position. +With no self-skip filter, the moving sphere's own cylinder is always +sitting at the body's exact position and `CylinderCollision` slides +the sphere out of overlap on every airborne tick. Validated by the +[SWEEP-OBJ] diagnostic added in commit `a36369d`: every drift event +showed `gfxObj=0x02000001` (humanoid setup) at `obj.Position` exactly +matching the body's `pre`. Mirrors retail's `CObjCell::find_obj_collisions` +self-skip at named-retail line 308931: + +```c +if ((physobj->parent == 0 && physobj != arg2->object_info.object)) + result = CPhysicsObj::FindObjCollisions(physobj, arg2); +``` + +Plumbing: `ObjectInfo.SelfEntityId` field, optional +`movingEntityId = 0` parameter on `ResolveWithTransition`, +`PlayerMovementController.LocalEntityId` refreshed per-tick from +`_entitiesByServerGuid[_playerServerGuid].Id`, remote sweep at +`GameWindow.cs:6474` passes `kv.Key`. Lock-the-fix unit test at +`PhysicsEngineTests.ResolveWithTransition_SelfShadowEntry_NotPushedWhenIdMatches`. + +Verified via two visual + log runs (`launch-42-verify.log` / +`launch-42-verify2.log`): zero stationary-jump drift across both, +`gfxObj=0x02000001` phantom no longer appears in `[SWEEP-OBJ]`, +no >0.5m pushes anywhere. The originally-listed hypotheses (H1 +slope-driven AdjustOffset projection, H2 step-down probe, H3 +EdgeSlide) were all RULED OUT by the first evidence run — `cpN` +was `(0, 0, 1)` flat for every drift event. + +**Diagnostic kept in tree:** `ACDREAM_AIRBORNE_DIAG=1` enables the +`[SWEEP]` + `[SWEEP-OBJ]` traces for future regression hunts. + +The original investigation log is preserved below for context. **Root cause (verified 2026-05-05 via A/B test):** @@ -1188,6 +1228,53 @@ If hypothesis (a) is correct, this issue effectively rolls into **#28** — the # Recently closed +## #43 — [DONE 2026-05-05 · 9e4772a] Slope staircase on observed player remotes (anim-only fallback ignored slope) + +**Closed:** 2026-05-05 +**Commit:** `9e4772a` +**Component:** motion (`PositionManager.ComputeOffset` queue-empty fallback) + +**Resolution:** Grounded player remotes showed a ~5 Hz Z staircase when +running up/down hills. `PositionManager.ComputeOffset` has two modes: +queue-active (3D direction toward server's broadcast position, Z +follows naturally) and queue-empty / head-reached (`seqVel × dt` +rotated into world). Every locomotion cycle bakes Z=0 in body-local, +so the world result has Z=0 too. With server UPs at ~5 Hz and +catchUpSpeed = 2× maxSpeed, body chases each waypoint in ~100ms (Z +ramps), then sits in seqVel-only mode for ~100ms (Z flat) until the +next UP. Visible 5 Hz staircase. + +Fix mirrors retail's `CTransition::adjust_offset` contact-plane +projection (named-retail acclient_2013_pseudo_c.txt:272296-272346), +applied at the queue-empty boundary instead of inside the sweep. +`ComputeOffset` gains an optional `Vector3? terrainNormal`; when +the seqVel fallback runs and the supplied normal is non-trivial, +`rootMotionWorld -= N × dot(rootMotionWorld, N)`. XY motion gains a +Z component proportional to slope × forward speed; body Z follows the +terrain mesh between UPs. No-op on flat ground (N ≈ +Z, dot ≈ 0) so +no regression to L.3 M2's flat-ground verification. + +`GameWindow.TickAnimations` grounded-remote path samples +`PhysicsEngine.SampleTerrainNormal` (a thin public wrapper over the +existing internal `SampleTerrainWalkable`) at the body's current XY +each tick and passes it to `ComputeOffset`. + +Two unit tests in `PositionManagerTests`: 30° east-tilted slope +(asserts `(3.0, 0, −1.732)` for 4 m/s east motion over 1s — body +descends along slope) + flat-ground no-op (asserts unchanged +behaviour with `N = +Z`). + +Verified via `launch-slope-verify.log` over a 34m vertical traversal: +9,193 queue-empty-with-non-zero-offset.Z ticks on slopes (the path +that previously stair-cased), 26,497 sloped-normal ticks total, zero +#42 regressions. + +**Diagnostic kept in tree:** `ACDREAM_SLOPE_DIAG=1` enables the +`[SLOPE]` per-tick trace (`bodyZ` before/after, offset, queue active, +sampled `cpN.Z`) for future regression hunts. + +--- + ## #31 — [DONE 2026-04-29] Low outdoor cell id can go stale after transition movement **Closed:** 2026-04-29