fix(physics): L.2.3a — retail-realistic step heights (was 5m up, 4cm down)
Two values were producing weird live-test behavior: - PlayerMovementController.StepUpHeight default = 5.0f (5 meters) and GameWindow's fallback = 2.0f. With these, walking horizontally into a steep slope let the step-up scan find walkable polygons up to 5m away, which often included a small building's flat top. The player visually "teleported" up onto the roof and then could walk on surfaces they should have just slid off. - stepDownHeight was hardcoded 0.04f (4 cm) in two ResolveWithTransition call sites. A typical stair step is 15–25 cm tall, so when the player walked off the top of a stair onto level ground, the step-down probe didn't reach the next surface. For one frame the contact plane was invalid → ValidateTransition cleared OnWalkable → animation flickered to falling → next frame gravity dropped + terrain found. Visible 1-frame flicker reported as "small falling animation when reaching stair top." Retail's Setup.step_up_height and Setup.step_down_height for human characters are both ~0.4 m. Sourcing them from the player's Setup (already cached in PhysicsDataCache) with a 0.4 m fallback when the field is missing. Files: - PlayerMovementController.cs:104 — StepUpHeight default 5.0 → 0.4 - PlayerMovementController.cs (new) — StepDownHeight property, default 0.4 - PlayerMovementController.cs:414 — pass StepDownHeight from controller - GameWindow.cs:7019-7036 — read Setup.StepDownHeight + reduce fallbacks - GameWindow.cs:5759 — remote dead-reckoning: 2.0/0.04 → 0.4/0.4 No test changes; existing 12 BSPStepUp tests still cover the value flow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
670f892bd3
commit
b2aaac4e52
2 changed files with 34 additions and 10 deletions
|
|
@ -5755,8 +5755,8 @@ public sealed class GameWindow : IDisposable
|
|||
preIntegratePos, postIntegratePos, rm.CellId,
|
||||
sphereRadius: 0.48f,
|
||||
sphereHeight: 1.2f,
|
||||
stepUpHeight: 2.0f, // retail default for unknown remotes
|
||||
stepDownHeight: 0.04f, // PhysicsGlobals.DefaultStepHeight
|
||||
stepUpHeight: 0.4f, // L.2.3a: retail human-scale, was 2.0f
|
||||
stepDownHeight: 0.4f, // L.2.3a: retail human-scale, was 0.04f
|
||||
// K-fix9 (2026-04-26): mirror the K-fix7 gate —
|
||||
// airborne remotes must NOT pre-seed the
|
||||
// ContactPlane, otherwise AdjustOffset's snap-to-plane
|
||||
|
|
@ -7016,7 +7016,13 @@ public sealed class GameWindow : IDisposable
|
|||
_playerController.SetCharacterSkills(_lastSeenRunSkill, _lastSeenJumpSkill);
|
||||
Console.WriteLine($"live: {loggingTag} — applied server skills run={_lastSeenRunSkill} jump={_lastSeenJumpSkill}");
|
||||
}
|
||||
// Read the real step height from the player's Setup dat.
|
||||
// Read the real step heights from the player's Setup dat.
|
||||
// L.2.3a (2026-04-29): retail's Setup.StepUpHeight for humans is
|
||||
// ~0.4 m, NOT 2 m. With 2 m fallback the step-up scan reached
|
||||
// small-building roofs and teleported the player onto them. Same
|
||||
// for StepDownHeight — was hardcoded 0.04 m, causing stair-top
|
||||
// contact-plane gaps. Both now come from Setup with retail-realistic
|
||||
// 0.4 m fallbacks.
|
||||
if (_dats is not null && (playerEntity.SourceGfxObjOrSetupId & 0xFF000000u) == 0x02000000u)
|
||||
{
|
||||
var playerSetup = _dats.Get<DatReaderWriter.DBObjs.Setup>(playerEntity.SourceGfxObjOrSetupId);
|
||||
|
|
@ -7024,11 +7030,15 @@ public sealed class GameWindow : IDisposable
|
|||
_physicsDataCache.CacheSetup(playerEntity.SourceGfxObjOrSetupId, playerSetup);
|
||||
_playerController.StepUpHeight = (playerSetup is not null && playerSetup.StepUpHeight > 0f)
|
||||
? playerSetup.StepUpHeight
|
||||
: 2f;
|
||||
: 0.4f;
|
||||
_playerController.StepDownHeight = (playerSetup is not null && playerSetup.StepDownHeight > 0f)
|
||||
? playerSetup.StepDownHeight
|
||||
: 0.4f;
|
||||
}
|
||||
else
|
||||
{
|
||||
_playerController.StepUpHeight = 2f;
|
||||
_playerController.StepUpHeight = 0.4f;
|
||||
_playerController.StepDownHeight = 0.4f;
|
||||
}
|
||||
int plbX = _liveCenterX + (int)MathF.Floor(playerEntity.Position.X / 192f);
|
||||
int plbY = _liveCenterY + (int)MathF.Floor(playerEntity.Position.Y / 192f);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue