diff --git a/src/agent/commands/actions.js b/src/agent/commands/actions.js index 07a0c5d76..4eb72ba4f 100644 --- a/src/agent/commands/actions.js +++ b/src/agent/commands/actions.js @@ -128,7 +128,7 @@ export const actionsList = [ description: 'Find and go to the nearest block of a given type in a given range.', params: { 'type': { type: 'BlockName', description: 'The block type to go to.' }, - 'search_range': { type: 'float', description: 'The range to search for the block. Minimum 32.', domain: [10, 512] } + 'search_range': { type: 'float', description: 'The range to search for the block. Minimum 32, maximum 128.', domain: [10, 128, '[]'] } }, perform: runAsAction(async (agent, block_type, range) => { if (range < 32) { diff --git a/src/agent/library/world.js b/src/agent/library/world.js index 132ff5bfa..1f7d0c122 100644 --- a/src/agent/library/world.js +++ b/src/agent/library/world.js @@ -141,17 +141,28 @@ export function getNearestBlocks(bot, block_types=null, distance=8, count=10000) return getNearestBlocksWhere(bot, block_ids, distance, count); } +// bot.findBlocks is synchronous and scans a volume that grows with the cube of maxDistance. With the +// default count (10000) a search for a rare or absent block never early-exits, so a large radius walks +// a huge volume on the main thread and blocks the event loop -- long enough that mineflayer misses +// keep-alive packets and the server drops the bot mid-task. !searchForBlock lets the model pass a +// radius up to 512, so this is reachable in normal play. Cap the radius (a search beyond the loaded +// view distance returns nothing useful anyway) and the count so one search can't stall the connection. +const MAX_SEARCH_DISTANCE = 128; +const MAX_SEARCH_COUNT = 4000; + export function getNearestBlocksWhere(bot, predicate, distance=8, count=10000) { /** * Get a list of the nearest blocks that satisfy the given predicate. * @param {Bot} bot - The bot to get the nearest blocks for. * @param {function} predicate - The predicate to filter the blocks. - * @param {number} distance - The maximum distance to search, default 16. - * @param {number} count - The maximum number of blocks to find, default 10000. + * @param {number} distance - The maximum distance to search, default 16 (capped at 128). + * @param {number} count - The maximum number of blocks to find, default 10000 (capped at 4000). * @returns {Block[]} - The nearest blocks that satisfy the given predicate. * @example * let waterBlocks = world.getNearestBlocksWhere(bot, block => block.name === 'water', 16, 10); **/ + distance = Math.min(distance, MAX_SEARCH_DISTANCE); + count = Math.min(count, MAX_SEARCH_COUNT); let positions = bot.findBlocks({matching: predicate, maxDistance: distance, count: count}); let blocks = positions.map(position => bot.blockAt(position)); return blocks;