docs(physics): #347 closed WITHOUT a code change — retail's glide alternates exactly as ours does; AD-70 retired as a wrong inference
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run
The round-2 cdb capture is decisive: during a live retail glide, edge_slide fired ~1.5 times per find_transitional_position — the arm/move alternation's exact signature (3 entries on the arming tick, 0 on the moving tick) — with cliff_slide in lockstep, step_down at 2.5x, step_up 0, and every stack sample on our identical call path. cliff_slide's bytes match our port and ACE's (compare constant at 0x794610 verified 0.0), and the user could not distinguish the two clients side by side. The "retail redirects within the tick" premise misread round-1's set_sliding_normal cadence (per-event, not per-tick, so its 1:1 ratio with edge never discriminated anything). The alternation-tolerant assertion in Issue345SteepSlopeGlideTests is therefore the CORRECT retail-shape pin from both sides; its comment now cites the capture instead of calling the shape a residual. The #269 note is honest the other way: the hope that a within-tick port would explain that feel residual is withdrawn with the premise. The temporary Scratch347 diagnostic is deleted. Capture evidence: 345-glide-stacks.cdb.log (repo root, untracked, cited from the contract's RESOLUTION section). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
535f41bbdf
commit
fa0c053ebf
5 changed files with 44 additions and 78 deletions
|
|
@ -82,9 +82,11 @@ public sealed class Issue345SteepSlopeGlideTests
|
|||
// 28 of 30 here). The fixed glide alternates: the arming tick
|
||||
// absorbs the request while edge-slide sets the sliding normal,
|
||||
// the next tick consumes it and moves (14 of 30 stuck). The
|
||||
// alternation itself is a KNOWN half-rate residual vs retail's
|
||||
// within-tick redirect (#347) — this assertion only rejects the
|
||||
// dead loop. Stuck ticks are counted from positions, not the
|
||||
// alternation IS retail's own shape — confirmed by the #347
|
||||
// round-2 cdb capture (345-glide-stacks.cdb.log: ~1.5 edge_slide
|
||||
// per find_transitional_position during a live glide, the
|
||||
// alternation's exact signature) — so this range pins it from
|
||||
// both sides. Stuck ticks are counted from positions, not the
|
||||
// (temporary) transit-fail probe, so the assertion survives the
|
||||
// probe family's eventual strip; the lower bound keeps it from
|
||||
// going vacuous if the fixture stops engaging the face at all.
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using AcDream.Core.Physics;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace AcDream.Core.Tests.Physics;
|
||||
|
||||
// TEMPORARY #347 diagnostic — deleted before landing.
|
||||
public sealed class Scratch347DiagTests
|
||||
{
|
||||
private readonly ITestOutputHelper _out;
|
||||
public Scratch347DiagTests(ITestOutputHelper output) => _out = output;
|
||||
|
||||
[Fact]
|
||||
public void DumpFirstArmingTick()
|
||||
{
|
||||
var heights = new byte[81];
|
||||
heights[3 * 9 + 4] = 32;
|
||||
var heightTable = new float[256];
|
||||
for (int i = 0; i < 256; i++) heightTable[i] = i;
|
||||
|
||||
var engine = new PhysicsEngine();
|
||||
engine.AddLandblock(0xA9B4FFFFu, new TerrainSurface(heights, heightTable),
|
||||
Array.Empty<CellSurface>(), Array.Empty<PortalPlane>(), 0f, 0f);
|
||||
|
||||
var body = new PhysicsBody
|
||||
{
|
||||
State = PhysicsStateFlags.Gravity,
|
||||
TransientState = TransientStateFlags.Active | TransientStateFlags.Contact | TransientStateFlags.OnWalkable,
|
||||
};
|
||||
|
||||
float dx = 0f, dy = 0.23f;
|
||||
var position = new Vector3(80.4f, 79.8f, 0f);
|
||||
uint cell = TerrainSurface.ComputeOutdoorCellId(0xA9B4FFFFu, 80.4f, 79.8f);
|
||||
|
||||
PhysicsDiagnostics.DumpTransitFailEnabled = true;
|
||||
var saved = Console.Out;
|
||||
var sw = new StringWriter();
|
||||
Console.SetOut(sw);
|
||||
try
|
||||
{
|
||||
for (int tick = 0; tick < 3; tick++)
|
||||
{
|
||||
var result = engine.ResolveWithTransition(
|
||||
currentPos: position,
|
||||
targetPos: new Vector3(position.X + dx, position.Y + dy, position.Z),
|
||||
cellId: cell,
|
||||
sphereRadius: 0.47f,
|
||||
sphereHeight: 1.20f,
|
||||
stepUpHeight: 0.60f,
|
||||
stepDownHeight: 1.50f,
|
||||
isOnGround: true,
|
||||
body: body,
|
||||
moverFlags: ObjectInfoState.IsPlayer | ObjectInfoState.EdgeSlide,
|
||||
movingEntityId: 0x5000000Au);
|
||||
position = result.Position;
|
||||
cell = result.CellId;
|
||||
if (tick < 2) sw.GetStringBuilder().Clear(); // keep only the arming tick
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(saved);
|
||||
PhysicsDiagnostics.DumpTransitFailEnabled = false;
|
||||
}
|
||||
|
||||
foreach (var line in sw.ToString().Split('\n'))
|
||||
_out.WriteLine(line.TrimEnd());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue