Skip to content

1.8.0-SNAPSHOT: 移动与寻路修复及改进#8

Merged
huangdihd merged 12 commits into
mainfrom
1.8.0-SNAPSHOT
Jun 30, 2026
Merged

1.8.0-SNAPSHOT: 移动与寻路修复及改进#8
huangdihd merged 12 commits into
mainfrom
1.8.0-SNAPSHOT

Conversation

@huangdihd

Copy link
Copy Markdown
Owner

修复

  • walk 停不下来updateMotionTask 的 velocity 丢失更新竞态——物理 tick 改为操作副本并原子合并写回,不再覆盖并发的 WalkMovement.onStop 扣减、跳跃冲量和停止指令
  • 维度索引错位RegistryDataListener 解析 dimension_type registry 时 data 为 null 的条目不再被跳过(known packs 下会导致把下界的 min_y 用到主世界),并对缺失的 min_y/height 键做回退
  • goto 静默失败:找不到完整路径时提示「前往最近可达点」,完全无路时也有提示;坐标支持带逗号;y 上限放宽到 maxWorldY+1(可站在最高方块顶上)

改进

  • follow 防抖与保持半径:目标在保持半径内时不再每 tick 重寻路;默认半径 1 格,PathMovement(path, radius) 重载与 follow <entityId> [keepRadius] 可选参数可自定义
  • 斜向跳坑GapJumpStrategy 新增斜向跳跃边(跨 1 格宽斜向坑,落点 2 格对角)
  • 跳坑冲刺:跳坑段速度 ×1.3,保证斜向 2.83 格落点和直向 2 格宽坑跳得过去;跳坑段开始打一条诊断日志
  • 无方块时跳过搭路策略:新增 addNoPlacementStrategies(),背包没有方块时寻路不再考虑搭桥/垫高边(同时省去每次节点扩展扫背包)
  • 每次重寻路的 "Path NOT found" 警告降为 debug,不再刷屏

🤖 Generated with Claude Code

huangdihd and others added 12 commits June 12, 2026 14:05
- Fix velocity lost-update race in updateMotionTask: physics tick now works
  on a copy and merges its writes atomically instead of overwriting the whole
  vector, so WalkMovement.onStop / jump impulses / stop are no longer eaten
- Fix dimension registry index misalignment in RegistryDataListener (null-data
  entries now keep their slot) and guard missing min_y/height keys
- Follow: stay put within a keep radius instead of repathing every tick;
  default radius 1 block, configurable via new PathMovement(path, radius)
  overload and optional `follow <entityId> [keepRadius]` argument
- GapJumpStrategy: add diagonal gap jump edges (1-wide diagonal hole)
- PathMovement: sprint (1.3x) during gap jump segments so long jumps reach;
  log gap jump segments once for diagnostics
- Goto: tolerate commas in coordinates, allow y up to maxWorldY+1, report
  partial/no-path results instead of failing silently
- Pathfinding without blocks in inventory now skips BridgePillarStrategy via
  new PathfindingContextBuilder.addNoPlacementStrategies()
- Demote per-repath "Path NOT found" warning to debug

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mid-flight the current target node hangs over the gap, so checkAndPlace
would see non-solid ground, find no blocks in the hotbar and kill the
whole path in the middle of the jump.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Edges now carry the MovementType that traverses them, and findPath
returns List<PathStep> (node + how to reach it) instead of bare nodes.
PathMovement executes the type declared by the planner rather than
re-deriving it geometrically; dig/bridge/pillar execution moved into
BuiltinMovementType.createMovement. Plugins can implement MovementType
(with requiresGroundToDispatch for mid-air types) and attach it to
edges from their own strategies. A traversability check on built-in
edges replans when the world changed since planning.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The per-tick "is the target still walkable?" check replanned on every
failure, and a replan resets currentIndex to 0 — whose first target is
the centre of the bot's current block. Mid-step that pulls the bot
backwards, and isStillTraversable's live isSolid/isPassable probes
false-negative often enough (cross-section air reads, non-full ground)
to fire constantly, so the bot kept backing up while walking.

Replace it with progress-based stuck detection: only replan after ~2s
of no horizontal progress toward the target while on the ground. Normal
walking always makes progress, so it never triggers and never yanks the
bot back, while a genuinely blocked path still recovers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ChunkDataListener fires requestRepath() on every nearby block/section
update, and repathInternally() rebuilt the path with currentIndex reset
to 0. Two failures resulted:

- Backing up: newPath[0] is the block the bot already stands in, so
  after any repath the bot first walked back to that block's centre.
  With frequent updates it kept getting yanked back a node.
- Drifting over gaps: a repath mid jump/fall rebuilt from a mid-air
  point, dropping the sprint/jump momentum, so the bot floated across
  a gap instead of clearing it.

Defer external repaths until the bot is back on the ground, and start
the new path at index 1 (skip the block we're standing in) so the bot
heads for the next node — and a gap-jump edge stays the live target.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
findBlock() passed an item id straight into isSolidBlock(int), which
expects a block-state id — two unrelated registries. Empty/air slots and
random items could land on a solid block's state range, so an empty
hotbar was reported as holding placeable blocks. The planner then built
bridge/pillar paths it couldn't execute, spamming "NO BLOCKS" and
walking the bot into gaps.

Resolve the item id to its registry name via ItemRegistry, then look the
block up by name with the new BlockStateParser.isSolidBlockByName. Air
and non-block items now correctly report no placeable blocks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
If a bridge/pillar edge's createMovement returns null (e.g. the hotbar
ran out of blocks mid-path), the follower used to fall through to plain
walking and step straight into the gap the placement was meant to fill,
spamming the no-blocks warning each tick.

Add MovementType.canWalkWhenNoMovement (true for walk-like moves, false
for BRIDGE/PILLAR). When a non-walkable type yields no movement, replan:
with an empty hotbar the planner drops placement strategies and routes
around the gap or reports the goal unreachable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
As the bot moves, chunks load and unload and nearby blocks update,
firing a burst of requestRepath() calls. Each repath rebuilds the path
from the current block, and the planner may pick a different equivalent
route, so the bot jittered and stepped backwards a little whenever a new
chunk loaded.

Stop ForgetLevelChunk (chunk unload) from requesting a repath — it never
invalidates the path being walked — and throttle remaining external
repath requests to at most one per 20 ticks. Genuine path failures still
replan promptly via stuck detection and goal/placement handling.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DigBlockMovement only computed the dig side; it never aimed at the block,
so the bot kept its pre-dig heading (pitch forced to 0). Servers that
validate line of sight would reject the dig, and blocks overhead or
underfoot were never looked at. Add directLookAt to the block centre in
init(), mirroring PlaceBlockMovement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
On a published release, dispatch an update_version event to the
MovementSync_documention repo so its version.json reflects the new release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On merging a PR into main, flip the project version from -SNAPSHOT to
-RELEASE, build the shaded JARs, and create a draft GitHub Release with
them attached, then delete the PR head branch. Mirrors xinbot's flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@huangdihd
huangdihd merged commit 940c81f into main Jun 30, 2026
1 check passed
@huangdihd
huangdihd deleted the 1.8.0-SNAPSHOT branch June 30, 2026 12:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant