Ecosystem plugin patches
The mineflayer ecosystem plugins run on bedboo unchanged except for the small pnpm patches in patches/
(patches/mineflayer-*.patch). This page says what each patch changes and why, and records how the plugins behave on
Bedrock where that differs from Java (and the workarounds that help). Recommended usage: Plugins.
Observed on BDS 1.26.51.1 (protocol 2193).
mineflayer-pathfinder 2.4.5 patch
- Affects:
Movements,bot.pathfinder.bestHarvestTool,goto,stop, the path executor (monitorMovement,fullStop,postProcessPath); everything built on it (mineflayer-collectblock, mineflayer-pvp, mineflayer-tool's chest retrieval) - Java: block-name sets with Java names; doors are dug through (only fence gates can be opened, and
canOpenDoorswas left off upstream);fullStop()recentres the bot by movingbot.entity.position("the server will not tell the difference"); dig costs from prismarine-blockblock.digTimewith the tool's simplified NBT. - Bedrock: different block names (
flowing_water/flowing_lavaare blocks of their own,web,wooden_door,fence_gate,standing_sign,lit_furnace, … —lib/interactable.jsononly knew Java names); server-authoritative movement corrects any client-side position change (the recentring cost 3–4 corrections of 0.16–0.64 block per bridge, see scaffolding); Bedrock items keep enchantments inench(numeric ids) and BDS applies Bedrock's Haste / Mining Fatigue factors (dig speed). - bedboo (patch, new file
lib/bedrock.js+ edits):- names:
flowing_water/flowing_lavajoinliquidsandreplaceables,flowing_lavajoinsblocksToAvoid; water-filled blocks (seagrass,kelp,bubble_column, …) and waterlogged blocks count as liquid, the postprocessed path centres in them (backport of upstream master #384);interactable.jsongets the 156 Bedrock names of interactive blocks (the same set aslib/bedrock/placement.js), so pathfinder also sneaks before placing against them (sneak-placing); - doors and gates:
openableholds the hand-openable doors (wooden_door,spruce_door, …, copper doors; never iron) besides fence gates; withcanOpenDoorsa closed one becomes auseOneclick (the door's upper half is not dug), an open door / gate (open_bit, Javaopen) is passable and never clicked again; the doorway node is the floor centre and auseOnenode no longer stops the path post-processing (backport of master #372); after the click the executor walks on (upstream keptplacingset and then readplacingBlock.yof undefined or reset the path for want of scaffolding blocks). BDS opens a door's lower half only (the upper half keepsopen_bit0): the upper half gets the open leaf's shape from bedboo'sblockAt()(door halves), so the bot walks back through a door it opened instead of finding no path or digging it; fullStop()keeps upstream's zeroed horizontal velocity but skips the recentring teleport when the bot hasbot._bedrock.physics(server-authoritative movement). Measured: pathfinder bridge 0 corrections (was 3–4); at most one ~0.24-block correction now and then when BDS does not accept the zeroed velocity (releasing the keys only let the bot drift out of the goal block);- dig costs (
bestHarvestTool,safeOrBreak):item.enchants(JavaEnchantmentsand Bedrockenchalike; the simplified NBT hadid, which prismarine-block never matched) andbot._bedrock.digging.blockDigTimewhen present (Bedrock effect factors; prismarine-block'sdigTimeotherwise); - backports of master #375:
stop()while idle no longer latches (it stopped the next goal),gotorejects withNoPathinstead of resolving on an empty failed search. mineflayer-collectblock'scancelTask()relied on that latch (it callsstop()while the pathfinder is idle during a dig): its patch now cancels by itself (mineflayer-collectblock); lib/passableEntities.jsonalso lists the Bedrock names of the passable entities (xp_orb,xp_bottle,splash_potion,lingering_potion,fireworks_rocket,thrown_trident,fishing_hook,evocation_fang,wind_charge_projectile,breeze_wind_charge_projectile,ender_crystal,eye_of_ender_signal,ominous_item_spawner,wither_skull_dangerous): with only the Java names, XP orbs and projectiles counted as obstacles (entity cost, no pillaring or scaffolding where an orb was);detectDiggingStoppedremoves only its own listeners (removeAllListeners(event, fn)ignoresfnand dropped every otherdiggingCompleted/diggingAbortedlistener of the bot);- a dynamic goal (
GoalFollow) re-plans when the bot was pushed more than a block away from where its finished path was computed (a skeleton's arrows pushed a mineflayer-pvp bot out of range for good: the target itself had not moved far enough forhasChanged()); - failed placements never hang the path (upstream 2.4.5 and master d773d15 both hang — master's open PR #365 only
moves the futility check; any server, Java too):
- upstream: a rejected
bot.equipof the scaffolding block never releasedlockEquipItem, so the executor returned early on every tick, before its futility check, for good; a refused placement reset the path into the same placement for ever;stop()waited for a node or a reset that never came; - now the equip lock is held from the equip until the placement settles and released on every outcome;
- a failed equip / placement / door click (
equip_error,place_error,use_error) or one that takes overplaceTimeout(10 s,place_timeout) is counted at its cell: a cell that failed more thanmaxPlaceRetries(1) times joinsbot.pathfinder.refusedPlacements, whereMovements#getNeighborsnever plans a placement for the current goal (the same goal object set again — a caller's retry — keeps them; another goal orstop()clears them); maxPlaceFailures(6) in a row give the goal up (path_update'noPath',gotorejectsNoPath"… placements failed in a row"; the goal is dropped unless dynamic, so no later reset revives it);stop()during a placement settles on the next tick; a placement abandoned by a stop / reset / new goal changes nothing when it settles late (and never releases a newer placement's lock); the walk back toreturnPosafter a placement is bounded like a walk to a node;- after a failure the bot steps back onto the block it leaned out from, and a search begins from the block the bot
stands on when its floored position is over a gap (upstream started from the cell over the gap and planned a
placement against the air under it — after a stop at a bridge edge the next
gotospent 2 × 10 s on it).
- upstream: a rejected
- names:
Long searches and partial paths
- Affects: mineflayer-pathfinder
goto()to goals 100+ blocks away over hills (same on Java) - Java / Bedrock: identical upstream behaviour:
goto(GoalLookAtBlock(<ore 90 blocks away>))rejects with "Took to long to decide path to goal!" —gotorejects on the search'stimeoutstatus instead of following the best partial path, although the pathfinder then walks that partial path, and nothing re-plans at its end. - bedboo: nothing in the library or the patch. Workarounds (used by the bundled agent,
packages/agent): walk far goals in legs of 32 blocks (GoalNearXZwaypoints, a leg 16 blocks to the side when one fails),thinkTimeout10 s; after a timeout wait for the partial walk to end and search again from there; give up when the bot has not moved for 30 s. A 1×1 pillar needs the bot centred in its column (a hitbox overlapping the neighbouring column hits that column's ceiling when jumping): centre the bot before each jump.
No path out through a door the bot just placed
- Affects: mineflayer-pathfinder (patched,
canOpenDoors) right after the bot placed a wooden door and stays connected - Java: not observed.
- Bedrock (observed, not explained): a bot that had placed a house door from the inside got
NoPathfor every goal outside; after a rejoin pathfinder opened the same door and walked out. The door's block states seen by the bot are correct (open_biton the lower half,upper_block_biton the upper one, the same after a rejoin), so the cause is not the world model; not investigated further. - bedboo: no fix. Workaround: place a door from outside the footprint and leave a finished structure through its
door explicitly (
activateBlock+ walk); when stuck, open an adjacent closed door and step through.
mineflayer-pathfinder drops into lava
- Affects: anyone using mineflayer-pathfinder's defaults in the Nether
- Java / Bedrock: identical upstream behaviour:
Movements.infiniteLiquidDropdownDistance(default true) lets a path drop any height into a "liquid", and pathfinder's liquids include lava — a nether path dropped the bot into the lava ocean (measured: "<bot> tried to swim in lava" while exploring at y 26). - bedboo: nothing in the library or the patch. Workaround: set
infiniteLiquidDropdownDistance = false(drops limited tomaxDropDown3) and add portals, fire, magma, berry bushes, … toblocksToAvoid.
Pillaring (1×1 towers) under a ceiling
- Affects: mineflayer-pathfinder's
allow1by1towers - Java: pathfinder jumps and places a block under its feet; it only clears the block two above the feet. Java's server accepts the placement as soon as the client says it rose; the client re-centres itself on the pillar.
- Bedrock: BDS refuses any block that overlaps the player's server-side hitbox
(scaffolding), and the patched pathfinder no longer re-centres the bot (that caused
corrections). An off-centre hitbox spans the neighbouring columns; a block two or three above the feet there (e.g.
the underside of the End's island over its arrival platform) cuts the jump short and every placement is refused
(measured: 204
place_errorpath resets in a row, the bot stuck on a 3-block pillar). - bedboo: nothing in the library. Workaround: where a ceiling is near, drop tower steps with a block 2–3 above the feet in any of the nine columns, so the pathfinder digs a staircase instead (End platform → island top in ≈ 25 s). Elsewhere towers work (a bot that dug itself into a 1×1 shaft is centred and towers out fine).
Bridging over the Nether's lava ocean
- Affects: mineflayer-pathfinder scaffolding in the Nether
- Java / Bedrock: identical: a bridge over the lava ocean is exposed (a hoglin's toss or a crossbow bolt knocks the bot into the lava).
- bedboo: nothing in the library. Workaround: place no scaffolding block over a drop deeper than 4 blocks there; the pathfinder digs through rock instead.
mineflayer-tool 1.2.0 patch
- Affects:
bot.tool.getDigTime,equipForBlock,retrieveTools' cost order - Java:
block.digTime(type, …, nbt.simplify(item.nbt).Enchantments, effects). - Bedrock: enchantments are
enchNBT with numeric ids; Bedrock effect factors (dig speed). - bedboo (patch):
item.enchants+bot._bedrock.digging.blockDigTime(else prismarine-block) — the estimate equalsbot.digTimewith that tool in hand, so Efficiency picks the enchanted tool.- Upstream bug fixed (not Bedrock-specific):
equipForBlock(block, { requireHarvest, getFromChest })with no harvesting tool in the inventory calledretrieveTools(), which returns without an error when there is no chest (or no chest had a tool), and then called itself again — for ever. Without chests that is an endless chain of microtasks: the event loop froze and the process died out of memory within ~25 s (e.g. mineflayer-collectblock'scollect()of coal ores without a pickaxe; its options are{ requireHarvest: true, getFromChest: true, maxTools: 2 }). The patch searches the chests only when there are some, and one round of them; otherwise (or still without a tool) the call rejects withNoItem, as withoutgetFromChest.
- Upstream bug fixed (not Bedrock-specific):
mineflayer-collectblock 1.6.0 patch
- Affects:
bot.collectBlock.collect(target, [options], cb)(callback form), the drops it picks up,cancelTask() - Java / Bedrock: the same upstream bugs on both:
callbackify(this.collect)lostthis, so the callback form (mineflayer'sexamples/collectblock.js) always failed with "Cannot read properties of undefined (reading 'bot')";- a mined block's drops spawn at a random point 0.25–0.75 into the block on each axis (minus half the item height): up to ~0.52 block from its centre (measured on BDS: 0.17–0.52). collectblock only targets drops within 0.5 of the centre, so now and then a drop was left behind (Java has the same spread);
- a target block that is already gone when its turn comes (mineflayer-pathfinder digs what is in its way, e.g. the
log above a dug one while following that log's drop) got a
GoalLookAtBlockon air, which never ends: the search ran into its 5 s timeout andcollect()rejected (measured: 2 of 4 runs collecting 5 logs); cancelTask()callsbot.pathfinder.stop()and waits for the job to end. With pathfinder 2.4.5 the stop latched while the pathfinder was idle (during a dig, while waiting for a pickup), so the job's nextgotorejected withPathStopped, whichcollect()swallows. The patched pathfinder no longer latches (mineflayer-pathfinder): the cancel was lost andcancelTask()waited for the whole job (measured: 17 s for 4 logs).
- bedboo (patch):
callbackify(this.collect).call(this, …); drops within 0.75 of the mined block's centre are collected; a block target that changed is dropped before pathing to it;cancelTask()also flags the running job, which checks the flag after each step (goto, the dig, the pickup wait, emptying the inventory) and ends withPathStoppedlike before — after the step in progress, as with pathfinder 2.4.5 — and a pickup wait ends at once. Nothing else is patched: digging waits for the server (completion), drops come fromitemDrop→GoalFollow→playerCollect/entityGone, the chest flow usesopenChest/depositunchanged.
Ore search uses the chunk data
- Affects:
bot.findBlocksfor ores (mineflayer-collectblock's examples do the same) - Java / Bedrock: identical — the server sends whole chunks, and bots locate blocks with
bot.findBlocks. - bedboo: nothing to change. Nether facts worth knowing when mining there:
- the ancient debris band y 8–22 (the big veins, around y 15) mostly lies under the lava ocean (y ≤ 31): targets there often sit under an open cavern, and mineflayer-pathfinder bridges and pillars through the void towards them or the bot falls into the lava. Searching above the lava ocean first (y ≥ 32, where the small veins are), requiring the debris to be buried in rock up to the bot's level (no open cavern or lava above it), and falling back to the 8–22 band or a straight branch-mining tunnel works better;
- when pathing to ores, never break a block next to a liquid;
- mining nether gold angers the piglins that see it, gold armour or not (crossbow piglins then shoot the bot): mine it last and never within 20 blocks of a piglin.
mineflayer-armor-manager 2.0.1 patch
- Affects: auto-equip on
playerCollect - Java: each picked-up piece starts
equipItem100 ms later; with Java's instant window clicks the equips rarely overlap. - Bedrock: every click waits for the server's item stack response, so pieces picked up together equip at the same time; their clicks interleave through the shared cursor and swap the pieces around (measured: 1 of 5 pieces ended up equipped).
- bedboo (patch): the equips run one after another (a promise queue).
getDroppedItem()and the Java armor slots 5–8 / off-hand 45 work as is;supportFeature('doesntHaveOffHandSlot')is false.
mineflayer-auto-eat 5.0.3 patch
- Affects:
bot.autoEat.eat(),enableAuto() - Java: a meal ends with
entity_status9 onbot._client. - Bedrock: no
entity_statuspacket; BDS sendscompleted_using_itemto the eater (whatbot.consumewaits for). - bedboo (patch): the eating listener also completes on
completed_using_item. The plugin is ESM-only (load it withawait import('mineflayer-auto-eat'));registry.foods/foodsByNamecome from bedrock-data; its GPL-3.0 dependency@nxg-org/mineflayer-util-pluginis used unmodified (it needs Java version comparisons (version comparisons),bot.version.split('.'),clickWindow,inventory.selectedItem,firstEmptyInventorySlot). Hunger only drops on difficulty easy or harder (on peaceful Bedrock never lets the food level drop).- Upstream bugs fixed (not Bedrock-specific):
eat()sets its eating flag before equipping the food and only cleared it on the paths after the meal started: an equip that failed (customEquip→ false, e.g. a window open or a hand swap at the same moment) leftisEatingtrue for good — every latereat()threwAlready eating!and the automatic mode never ate again (details). Now any failure before the meal starts (no food, the equip, activating the item) clears the flag; such a failure still emits nothing (no meal started), as upstream.- With
strictErrors(the default) a failed meal (timeout, the item switched away,cancelEat()) threw before emittingeatFail, so no failure event was ever emitted with the default options; noweatFailcomes first (theneatFinish, then the rejection), as withstrictErrors: false.eatFailis emitted once per failure: code that emitted it itself with the erroreat()threw (a workaround for the missing event) does not report a failure twice.
- The automatic mode tries again 2 s after a meal that could not start (a failing equip would otherwise be repeated
on every tick), at once after a meal that failed, as upstream;
eat()called directly is never held back. A throwingeatStartlistener no longer leaves the flag set either (the event is emitted inside the meal'stry).
- Upstream bugs fixed (not Bedrock-specific):
mineflayer-auto-eat eats whenever health < 14
- Affects: mineflayer-auto-eat 5.0.3
minHealth(default 14), on Java and Bedrock alike - Java: the same option; a low-health meal at a full food bar is the same futile loop for ordinary food.
- Bedrock: a player with a full food bar cannot eat (BDS refuses the meal), so an auto-eat triggered by low health alone starts a meal every tick that never completes (3 s timeout each).
- bedboo: nothing patched. Recommended options:
minHealth: 0,minHunger: 16(eat by hunger only).
mineflayer-auto-eat stops eating after a refused equip
- Affects: mineflayer-auto-eat 5.0.3
eat()/ its automatic mode (same code on Java) - Java / Bedrock: identical upstream bug:
eat()sets its "eating" flag before equipping the food and clears it only on the paths after the meal started; an equip that throws (other code or a fight swapping the hand at the same moment, a window open) leaves the flag set, and the automatic mode (physicsTick→if (!_eating) eat()) never tries again (observed: a bot went on with food 5 and 5 cooked meals in its inventory for minutes). - bedboo: fixed in the mineflayer-auto-eat patch: the flag is cleared after a failure before the meal. As a last resort, resetting a meal that has been "in progress" for 15 s is still a sensible safety net.
mineflayer-auto-eat against the pathfinder's held item
- Affects: bots that dig or place while hungry with mineflayer-auto-eat enabled
- Java / Bedrock: identical upstream behaviour. auto-eat starts a meal on any physics tick where the food level is
under
minHungerand something edible is carried (it equips the food and holds "use"); it gives the meal up with "Item switched early" as soon as the held item changes. mineflayer-pathfinder equips a tool to dig and a block to place — on the next tick auto-eat equips the food again. A hungry bot whose path needs digging or a block placed does neither (measured: a bot stood 12 min next to a lava pool, food 4, nine rotten flesh carried, every walk timing out). - bedboo: nothing patched. Workaround: eat first, standing still (auto-eat's own
eat()with the pathfinder stopped), before a task that digs or places; do not treat a meal in progress as an interruption to retry forever; bound retries and searches by time.
mineflayer-pvp 1.3.2 patch, shield and timing
- Affects:
bot.pvp(creeper shield block, shield use, attack timing,followRange) - Java: a fusing creeper is metadata index 16 = 1; the shield is raised with
activateItem(true); the attack rate follows Java's weapon cooldowns. - Bedrock: a fusing creeper has the
ignitedentity flag; a shield is raised by sneaking (no use action, see Item use, eating and the shield); there is no attack cooldown. - bedboo (patch):
checkExplosionalso readsmetadata.flags.ignited(measured live: the flag is set, pvp raises the shield). Unpatched:activateItem(true)/deactivateItem()hold / release sneak, so the bot moves at sneaking speed between attacks while it holds a shield; that sneak is the shield's own, so pathfinder'sclearControlStates()(each time a chase ends, before a dig or placement, onstop()) does not lower it;- the Java cooldown timing just attacks a little slower than Bedrock allows;
- with the default
followRange2 a skeleton that backs off while shooting stays 4 blocks away (GoalFollowre-plans only when the target moved more than the range; the same on Java): usebot.pvp.followRange = 1against ranged mobs; - pvp listens to
physicTick(mineflayer prints its deprecation warning, as on Java).
Core fixes found by running the plugins
- Affects:
bot.stopDigging,bot.creative.flyTo,bot.waitForChunksToLoad - Java: n/a (library behaviour the plugins rely on).
- Bedrock: the plugins exercise timing that the basic API calls do not.
- bedboo:
lib/plugins/digging.js:blockUpdatelisteners run before the dig's per-position one; mineflayer-pathfinder stops digging on any change near its path, so every pathfinder dig ended asdiggingAborted("Digging aborted") although the block broke. AstopDiggingwhile the block is already broken now completes the dig like upstream (whosefinishDiggingclearstargetDigBlockbefore the local update).bot._bedrock.digging.blockDigTime(block, type, creative, inWater, notOnGround, enchantments, effects)(prismarine-block's signature, Bedrock factors) is provided for the plugins' cost estimates.lib/plugins/physics.js: the creativeflyToplanner never re-presses forward within 10 ticks of releasing it (BDS sprint-flies after a double-tapped forward), keeps its jump guard across consecutiveflyTocalls and never lands short of a destination above the landing spot (BDS stops the flight when the player touches the ground); see flight.waitForChunksToLoad: called on "loaded" right after a teleport, it timed out because columns BDS sent during the join (beyond its advertised publisher radius) were unloaded and never resent;lib/plugins/blocks.jsnow keeps them.
Ported mineflayer examples
- Affects: the library's
examples/ - Java: mineflayer 4.39.0
examples/(require('mineflayer')). - bedboo: 51 example files ported with
require('bedboo')and otherwise identical (Java item / block names they hard-code are kept: e.g. fisherman'sfish, graffiti'ssignare not Bedrock names — nor modern Java ones).auto-eat.jsis adapted to the pinned mineflayer-auto-eat 5 API (ESMimport(),setOpts,enableAuto/disableAuto,eatStart/eatFinish), which upstream's example predates. Not ported:session.js(Java launcher-profile authentication),discord.js/telegram.js(third-party bots, nothing Bedrock-specific),perfectShotBow.js(minecrafthawkeye, Java),viewer/,screenshot-with-node-canvas-webgl/(prismarine-viewer: Java chunks),anvil_saver/(Java Anvil world files),python/. Where an example needs Bedrock behaviour:/opfrom a player is refused by BDS; op through the server console (op command);bee.js(creativeflyTo) really flies on Bedrock: its 11 short legs take ≈ 15.5 s instead of ≈ 3 s (flight);inventory.js:equip off-handonly takes off-hand items such as arrows, not dirt (off-hand).