feat(phys L.2a slice 1): resolver + cell-transit probes (PhysicsDiagnostics)
New static `AcDream.Core.Physics.PhysicsDiagnostics` holds two runtime-toggleable flags initialized from env vars: - ACDREAM_PROBE_RESOLVE=1 — emit one [resolve] line per PhysicsEngine.ResolveWithTransition call: input/target/output position+cell, ok-vs-partial, grounded-in, contact-plane status, wall normal if hit, walkable-polygon valid, moving entity id. - ACDREAM_PROBE_CELL=1 — emit one [cell-transit] line per PlayerMovementController.CellId change: old → new cell, current world position, reason tag (resolver / teleport). Both also exposed as runtime-toggleable checkboxes in the DebugPanel "Diagnostics" section. Unlike the existing four Dump-* checkboxes (which only mirror sticky-at-startup env vars), the two new ones forward directly to PhysicsDiagnostics — toggling on/off takes effect on the next physics resolve, no relaunch. Why now: L.2's plan-of-record (docs/plans/2026-04-29-movement-collision- conformance.md) explicitly says "Land L.2a diagnostics first. Do not make another physics change blind." This slice closes the most-load- bearing gap in L.2a — a general-purpose probe on the resolver outcome and a cell-transit log — so that later L.2b/c/d/e physics changes can be evidence-driven instead of guessed. Foundation for the indoor / dungeon walking trajectory (G.3 unblock). Pure additive: when both flags are off (default), the probes collapse to a single static-bool read per resolve, zero log cost. PlayerMovement Controller's two CellId-mutation sites are now routed through a private UpdateCellId(reason) helper for diag chokepoint. Build green, 1032/1040 unit tests pass. The 8 failing tests are pre-existing on the branch base (verified by stash-and-rerun); none touch resolver or cell-transit code; all fail identically with this slice stashed. Investigation deferred to a follow-up. Refs: docs/plans/2026-04-29-movement-collision-conformance.md (L.2a shipped-slice note added in same commit). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
eab347d7e4
commit
ebef82034e
6 changed files with 151 additions and 10 deletions
|
|
@ -288,12 +288,29 @@ public sealed class PlayerMovementController
|
|||
_motion.apply_current_movement(cancelMoveTo: false, allowJump: false);
|
||||
}
|
||||
|
||||
// L.2a slice 1 (2026-05-12): centralized CellId mutation so the
|
||||
// [cell-transit] probe fires from a single chokepoint. Both the
|
||||
// server-snap path (SetPosition) and the per-frame resolver path
|
||||
// route through here. When PhysicsDiagnostics.ProbeCellEnabled is
|
||||
// off this collapses to a single bool-compare + assignment — zero
|
||||
// logging cost.
|
||||
private void UpdateCellId(uint newCellId, string reason)
|
||||
{
|
||||
if (newCellId != CellId && PhysicsDiagnostics.ProbeCellEnabled)
|
||||
{
|
||||
var pos = _body.Position;
|
||||
Console.WriteLine(System.FormattableString.Invariant(
|
||||
$"[cell-transit] 0x{CellId:X8} -> 0x{newCellId:X8} pos=({pos.X:F3},{pos.Y:F3},{pos.Z:F3}) reason={reason}"));
|
||||
}
|
||||
CellId = newCellId;
|
||||
}
|
||||
|
||||
public void SetPosition(Vector3 pos, uint cellId)
|
||||
{
|
||||
_body.Position = pos;
|
||||
_prevPhysicsPos = pos;
|
||||
_currPhysicsPos = pos;
|
||||
CellId = cellId;
|
||||
UpdateCellId(cellId, "teleport");
|
||||
|
||||
// Treat as grounded after a server-side position snap.
|
||||
_body.TransientState = TransientStateFlags.Contact | TransientStateFlags.OnWalkable;
|
||||
|
|
@ -760,7 +777,7 @@ public sealed class PlayerMovementController
|
|||
|
||||
|
||||
_wasAirborneLastFrame = !_body.OnWalkable;
|
||||
CellId = resolveResult.CellId;
|
||||
UpdateCellId(resolveResult.CellId, "resolver");
|
||||
|
||||
// ── 6. Determine outbound motion commands ─────────────────────────────
|
||||
uint? outForwardCmd = null;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue