3.0.0+26.2
Compatibility
Required content
Changes
BeaCraft 3.0.0+26.2
For Minecraft 26.2, and only 26.2. Protocol 2: pair it with a projectBEA brain that speaks protocol 2. An older brain still connects, but reads the answers in order and misses their explanations.
Every answer names the request it answers
The agent sends an id with every action, and now every answer carries it
back: when the action finishes, when a newer action replaces it, when
stop_moving stops it, and when something cuts it short. Before, nothing was
echoed and answers were matched by order, so whatever the mod did on its own
answered for the wrong request: eating made a walk and a mining job both come
back INTERRUPTED in a few milliseconds, and self-defence reported a walk as a
success while she stood fifteen blocks short of it.
Each answer also says what happened in plain words, on top:
{"status": "FINISHED", "id": "r41-3fa2c1", "action": "move_to", "result": "INTERRUPTED",
"message": "interrupted (self_defence: Zombie)", "reason": "self_defence: Zombie"}
message used to sit only under details, where the brain never looked.
details is still sent, unchanged. Numbers in messages always use a dot for
the decimal point, whatever the machine's language.
A skill that throws no longer crashes the game: its request is answered
FAILURE_EXCEPTION with the error, the body is free again, and the stack goes
to the log. The same holds for every part of the tick (self-defence, eating,
the clutch, death, the stuck watchdog, the state packet): one that fails is
logged and the others go on. A skill that throws while being stopped still
answers, once.
follow_player is answered as soon as she is on her way; the following goes on
until another action or stop_moving, and its end (she lost them, or it was
replaced) is announced as {"type": "activity", "action": "follow_player", "id": …, "result", "message"}. It used to answer nothing, and the agent's wait ran
out every time.
While she is dead, a request is answered FAILURE_DEAD; a respawn the server
does not act on is asked for again every five seconds.
Reflexes are events, not answers
Eating, self-defence, the water-bucket clutch, getting stuck and respawning are
announced as {"type": "reflex", ...} with started / finished, and name the
request they cut short in interrupted_id. They never carry a status, so they
can never be mistaken for the answer to anything. The old ENGAGED_AUTO_ACTION
packet and the anonymous INTERRUPTED packets from the stuck watchdog, the
clutch and death are gone.
Auto-eat only starts when there is something to eat. With an empty inventory it used to try, and fail, every five seconds. A reflex takes the body from a request but leaves the side tasks alone: eating no longer cuts a scan or a chat line short.
The water-bucket clutch owns the body until she lands: a request that arrives
mid-fall is answered FAILURE_BUSY instead of cutting the clutch short, other
reflexes wait, and stop_moving stops everything but the landing. It says what
happened: landed in the water or beside it, and whether the water went back into
the bucket (FAILURE_NOT_RECOVERED names where it stayed). The hand she had
comes back afterwards. A death mid-fall ends it cleanly.
Talking and looking no longer stop the body
chat, look_at, check_death_log and request_screenshot run beside
whatever the body is doing and answer at once. Her own chat line used to stop
the walk she was on. A glance while the body is busy lasts at most a second, so
it never steers the walk, and it waits while a skill is aiming a click (placing,
mining, fighting, landing a fall): the server orients a door, a stair or a bed
by the last look it received, and a glance at that moment turned them. The
handshake lists them under concurrent.
check_death_log answers with a sentence ("you died at (3, -57, 0) in
minecraft:overworld to Zombie, 2 min ago") and request_screenshot with the
image under details.data; both used to send packets the agent could not match
to anything.
Mining works with the game in the background
Blocks are broken through the game itself rather than by holding the attack key, which vanilla ignores while the window is unfocused or any screen is open: during a stream, mining used to hang until the agent gave up. A chest, furnace or table left open is closed first.
mine_block now:
- checks the tool before it starts:
FAILURE_WRONG_TOOL"iron_ore needs a stone_pickaxe or better to drop anything, and you carry none", and takes the best tool from anywhere in the inventory, not only the hotbar; - mines the tree or vein the block belongs to, meaning the blocks that touch it (at most 64), not everything in a 9×9×9 box around each one, which reached into the next tree;
- hits only what she can see, as a player's crosshair would: leaves, dirt or grass between her and the block are broken first, and anything she must not break (a chest, glass, bedrock) sends her to a side she can see it from. The server only checks the distance, so she used to mine a log straight through the leaves around it, and the drop stayed sealed inside;
- stands anywhere the block is within reach from, gives a block up after two failed walks, and builds a pillar under a treetop it cannot otherwise reach, digging the pillar back up afterwards;
- counts a block only once the server has answered for it: the client shows a
broken block at once, as a guess, and with some ping a block the server put
back used to count. Water or lava flowing into the hole, or sand falling into
it, is still a broken block (it used to be twenty seconds of "the server put
it back"); a block the server puts back three times is protected ground,
FAILURE_PROTECTED; - picks up what dropped,
and answers with what happened: "mined 6 of 6 oak_log; now carrying 6
oak_log more", or "1 left out of reach at (0, -51, 3)" with
FAILURE_UNREACHABLE, orFAILURE_NOTHING_MINED. It used to answerSUCCESSwhatever happened.
pickup_items (new) walks over the items on the ground nearby and says what
ended up in the inventory. A drop down a hole, up a step or behind leaves is
reached with the path planner, which digs and steps down, instead of waiting at
the edge: the game only hands over what touches her box grown by half a block
up and down, not the block and a half the mod used to wait for. It names a
drop as left behind only if it is still on the ground at the end.
find_block hands every find to the same miner, prefers blocks with open air
next to them, searches 48 blocks by default, never looks at a block that
yielded nothing again, and answers SUCCESS, FAILURE_NOT_ENOUGH ("collected
2/5 log…"), FAILURE_NONE_REACHABLE or FAILURE_NONE_FOUND. Unreachable logs
used to be found and skipped on every tick, forever. It no longer takes
allowPillaring / allowBridging. It counts what the blocks drop (stone
gives cobblestone, grass gives dirt, iron ore raw iron), never a piece of the
name, which used to count redstone dust as stone. Six blocks in a row that gave
none of it (leaves without shears) end it with FAILURE_NO_DROPS, and a full
inventory with FAILURE_INVENTORY_FULL: both used to dig until the budget ran
out. The block test is worked out once per search, not once per block read.
Nothing runs forever
Every action has a budget (90 s to walk, 180 s to find, 60 s to mine, 30 s to
craft, 45 s by default; following a player has none). Past it, the action is
stopped and answered FAILURE_TIMEOUT with what it was doing. The handshake
lists the budgets under budgets. bridge answers FAILURE_NO_EDGE within
three seconds when she is not at an edge, instead of walking backwards
indefinitely; attack_entity answers FAILURE_NOT_FOUND after five seconds
without a target, and chases a target more than four blocks away along a real
path.
Items are matched by name
discard_item, store_item, retrieve_item, equip_item, smelt_item and
pillar_up match an exact item id, or a family word (log, planks, wool,
cobble), and nothing else. "stone" used to match every item with "stone" in
its name: a discard of 5 stone threw away a stone pickaxe, a stone sword and 16
cobblestone as well. Tools, weapons and armour only ever match exactly.
Reflexes
- She eats on her own at 14 food or less while idle, and interrupts what she was asked to do only when hurt and hungry (health under 10, food under 20). She never picks rotten flesh, spider eyes, poisonous potatoes, pufferfish or raw chicken on her own.
- Hit down under 6 health with no weapon, she runs 20 blocks away from the
attacker (
fleereflex) instead of fighting on. - A fight that ends with the attacker alive and out of reach (no blow landed in 10 s, or two walks to it came up short) leaves that attacker alone for 30 s, and the queue of attackers never takes the body from a request: a skeleton on a pillar used to cut every request short for as long as it stood there.
- A player is fought back only after three hits in ten seconds: one hit in play is not a fight.
A walk that is stopped says so ("Stopped on the way to (20, -57, 0), 11.0 blocks short") instead of "Arrived at".
Placing a block does what it says
place_block walks into reach, takes the block from anywhere in the
inventory, places it against a real neighbour and checks that it is there.
It used to click the top of the target cell from wherever she stood, so a block
out of reach, or one in an occupied cell (it landed a cell higher), still
answered SUCCESS, and only the hotbar counted.
Before clicking, it asks the game which state each possible click would make
and takes the one that makes the state asked for: block accepts vanilla's
syntax, oak_door[facing=south], oak_log[axis=x],
oak_stairs[facing=east,half=top], wall_torch[facing=east] (or the facing
parameter). She crouches to click on a block that would react to the click
(a chest, a crafting table, a door, a lever), so placing on it does not open or
toggle it; against stone, dirt or planks she just clicks, instead of bobbing
for every block of a wall. New parameters: replace breaks what is in the cell
first; facing. It steps aside when she stands in the cell.
The check waits for the server's answer to the click, not for the client's
guess: a block refused by spawn protection, a claim or an anticheat is
FAILURE_NOT_PLACED however much ping there is.
Results: SUCCESS ("placed oak_door at (2, -57, 0)."), FAILURE_OCCUPIED,
FAILURE_NO_SUPPORT, FAILURE_OUT_OF_REACH, FAILURE_BODY_IN_THE_WAY,
FAILURE_NO_ITEM, FAILURE_NOT_PLACED, FAILURE_INVALID_ARGS.
A block goes against a face, never into thin air: "allowAirPlace": true in
config/beacraft.json allows it (default false, servers with an anticheat
kick for it).
build: a whole structure in one action
build (new) takes a structure as origin, rotation (0/90/180/270,
clockwise), palette + layers and/or ops (fill, walls, set, roof),
clear and dry_run, up to 2000 cells. It clears the cells meant to be empty
from the top down, places the rest from the bottom up starting from what
already holds them, with the same placer as place_block, retries what failed
once, and answers with the cells still wrong, the blocks it ran out of and the
cells that had nothing to rest on:
{"result": "FAILURE_INCOMPLETE",
"message": "built 2/6 cells of the build; missing 4 cobblestone."}
While it works she stays out of the structure's footprint whenever she can
reach it from outside, never stands in a cell meant to hold a block, and first
steps out if she starts inside it. A door and a bed take one item for their two
cells; a bed faces from its first cell to its second. dry_run answers with
what is already right and what she is short of, without moving. Every ten cells
a {"type": "progress", "id", "done", "total", "message"} packet says how far
it has got. Budget: 600 s; when it runs out the answer says to send the same
build again, which carries on (what is already right is skipped).
Clearing never breaks the protected blocks (doors, chests, beds, furnaces,
glass, torches…): they stay and are named in the answer. "clear": "all"
breaks them too.
A cell no standing spot reaches gets a pillar once both passes are done: she walks to a column beside it, outside the build where she can, towers up on blocks the rest of the build does not need, places what the top reaches, and digs the pillar back down.
A build spans at most 256 blocks along any axis, and a malformed argument (a
flattened layers, an op that is not an object, a hollow that is not true or
false, a coordinate that is not a whole number) is refused with the sentence the
brain gives for it; null for an optional argument means it was left out.
A walk that is going nowhere ends
A walk that gains no ground after four fresh plans in a row ends with
FAILURE "Stuck on the way to …: the path is there but her body cannot follow
it". It used to plan again every two seconds for as long as the action was
allowed to run.
A long search for a route is worked on a slice at a time (1,500 nodes a tick): one of fifteen thousand nodes used to hold a frame for up to 89 ms. A short one is still answered in the tick it is asked for. The sprint key is let go when a walk ends.
She sees what there is to use
The state packet gains resources: every two seconds the mod scans a cube of
20 blocks around her (68,921 blocks, measured at 4 to 19 ms) and reports each
useful kind once, with its count, the nearest one and the nearest one open to
the air: logs by wood, leaves, stone, cobblestone, deepslate, every ore, sand,
gravel, clay, water and lava sources, crafting tables, furnaces, chests,
barrels, beds and ripe crops. The close view (lidar, 4 blocks) stays. A tree
seven blocks away used to be invisible.
"resources": {"oak_log": {"count": 5, "nearest": {"x": 7, "y": -57, "z": 0, "distance": 7.0},
"nearest_exposed": {"x": 7, "y": -57, "z": 0, "distance": 7.0}}},
"resources_scan": {"radius": 20, "ms": 8.7}
world says the time of day, is_night (dark outside), the dimension, the
biome, rain and thunder, the light at her feet and the block light alone
(monsters spawn where it is 0), and the game mode.
scan (new, runs beside the current action) finds the nearest blocks of a
kind up to 64 blocks away: "nearest iron_ore: (40, -57, 3) 40.1m."
Parameters block, radius (default 32), count (default 5).
An exact block name now means that block (and its deepslate twin) for scan
and find_block; family words (log, stone, ore, planks, wool,
dirt…) still mean the family. "iron_ore" used to match every ore, and
"redstone_ore" matched stone.
Crafting finds its own table
craft_item takes count, the number of items wanted: five sticks are two
crafts. quantity still means crafts, for older brains. A recipe that fits the
2x2 grid is made in the inventory, anything bigger at the nearest crafting table
within 16 blocks, walking there (the first one found in a 5-block box used to
win, even the far one). With no table around she sets down the one she carries,
crafts, and picks it back up; pickUpPlacedTable in config/beacraft.json (on
by default) decides the last part.
Whether a recipe fits 2x2 is its shape, not its number of ingredients. 133 of
the 733 shaped recipes were called 2x2 by the count, among them every slab,
sword, shovel and hoe: craftable_2x2 offered them, and crafting them failed.
craftable_3x3 is now also sent when she carries a table or one is within 16
blocks, since that is where craft_item can make it.
A failure says why: FAILURE_MISSING_INGREDIENTS "1 wooden_pickaxe takes 3
planks and 2 stick; you are short of 2 planks (you have 1)", FAILURE_NO_TABLE,
FAILURE_NO_RECIPE (not unlocked yet) or FAILURE_UNREACHABLE. It used to be
"Crafting failed (Verified: 0 -> 0)". An exact item name no longer turns into
another wood: asking for oak_planks never makes birch planks. The recipe book is
clicked at the pace of a hand, or once with "as many as fit" when that is
everything she can make, never sixty-four times in one tick.
Smelting from start to finish
smelt_item(item, count, fuel) goes to the nearest furnace within 16 blocks
or sets down the one she carries, puts in exactly count items and just enough
fuel of one kind, the kind that wastes the least burn (one raw iron costs a
plank, not a coal), waits and takes out what comes out, takes back what was not
used, closes the furnace and picks her own back up. At most 10 per call. A
furnace busy with someone else's smelt is left alone (FAILURE_FURNACE_BUSY).
The old skill needed the furnace screen already open, never waited and never
closed it. input_item and fuel_item are still read.
Chests
store_item and retrieve_item take count and optional x, y, z: she walks
to that chest or barrel, or the nearest one within 32 blocks, opens it, moves
exactly that many of exactly that item and closes it; the answer lists what the
chest holds now. They used to need the chest already open and moved every stack
whose name contained the word. view_container (new) only looks.
Walking breaks less
move_to first looks for a way that breaks nothing, and digs only when there is
none: a stone wall with a way round it used to get a tunnel through it when
digging was cheaper than the detour. Some blocks a path never breaks at all:
doors, trapdoors, fence gates, beds, chests, barrels, shulker boxes, furnaces,
crafting tables, glass and panes, torches and lanterns. The list is
protectedBlocks in config/beacraft.json (block ids, #tags, *suffixes).
A closed wooden door or fence gate is a way through: she opens it, walks on, and shuts it behind her once she is two blocks past and the path does not come back through it (one out of reach at the end is said to be left open). Doors used to count as walls, dug through when digging was allowed. A fence or a wall is no longer taken for a step: a fence line used to get a path straight over it, and the walk ended "stuck" in front of it.
move_to takes range, how close counts as there. move_away(distance) (new)
puts distance between her and where she stands, trying up to three directions.
go_to_surface (new) walks out from underground, or digs a staircase up away
from lava and water, and ends standing on open ground.
A walk that stops gaining ground steps aside once and tries again before giving up, and says so in its log. The stuck watchdog does the same once before it interrupts. Its head-swing check no longer counts a turn across north (359° to 1°) as a swing of 358°.
use_block and mine_down look before they act
use_block walks into reach, clicks the face turned towards her and says what
the click changed ("used lever at (2, -57, 1): powered is now true"). It used to
click from wherever she stood and answer SUCCESS while the server ignored a
click from out of reach. A screen it opens is closed again: chests, furnaces and
tables have their own actions now.
mine_down stops before breaking a block with lava or fire under or beside it,
water right under it, or a drop deeper than three blocks, and says which
(FAILURE_DANGER). It used to dig and fall into whatever was there.
It also used to dig one block and wait there: it waited for a landing it only
noticed on one exact tick. It now counts a step once she stands a block lower.
The game state's world names the server she is on (server: its address, or
singleplayer:<world>), so a brain can keep what it remembers per world.
Baritone plans, or plans and walks
When the player installs Baritone as a separate mod, she walks its routes:
full lets it plan and walk, plan takes only its routes while her own skills
do the walking, off keeps the built-in A*. The switch is baritoneMode in
config/beacraft.json and /beacraft baritone in game. Nothing of Baritone
ships with the mod; without it everything works as before.
Its routes keep her own rules: the protected blocks are never broken, a closed door or gate on the way is opened and named, a walk that stops short steps aside once before giving up, and a finished walk lets go of the planner, so no old goal walks her into whatever she does next.
Baritone's settings are global, so the ones she changes (renderers, parkour, look, breaking and placing, the protected blocks) hold only while one of her routes is planned or walked, and go back to what they were afterwards: someone using Baritone by hand on the same client finds it as they left it.
Its chat control stays off, so what she says reaches the game. A line starting
with its command prefix is refused (FAILURE_BARITONE_PREFIX) instead of
ending up in its command handler.
A hand at a person's pace
Chests, furnaces, crafting grids and the inventory are worked the way a player
works them: the screen opens, she looks at it for a moment, the clicks come one
at a time a fifth to two fifths of a second apart, and she lingers on the result
before closing it. Every click of a smelt or a partial stack used to go out in
one tick, and on a stream the items teleported. Swapping armour, the offhand or
an item from the main inventory into her hand opens the inventory to do it;
picking a hotbar slot is still a key press. humanPace in config/beacraft.json
(on by default) turns it off. Eating, fighting, clutching and fleeing never wait
for it.
The head turns like a person's
Every turn she makes on purpose eases: fast through the middle, slow into the end, three quarters of a second for a quarter turn, where it used to snap in one tick (placing, opening a chest, using a lever) or sweep at a constant speed. She looks at a block before she starts breaking it, at a face before she places against it, at a chest before she opens it, and looks down before a pillar and along the edge before a bridge. The last tenths of a degree before a placement are exact, so blocks face the same way as before.
While nothing needs her aim exact, it is never perfectly still: it drifts
slowly, under a degree, a few seconds per swing, like the aim drift of 2.1.0,
aimSway in config/beacraft.json (0.8 by default, 0 turns it off). It stops
while she breaks or places a block, bridges, pillars, fights or clutches, and
while a screen is open, where 2.1.0 drifted while mining too. Bridging and
pillaring now also keep look_at from turning the head mid-placement, as
placing and mining already did.
Chests and furnaces are found through the chunks
A chest, barrel or furnace nearby is found in the chunks' lists of block entities instead of by reading every block around her: a chest within 32 blocks used to cost 274,625 block reads in one tick.
Live tests
make live-server, make live-client and make live-test run the mod against
a vanilla server and check every scenario against what the server says actually
happened. make live-proxy puts ping between the client and the server, and the
protect scenarios make the server refuse her through spawn protection. See the
README.
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:px0NmIO6:5EnE6uom"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:px0NmIO6:5EnE6uom"
}

