`bot.pathfinder.goto` sometimes never finish if goal is GoalNear and the block is not full height
nishio opened this issue · 12 comments
Sometimes bot.pathfinder.goto
never finish. It may related floating-point calculation.
Here is my code:
const { x, y, z } = toHarvest.position;
const goal = new GoalNear(x, y, z, 2);
if (!goal.isEnd(bot.entity.position)) {
console.log("go to ", [x, y, z], "from ", bot.entity.position);
await bot.pathfinder.goto(goal);
console.log("done");
}
And it stop after the following message:
go to [ -33, 63, -214 ] from Vec3 { x: -28.55625503370811, y: 62.875, z: -213.3506397248765 }
GoalNear.isEnd is false and bot won't walk.
Is there any workaround?
If there is an error, goto reject the promise (which throws and exception that should be catched).
Try to catch and print the error:
try {
await bot.pathfinder.goto(goal)
} catch (e) {
console.log(e)
}
What makes you think it is related to floating point calculation ?
I already enclosed it with try/catch and there are no error.
I'm not confident that it is related to floating point calculation. Any other suggestion?
The code is usually success, but in a small probability bot stops without any error thrown. It is reproductive. Here are some cases:
go to [ -28, 63, -212 ] from Vec3 { x: -30.5, y: 62.875, z: -211.68502145455264 }
go to [ -33, 63, -213 ] from Vec3 { x: -28.5, y: 62.875, z: -212.3358946346443 }
go to [ -35, 63, -211 ] from Vec3 { x: -33.4805719963985, y: 62.875, z: -213.31170003933832 }
The bot stands on a flat farm of soul sand and nether wart.
My first guess about radius boundary looks not correct. I changed the title.
Here are some other cases with distances:
go to [ -35, 63, -210 ] from Vec3 { x: -34.327009310748934, y: 62.875, z: -212.6377405258382 } distance: 2.7251085390251646
go to [ -29, 63, -208 ] from Vec3 { x: -31.623865659091162, y: 62.875, z: -206.42575916155076 } distance: 3.0624386058171473
go to [ -28, 63, -213 ] from Vec3 { x: -27.5, y: 62.875, z: -209.5 } distance: 3.5377429245212264
Is there any way to observe internal path-finding status? I wonder why the bot won't walk.
I added console.log in bot.pathfinder.getPathTo
and found const result = astarContext.compute();
return successful result, sometimes bot won't walk and never achieve the goal.
I feel it is not related to GoalNear.
At https://github.com/PrismarineJS/mineflayer-pathfinder/blob/master/index.js#L384
nextPoint
was
Move {
x: -32.5,
y: 62.875,
z: -208.5,
remainingBlocks: 0,
cost: 1,
toBreak: [],
toPlace: [],
parkour: false,
hash: '-33,63,-209'
}
bot.entity.position
was { x: -32.68931395891055, y: 62.875, z: -208.51950746279664 }
They are close. At https://github.com/PrismarineJS/mineflayer-pathfinder/blob/master/index.js#L449
dx, dy, dz
are 0.18931395891055303 0 0.019507462796639174
.
However, after that it repeats path.length === 0
https://github.com/PrismarineJS/mineflayer-pathfinder/blob/master/index.js#L361
It checks stateGoal.isEnd(bot.entity.position.floored())
repeatedly, and it is false.
bot.entity.position.floored()
is { x: -33, y: 62, z: -209 }
.
It looks the case that bot.entity.position
is in the boundary of the goal, but bot.entity.position.floored()
is not in it.
By changing bot.entity.position.floored()
to bot.entity.position
, it works well in my case. Again, I use GoalNear
and it has spherical boundary. I see there are many type of goals. I'm not sure some of those goals require floored position.
There seems to be an issue with the height (y) of the block. What block is it standing on at the end ?
What block is it standing on at the end ?
Soul sand, its height is 0.875.
By changing bot.entity.position.floored() to bot.entity.position, it works well in my case.
Sorry, it decrease the frequency but not fix the problem. I recover to the original.
At this code:
https://github.com/PrismarineJS/mineflayer-pathfinder/blob/master/index.js#L361
After path.length === 0
, if isEnd
is false, it does not emit goal_reached
nor path_update
. There are nothing changes the situation, so await bot.pathfinder.goto(goal)
never finish.
Changing bot.entity.position.floored()
to bot.entity.position
makes the X-Z boundary broaden and decrease the frequency of the problem.
Here is an illustration:
https://gyazo.com/213c3d81da2ab7fca00bd1517367ee26
Based on the knowledge above, I changed GoalNear to GoalNearXZ. It looks work well in my case. I'll fix the title of the issue.