From 1c2e6fba2b04b329a8b14dc18755822dcf65a542 Mon Sep 17 00:00:00 2001 From: BruceChen Date: Sat, 25 Apr 2026 18:43:18 +0000 Subject: [PATCH] pathing: tighten diagonal step-descend and Descend-carry runway * JumpFeasibility.EvaluateStepDescend now requires BOTH cardinal shoulder columns to be passable. Axis-separated collision resolution at the corner zeros one velocity component when a shoulder is walled, sliding the bot straight down past the intended diagonal landing into a multi-block fall-through (observed on the 251 -> 244 route around (249,136,207)). * ParkourFeasibility now distinguishes Parkour-carry from Descend-carry for flat (yDelta == 0) jumps. A Descend often overshoots the takeoff block, killing the sprint runway the SprintJumpTemplate needs to reach 5 c2c. Treat Descend-carry like a cold start: 3.5 m threshold and 2 aligned back-runway blocks. This prevents the planner from picking impossible 5 c2c flat jumps right after a Descend (e.g. (248,122,197) -> (248,122,192)). Verified live on 1.21.11 across all 6 directions between (251.5,141,210.5), (252.5,138,220.5) and (244.5,122,188.5): 0 replans, 0 segment failures, no mid-path stalls. Made-with: Cursor --- .../Pathing/Moves/JumpFeasibility.cs | 13 +++++++++- .../Pathing/Moves/ParkourFeasibility.cs | 26 ++++++++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/MinecraftClient/Pathing/Moves/JumpFeasibility.cs b/MinecraftClient/Pathing/Moves/JumpFeasibility.cs index 86793c45..8054402f 100644 --- a/MinecraftClient/Pathing/Moves/JumpFeasibility.cs +++ b/MinecraftClient/Pathing/Moves/JumpFeasibility.cs @@ -242,7 +242,18 @@ internal static class JumpFeasibility bool pathViaZ = ctx.CanWalkThrough(x, y, z + dz) && ctx.CanWalkThrough(x, y + 1, z + dz); - if (!pathViaX && !pathViaZ) + // A diagonal Step descend forces the player off the corner of the + // current standing block. Vanilla axis-separated collision resolves + // -X and -Z movement independently: when ONE cardinal shoulder is + // blocked by a wall, the matching velocity component is zeroed and + // the bot slides along the open axis only. If the open-axis column + // (e.g. (x, y-1, z+dz) when only pathViaZ is clear) lacks a floor, + // the bot falls straight down past the intended landing block at + // (x+dx, y-2, z+dz) into whatever solid surface lies further below + // — exactly the multi-block fall-through observed on the 251→244 + // route around (249,136,207). Require BOTH shoulder columns to be + // passable so the bot can actually clear the corner diagonally. + if (!pathViaX || !pathViaZ) { result.SetImpossible(); return; diff --git a/MinecraftClient/Pathing/Moves/ParkourFeasibility.cs b/MinecraftClient/Pathing/Moves/ParkourFeasibility.cs index 480a92fd..60d483ff 100644 --- a/MinecraftClient/Pathing/Moves/ParkourFeasibility.cs +++ b/MinecraftClient/Pathing/Moves/ParkourFeasibility.cs @@ -47,13 +47,27 @@ internal static class ParkourFeasibility { double horiz = Math.Sqrt(xOffset * xOffset + zOffset * zOffset); bool carriedEntry = ctx.PreviousMoveType is MoveType.Parkour or MoveType.Descend; + + // Sprint-momentum carry semantics for flat (yDelta == 0) parkour: + // * Parkour-carry: the previous move's airborne sprint is preserved + // cleanly through landing, so a chained 5 c2c flat parkour can + // fire immediately from the takeoff edge. + // * Descend-carry: the previous Descend often overshoots the + // takeoff block by ~0.5 m (the bot lands inside the takeoff + // block but already past the leading edge), eating the runway + // the SprintJumpTemplate needs to spin sprint back up. In + // practice this lets the bot launch with sub-12-tick momentum + // and short-fall the 5 c2c gap by ~0.7 m. Treat Descend-carry + // as a cold start for flat run-up so the planner inserts an + // explicit traverse runway or picks a shorter parkour. + bool parkourCarry = ctx.PreviousMoveType == MoveType.Parkour; double threshold = yDelta switch { > 0 when carriedEntry => 4.5, > 0 => 2.5, < 0 when carriedEntry => 5.5, < 0 => 3.5, - _ when carriedEntry => 5.5, + _ when parkourCarry => 5.5, _ => 3.5, }; if (horiz < threshold) @@ -67,14 +81,14 @@ internal static class ParkourFeasibility // Long flat sprint parkour (5 c2c, horiz~5) requires the player to be // launched at full vanilla sprint velocity (~12 momentum ticks). A - // standing-jump cold start only reaches gap=3 (=4 c2c). When the - // previous move is not a momentum-carrying Parkour/Descend, one back - // block of runway is not enough to spin sprint up; demand at least - // two aligned back blocks so the executor has a real run-up window. + // standing-jump cold start only reaches gap=3 (=4 c2c). Without a + // clean Parkour-carry, one back block of runway is not enough to + // spin sprint up; demand at least two aligned back blocks so the + // executor has a real run-up window. // tools/sim_jump_reach.py "Standing sprint jump (0t momentum)" matrix // shows gap=4 dy=0 is unreachable, while 12t-momentum gap=4 reaches // 5.1075 m. - int requiredBackBlocks = (yDelta == 0 && !carriedEntry && horiz >= 4.5) ? 2 : 1; + int requiredBackBlocks = (yDelta == 0 && !parkourCarry && horiz >= 4.5) ? 2 : 1; for (int i = 1; i <= requiredBackBlocks; i++) {