Skip to content

Fix builder in creative mode and directional/regrowing blocks - #5148

Draft
AliceLeyy wants to merge 13 commits into
cabaletta:1.21.4from
AliceLeyy:creative-build-autogive
Draft

AliceLeyy wants to merge 13 commits into
cabaletta:1.21.4from
AliceLeyy:creative-build-autogive

Conversation

@AliceLeyy

Copy link
Copy Markdown

Summary

Fixes several builder problems, most visible in creative mode where the bot otherwise pauses with "Missing materials" or gets stuck repositioning forever.

Creative mode

  • Auto /give blocks the schematic needs but that are not in the inventory (buildCreativeAutoGive, default on). Only the needed amount is requested (capped at one stack), one block type per invocation, only when there is room to receive it, and only after confirming /give is permitted — otherwise it gives up instead of spamming.
  • Blocks with no item form (fluids, technical blocks) are skipped rather than reported as missing.
  • Hotbar moves are processed even when allowInventory is off, so /give items actually reach the hotbar.

Directional blocks

  • Hotbar moves now match by block type, so logs/stairs/chests are moved to the hotbar (previously an exact blockstate match was required, so a differently-oriented item never matched).
  • Placement is simulated using the target rotation instead of the smoothed aim, so directional blocks are placed with the correct axis/facing.
  • World-determined properties (stair shape, chest type, fence/wall/redstone connections, waterlogged) are ignored when comparing blockstates, since they follow from the neighbours and otherwise cause an endless place/break loop.

Regrowing blocks

  • Naturally regrowing overgrowth (short/tall grass, ferns, dead bush, snow) is ignored instead of being mined forever.
  • Grass is accepted where dirt is requested, since grass spreads onto placed dirt.

Misc

  • New builderMinStandDistance setting (default 1 = previous behaviour) to prefer standing further from a block when placing.
  • Detailed, throttled build-status logging when the builder is stuck.

Testing

  • ./gradlew build and ./gradlew test pass (one elytra test is flaky and unrelated).
  • Verified in-game on 1.21.4 Fabric in creative mode.

⚠️ Some of these change builder defaults (creative auto-/give, ignored properties, grass/dirt substitutes). Happy to split or gate any of them behind settings if you'd prefer.

Alicesia added 13 commits October 13, 2026 21:17
- Creative: auto /give missing blocks (buildCreativeAutoGive), only the
  needed amount, only one type per tick, and only when there is room to
  receive it; skip blocks with no item form
- Hotbar moves now match by block type, so directional blocks (logs,
  stairs, chests) actually reach the hotbar
- Simulate placement using the target rotation, not the smoothed aim, so
  directional blocks are placed the right way up/facing
- Ignore world-determined block properties (stair shape, chest type,
  connections, waterlogged) when comparing states, ending place/break loops
- Treat naturally regrowing plants as ignorable and accept grass for dirt
- InventoryBehavior processes queued moves even when allowInventory is off
- Add builderMinStandDistance and detailed stuck-build logging
Log every PLACE/BREAK decision (blockstate, position, hotbar slot,
target and player camera rotations) to the game log, and dump a full
snapshot with a reason when the bot has not moved for 5 seconds.
- possibleToPlace now ray traces and simulates with the rotation that will
  actually be applied (peekRotation), not the ideal target. Using the ideal
  target made the builder report a placement it could never click, looping
  forever once standing still.
- Move the 5s stand-still watchdog before the placement return so it fires
  while the bot is stuck repeating a placement.
- Log player feet, eye position and the current objectMouseOver hit.
possibleToPlace now searches with the stable ideal rotation instead of the
randomized aim, so the chosen placement no longer changes every tick (which
made the camera never settle and looked like it freezing). A placement that
still cannot be clicked after 2s now triggers a reposition instead of
standing still forever. Lower the empty-search nudge threshold from 3s to
1.5s.
When a chosen placement cannot be clicked for a second, if the target is
more than 1.5 blocks away the builder now paths next to it instead of
nudging around its current spot, which never moved and froze forever.
Also lower the per-target timeout from 2s to 1s.
Clicking merely because the aim was close to the target (closeToRot) could
hit a different face, placing directional blocks (stairs, etc.) the wrong
way round, after which the builder broke and replaced them forever. Now a
click only fires when the raytrace actually lands on the intended face.
unstickGoal used to return null forever once each neighbouring stand spot
had been tried once, so the bot would stand still with the composite goal
already satisfied and never walk to the remaining (far) targets. It now
prefers walking to the nearest out-of-reach target and restarts the shuffle
instead of giving up.
The placement branch cancelled pathing (CANCEL_AND_SET_GOAL) on the ticks
between its 1s timeouts, so the walk goal it returned was cancelled the very
next tick and the bot never moved, freezing in place. It now keeps returning
the walk command every tick until it is close enough to place.
- possibleToPlace only accepts placements comfortably within reach, so the
  builder walks closer instead of thrashing between several targets that sit
  right at the edge of the reach distance.
- Temporarily zero randomLooking/randomLooking113 while the builder is active
  so the camera snaps onto the target face and the click fires immediately
  instead of waiting for the jitter to line up. Restored on lost control.
The builder waited 30 ticks of finding nothing to place before repositioning,
which showed up as a 1.5s freeze between batches of blocks. Cut it to 12.
The LookBehavior ticks before the builder, so the rotation set with
updateTarget() is only applied the next tick. Because the placement search
uses the current rotation, the chosen target changed every tick before the
camera ever turned onto it, so almost nothing got placed (about one block
per 8s). The builder now sticks with a chosen placement for 4 ticks.
hasAnyItemThatWouldPlace validated the orientation at the ideal rotation, but
the click used the client's live rotation / hit face, so stairs, logs and
chests were regularly placed facing the wrong way and then broken and
replaced in an endless loop. The click now re-simulates getStateForPlacement
with the client's current rotation and only fires when the result matches the
schematic. The retry counter is now global (ticks without a correct placement)
so repositioning still triggers while the held target changes.
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