From 228eecbb31bb5fd828fee9f49a843f1ba84512c5 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 12 Apr 2026 15:27:49 +0200 Subject: [PATCH] =?UTF-8?q?chore(app):=20Phase=20B.2=20=E2=80=94=20strip?= =?UTF-8?q?=20diagnostic=20logging=20+=20fix=20indoor-transition=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes all [PLAYER], [PLAYER-INIT], [PLAYER-ANIM] diagnostic dump lines now that walking, camera, and animation are verified working. Updates PhysicsEngineTests.Resolve_EnterIndoorCell to match the new behavior (outdoor→indoor transition disabled in the B.2 MVP): the test now asserts the player stays outdoor at terrain Z instead of transitioning to the indoor cell. 265 tests green. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/AcDream.App/Rendering/GameWindow.cs | 26 +++++-------------- .../Physics/PhysicsEngineTests.cs | 14 ++++++---- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/AcDream.App/Rendering/GameWindow.cs b/src/AcDream.App/Rendering/GameWindow.cs index 9c23303..124edb4 100644 --- a/src/AcDream.App/Rendering/GameWindow.cs +++ b/src/AcDream.App/Rendering/GameWindow.cs @@ -220,11 +220,6 @@ public sealed class GameWindow : IDisposable 1f - 2f * (q.Y * q.Y + q.Z * q.Z)); _playerController.Yaw = yaw; - Console.WriteLine($"[PLAYER-INIT] entityPos=({playerEntity.Position.X:F1},{playerEntity.Position.Y:F1},{playerEntity.Position.Z:F1}) " + - $"entityRot=({q.X:F3},{q.Y:F3},{q.Z:F3},{q.W:F3}) " + - $"initCellId=0x{(pinitCellId & 0xFFFFu):X4} " + - $"yaw={yaw:F3} " + - $"physics landblocks={_physicsEngine.LandblockCount}"); _chaseCamera = new AcDream.App.Rendering.ChaseCamera { Aspect = _window!.Size.X / (float)_window.Size.Y, @@ -1505,16 +1500,6 @@ public sealed class GameWindow : IDisposable var result = _playerController.Update((float)dt, input); - // DIAG: dump player state every ~60 frames to see what's happening. - if (_perfFrameCount % 60 == 0) - { - Console.WriteLine($"[PLAYER] pos=({result.Position.X:F1},{result.Position.Y:F1},{result.Position.Z:F1}) " + - $"cell=0x{result.CellId:X8} ground={result.IsOnGround} " + - $"yaw={_playerController.Yaw:F2} " + - $"fwdCmd={result.ForwardCommand?.ToString("X8") ?? "idle"} " + - $"stateChanged={result.MotionStateChanged}"); - } - // Update the player entity's position + rotation so it renders at // the physics-resolved location each frame. if (_entitiesByServerGuid.TryGetValue(_playerServerGuid, out var pe)) @@ -1812,16 +1797,19 @@ public sealed class GameWindow : IDisposable _animatedEntities[pe.Id] = ae; } + // The motion table cycle key is (style << 16) | (command & 0xFFFFFF). + // Without a stance override, the resolver uses the table default + // (which always maps to the idle/Ready cycle regardless of command). + // Pass the NonCombat stance (0x003D) so the resolver builds the + // correct cycle key for walk/run/turn commands. ushort cmdOverride = (ushort)(animCommand & 0xFFFFu); + const ushort NonCombatStance = 0x003D; var cycle = AcDream.Core.Meshing.MotionResolver.GetIdleCycle( ae.Setup, _dats, motionTableIdOverride: _playerMotionTableId, + stanceOverride: NonCombatStance, commandOverride: cmdOverride); - Console.WriteLine($"[PLAYER-ANIM] cmd=0x{animCommand:X8} cmdOverride=0x{cmdOverride:X4} " + - $"cycle={(cycle is null ? "NULL" : $"fr={cycle.Framerate:F1} low={cycle.LowFrame} high={cycle.HighFrame}")} " + - $"setup=0x{pe.SourceGfxObjOrSetupId:X8} mtable=0x{(uint)ae.Setup.DefaultMotionTable:X8}"); - if (cycle is null || cycle.Framerate == 0f || cycle.HighFrame <= cycle.LowFrame) return; ae.Animation = cycle.Animation; diff --git a/tests/AcDream.Core.Tests/Physics/PhysicsEngineTests.cs b/tests/AcDream.Core.Tests/Physics/PhysicsEngineTests.cs index 10b92b8..543555c 100644 --- a/tests/AcDream.Core.Tests/Physics/PhysicsEngineTests.cs +++ b/tests/AcDream.Core.Tests/Physics/PhysicsEngineTests.cs @@ -91,12 +91,16 @@ public class PhysicsEngineTests } [Fact] - public void Resolve_EnterIndoorCell_TransitionsToCell() + public void Resolve_EnterIndoorCell_StaysOutdoor_BecauseTransitionDisabled() { + // Phase B.2 MVP: outdoor→indoor transitions are disabled because + // CellSurface floor polygons are too aggressive (building + // footprints/roofs capture the player). Walking over a cell's XY + // area stays on the outdoor terrain Z. Indoor transitions will be + // re-enabled when portal-based detection lands in Phase E. var engine = new PhysicsEngine(); var terrain = new TerrainSurface(FlatHeightmap(50), LinearHeightTable()); - // Indoor cell with a floor at Z=55 covering (40..60, 40..60). var cellVerts = new Dictionary { [0] = new(40f, 40f, 55f), @@ -115,9 +119,9 @@ public class PhysicsEngineTests new Vector3(30f, 50f, 50f), cellId: 0x0001, delta: new Vector3(20f, 0f, 0f), stepUpHeight: 10f); - // Should transition to the indoor cell and snap to its floor Z. - Assert.Equal(0x0100u, result.CellId); - Assert.Equal(55f, result.Position.Z, precision: 1); + // Should stay outdoor (transition disabled) at terrain Z = 50. + Assert.True(result.CellId < 0x0100u); + Assert.Equal(50f, result.Position.Z, precision: 1); Assert.True(result.IsOnGround); }