From deb1bc47ccef03bcca9e13e24d43160e6118e6d9 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 11 Apr 2026 02:13:48 +0800 Subject: [PATCH] refactor: clean up debug logging in pathfinder and pathfind command Remove verbose per-node insertion tracking from A*. Keep essential logging: start, goal reached, partial/failed results. Clean up pathfind command with exception handling and cleaner output. Made-with: Cursor --- MinecraftClient/Commands/Pathfind.cs | 64 +++++++------------ .../Pathing/Core/AStarPathFinder.cs | 18 ------ 2 files changed, 23 insertions(+), 59 deletions(-) diff --git a/MinecraftClient/Commands/Pathfind.cs b/MinecraftClient/Commands/Pathfind.cs index 23a16285..50eade55 100644 --- a/MinecraftClient/Commands/Pathfind.cs +++ b/MinecraftClient/Commands/Pathfind.cs @@ -70,50 +70,32 @@ namespace MinecraftClient.Commands { try { - handler.Log.Info($"[Pathfind] Diagnosing blocks around start ({startX},{startY},{startZ}):"); - for (int ddx = -1; ddx <= 1; ddx++) + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); + var result = finder.Calculate(ctx, startX, startY, startZ, goalObj, cts.Token, timeoutMs: 10000); + + handler.Log.Info($"[Pathfind] Result: {result.Status}, {result.Path.Count} nodes, " + + $"{result.NodesExplored} explored, {result.ElapsedMs}ms"); + + if (result.Path.Count > 1) { - for (int ddz = -1; ddz <= 1; ddz++) + handler.Log.Info("[Pathfind] Path waypoints:"); + for (int i = 0; i < result.Path.Count; i++) { - int tx = startX + ddx, tz = startZ + ddz; - var below = ctx.GetMaterial(tx, startY - 1, tz); - var body = ctx.GetMaterial(tx, startY, tz); - var head = ctx.GetMaterial(tx, startY + 1, tz); - bool canOn = ctx.CanWalkOn(tx, startY - 1, tz); - bool canThru = ctx.CanWalkThrough(tx, startY, tz); - bool canThruH = ctx.CanWalkThrough(tx, startY + 1, tz); - handler.Log.Info($" ({tx},{tz}): below={below}(walkOn={canOn}) body={body}(thru={canThru}) head={head}(thru={canThruH})"); + var n = result.Path[i]; + handler.Log.Info($" [{i}] ({n.X},{n.Y},{n.Z}) via {n.MoveUsed}"); } + + handler.Log.Info("[Pathfind] Beginning movement along path..."); + FollowPath(handler, result); + } + else + { + handler.Log.Warn("[Pathfind] No path found!"); } - handler.Log.Info($"[Pathfind] ChunkLoaded at start: {ctx.IsChunkLoaded(startX, startZ)}"); - handler.Log.Info($"[Pathfind] ChunkLoaded at goal: {ctx.IsChunkLoaded(goalX, goalZ)}"); } catch (Exception ex) { - handler.Log.Warn($"[Pathfind] Diagnostic exception: {ex.Message}"); - } - - using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); - var result = finder.Calculate(ctx, startX, startY, startZ, goalObj, cts.Token, timeoutMs: 10000); - - handler.Log.Info($"[Pathfind] Result: {result.Status}, {result.Path.Count} nodes, " + - $"{result.NodesExplored} explored, {result.ElapsedMs}ms"); - - if (result.Path.Count > 0) - { - handler.Log.Info("[Pathfind] Path waypoints:"); - for (int i = 0; i < result.Path.Count; i++) - { - var n = result.Path[i]; - handler.Log.Info($" [{i}] ({n.X},{n.Y},{n.Z}) via {n.MoveUsed}"); - } - - handler.Log.Info("[Pathfind] Beginning movement along path..."); - FollowPath(handler, result); - } - else - { - handler.Log.Warn("[Pathfind] No path found!"); + handler.Log.Warn($"[Pathfind] Exception: {ex.Message}"); } }); @@ -127,12 +109,12 @@ namespace MinecraftClient.Commands var node = result.Path[i]; var target = new Location(node.X + 0.5, node.Y, node.Z + 0.5); - handler.Log.Info($"[Pathfind] Moving to waypoint [{i}]: ({node.X},{node.Y},{node.Z}) via {node.MoveUsed}"); + handler.Log.Info($"[Pathfind] Moving to waypoint [{i}/{result.Path.Count - 1}]: ({node.X},{node.Y},{node.Z}) via {node.MoveUsed}"); bool success = handler.MoveTo(target, allowUnsafe: true, allowDirectTeleport: false, timeout: TimeSpan.FromSeconds(10)); if (!success) { - handler.Log.Warn($"[Pathfind] Old pathfinder failed to plan sub-path to ({node.X},{node.Y},{node.Z}), trying direct teleport"); + handler.Log.Warn($"[Pathfind] Sub-path failed for waypoint [{i}], using direct move"); handler.MoveTo(target, allowUnsafe: true, allowDirectTeleport: true); } @@ -147,9 +129,9 @@ namespace MinecraftClient.Commands var cur = handler.GetCurrentLocation(); double dx = cur.X - target.X; double dz = cur.Z - target.Z; - double horizDistSq = dx * dx + dz * dz; + double horizDist = Math.Sqrt(dx * dx + dz * dz); - handler.Log.Info($"[Pathfind] Arrived near waypoint [{i}], pos=({cur.X:F2},{cur.Y:F2},{cur.Z:F2}), horizDist={Math.Sqrt(horizDistSq):F2}"); + handler.Log.Info($"[Pathfind] Waypoint [{i}] done, pos=({cur.X:F2},{cur.Y:F2},{cur.Z:F2}), dist={horizDist:F2}"); } handler.Log.Info("[Pathfind] Path execution complete!"); diff --git a/MinecraftClient/Pathing/Core/AStarPathFinder.cs b/MinecraftClient/Pathing/Core/AStarPathFinder.cs index f58dac28..05f4dde9 100644 --- a/MinecraftClient/Pathing/Core/AStarPathFinder.cs +++ b/MinecraftClient/Pathing/Core/AStarPathFinder.cs @@ -96,9 +96,6 @@ namespace MinecraftClient.Pathing.Core current.IsClosed = true; nodesExplored++; - if (nodesExplored <= 10) - DebugLog?.Invoke($"[A*] Expand #{nodesExplored}: ({current.X},{current.Y},{current.Z}) F={current.FCost:F2} G={current.GCost:F2} H={current.HCost:F2}, openSet={openSet.Count}"); - if (goal.IsInGoal(current.X, current.Y, current.Z)) { DebugLog?.Invoke($"[A*] Goal reached! {nodesExplored} nodes, {sw.ElapsedMilliseconds}ms"); @@ -111,15 +108,6 @@ namespace MinecraftClient.Pathing.Core moveResult.Cost = 0; move.Calculate(ctx, current.X, current.Y, current.Z, ref moveResult); - if (nodesExplored <= 2) - { - if (moveResult.IsImpossible) - DebugLog?.Invoke($"[A*] move {move.Type}({move.XOffset},{move.ZOffset}) from ({current.X},{current.Y},{current.Z}): IMPOSSIBLE"); - else - DebugLog?.Invoke($"[A*] move {move.Type}({move.XOffset},{move.ZOffset}) from ({current.X},{current.Y},{current.Z}): " + - $"-> ({moveResult.DestX},{moveResult.DestY},{moveResult.DestZ}) cost={moveResult.Cost:F2}"); - } - if (moveResult.IsImpossible) continue; @@ -139,8 +127,6 @@ namespace MinecraftClient.Pathing.Core if (nodeMap.TryGetValue(packed, out var neighbor)) { - if (nodesExplored <= 2) - DebugLog?.Invoke($"[A*] EXISTS ({nx},{ny},{nz}) pack={packed} actual=({neighbor.X},{neighbor.Y},{neighbor.Z}) closed={neighbor.IsClosed} tentG={tentativeG:F2} existG={neighbor.GCost:F2}"); if (neighbor.IsClosed) continue; if (tentativeG >= neighbor.GCost) @@ -154,8 +140,6 @@ namespace MinecraftClient.Pathing.Core } else { - if (nodesExplored <= 2) - DebugLog?.Invoke($"[A*] NEW ({nx},{ny},{nz}) pack={packed} G={tentativeG:F2} H={goal.Heuristic(nx, ny, nz):F2}"); neighbor = new PathNode(nx, ny, nz) { GCost = tentativeG, @@ -171,8 +155,6 @@ namespace MinecraftClient.Pathing.Core double partialScore = neighbor.HCost + neighbor.GCost * 0.5; if (partialScore < bestPartialScore) { - if (nodesExplored <= 3) - DebugLog?.Invoke($"[A*] partial improved: ({neighbor.X},{neighbor.Y},{neighbor.Z}) score={partialScore:F2} < {bestPartialScore:F2}"); bestPartialScore = partialScore; bestPartialNode = neighbor; }