class
Rosegold::Bot
- Rosegold::Bot
- Rosegold::EventEmitter
- Reference
- Object
Overview
Start here to write a Minecraft bot.
Bot is Rosegold's main scripting API. This page is the starting point for
connecting, moving, interacting, reading world state, managing inventory, and
reacting to events.
Use the task links below to find an operation, then its method documentation
for arguments, overloads, and examples.
CivMC bots should use the restricted rosegold-civmc API and its example template. The core API below exposes world observations that CivMC bots cannot use.
Your first bot
Create a project from the example template,
select the main dependency branch as shown in the
installation guide,
then use Bot to connect and run your script:
require "rosegold"
bot = Rosegold::Bot.new("localhost:25565")
begin
bot.join_game
bot.chat "Hello from Rosegold."
bot.wait_ticks 20
ensure
bot.disconnect("Script finished") if bot.connected?
end
Find an operation
- Connect and read player state:
.new,#join_game,#disconnect,#location,#health,#food,#chat. - Read received world state:
#block_at,#find_block,#find_blocks,#entity,#entities,#nearest_entity.#worldand#clientexpose live state for advanced callers. - Move and look:
#move_to,#look_at,#look,#sprint,#sneak. - Mine, place, use, and eat:
#dig,#place_block_against,#use_hand,#start_using_hand,#stop_using_hand,#eat,#eat!. - Manage items and containers:
#inventoryreturns anInventory;#open_container_handleyields aContainerHandle. - Craft and enchant:
#craft,#craft_all,#craft_pattern,#enchant. - React and wait: inherited
EventEmitter#on,EventEmitter#once, andEventEmitter#wait_for, plus#wait_ticks. - Watch your bot in Minecraft:
SpectateServer.
For longer scripts, see the runnable examples and idiom guide.
Execution model
Bot forwards game events from its Client and exposes movement, inventory,
interaction, and crafting operations. Most operations that wait for the
server yield cooperatively through ticks rather than blocking the process.
Event handlers run synchronously; use spawn inside a handler for work that
waits for ticks or more packets.
Defined in:
rosegold/bot.crrosegold/bot/world_api.cr
Constructors
-
.new(address : String)
Creates a bot for address without connecting it.
-
.new(client : Rosegold::Client)
Wraps an existing client.
Class Method Summary
-
.join_game(address : String, timeout_ticks = 1200)
Connects to address and waits until the player has joined the world.
-
.run(address : String, port : Int32 = 25565, offline : NamedTuple(uuid: String, username: String) | Nil = nil, timeout_ticks : Int32 = 1200, &)
Joins address and runs the block with a fresh bot after each reconnect.
Instance Method Summary
-
#attack(target : Vec3d | Nil | Look | Nil = nil)
Optionally aims at target, then presses and releases attack immediately.
-
#auto_respawn=(auto_respawn : Bool)
Whether a death automatically starts a background
#respawnattempt. -
#auto_respawn? : Bool
Whether a death automatically starts a background
#respawnattempt. -
#block_at(position : Vec3i) : BlockSnapshot | Nil
Returns received block state, or nil outside loaded chunks and world height.
-
#block_at(position : Vec3d) : BlockSnapshot | Nil
Floors fractional coordinates, including negative coordinates, to a block.
-
#can_craft?(recipe : RecipeDisplayEntry) : Bool
Whether the player inventory has one complete set of ingredients for recipe.
-
#chat(message : String)
Sends a chat message or slash command without waiting for a response.
-
#client : Client
The underlying client for protocol and engine access.
-
#connect
Opens and authenticates a connection.
-
#connected?
Whether the connection exists and has not been closed.
-
#container_type : Menu.class | Nil
The class of the currently open non-player menu, or
nilfor the player inventory. -
#craft(item_name : String, count : Int32 = 1, table : Vec3i | Nil = nil)
Attempts count recipe placements producing item_name.
-
#craft(recipe : RecipeDisplayEntry, count : Int32 = 1, table : Vec3i | Nil = nil)
Attempts count placements of a specific synchronized recipe.
-
#craft_all(item_name : String, table : Vec3i | Nil = nil)
Crafts the maximum possible amount of a craftable recipe producing item_name.
-
#craft_all(recipe : RecipeDisplayEntry, table : Vec3i | Nil = nil)
Crafts the maximum possible amount from a specific synchronized recipe.
-
#craft_pattern(pattern : Array(Array(String | Nil)), count : Int32 = 1, table : Vec3i | Nil = nil)
Crafts by manually placing the named items from pattern into the grid.
-
#dead?
Whether the player's health is zero or below.
-
#dig(ticks : Int32, target : Vec3d | Nil | Look | Nil = nil)
Optionally aims at target, holds attack for ticks, then releases it.
-
#disconnect(reason : String)
Closes the connection with the server-visible reason.
-
#disconnect_reason
The server-supplied close reason, or
nilwhile connected or before a connection exists. -
#drop_hand_full
Drops the full main-hand stack.
-
#drop_hand_single
Drops one item from the main-hand stack.
-
#eat : Nil
Best-effort version of
#eat!. -
#eat!
Eats allowed food from inventory when
#should_eat?is true. -
#effect_by_name(name)
Finds an active status effect by its display name, ignoring case and spaces.
-
#effects
The active status effects reported by the server.
-
#enchant(spec, *, option : Int32, timeout : Time::Span = 5.seconds) : Slot
Enchants one matching inventory item using option (0 through 2).
-
#enchant(*, option : Int32, timeout : Time::Span = 5.seconds, &spec : Slot -> _) : Slot
Enchants the first inventory item for which the block returns truthy.
-
#entities : Array(EntitySnapshot)
Detached snapshots of entities currently tracked in this dimension.
-
#entity(id : Int) : EntitySnapshot | Nil
Returns a detached entity snapshot, or nil if the entity is not tracked.
-
#estimated_break_ticks(block_name : String, *, buffer_ticks : Int32 = 10) : Int32
Estimates how many ticks it will take this bot to break the named block.
-
#experience_level : UInt32
The player's server-reported experience level.
-
#experience_progress : Float32
The player's server-reported progress toward the next experience level.
-
#eyes
Current eye position in world coordinates.
-
#feet
Deprecated alias for
#location.DEPRECATED Use
bot.locationinstead ofbot.feet -
#find_block(name : String, *, radius : Number, center : Vec3d | Vec3i = location) : BlockSnapshot | Nil
Returns the nearest matching loaded block within the required radius.
-
#find_blocks(name : String, *, radius : Number, center : Vec3d | Vec3i = location, limit : Int32 = 1) : Array(BlockSnapshot)
Searches loaded blocks within a spherical radius, nearest first.
-
#food
Current hunger points, from 0 through 20.
-
#full_health?
Whether the player has at least 20 health points.
-
#gamemode
Current game mode ID as supplied by the server.
-
#has_slow_falling?
Whether Slow Falling is active.
-
#health
Current health in half-hearts.
-
#host
The configured Minecraft server hostname.
-
#hotbar_selection
The selected main-hand hotbar slot, numbered 1 through 9.
-
#hotbar_selection=(index : UInt8)
Selects a main-hand hotbar slot, numbered 1 through 9.
-
#inventory : Inventory
The inventory facade for the player and currently open menu.
-
#join_game(timeout_ticks = 1200)
Connects and waits for a spawned player, returning the underlying
Client. -
#join_game(timeout_ticks = 1200, &)
Connects, yields the underlying
Clientafter spawning, then disconnects when the block returns normally. -
#jump_boost_level
Current Jump Boost amplifier plus one, or zero when Jump Boost is absent.
-
#jump_by_height(height = 1, timeout_ticks = 20)
Queues a jump and waits until the feet are height blocks above their start.
-
#keys
Mutable movement-key state used by physics on subsequent ticks.
-
#land_on_ground(timeout_ticks = 120)
Waits until the player's feet y coordinate stops changing.
-
#leave_bed
Leaves the current bed.
-
#levitation_level
Current Levitation amplifier plus one, or zero when Levitation is absent.
-
#location
The player's current feet position in world coordinates.
-
#look
The player's current
Lookdirection as a yaw/pitch pair in degrees. -
#look(&block : Look -> Look)
Computes the new look from the current look.
-
#look=(look : Look)
Sets the look direction.
-
#look=(vec : Vec3d)
Aims the look at a world position.
-
#look_at(location : Vec3d)
Aims from the eyes at a known world position and waits for the look update.
-
#look_at_horizontal(location : Vec3d)
Ignores y coordinate; useful for looking straight while moving.
-
#main_hand
The stack currently held in the main hand.
-
#move_to(location : Vec3d, stuck_timeout_ticks : Int32 = 60)
Moves straight towards the exact
#location(decimal coordinates are honored verbatim). -
#move_to(location : Vec3i, stuck_timeout_ticks : Int32 = 60)
Moves to the center of the given block coordinate (
x + 0.5,z + 0.5), preserving the bot's current feet#y. -
#move_to(x : Float, z : Float, stuck_timeout_ticks : Int32 = 60)
Moves straight towards the exact
(x, z)(decimal coordinates are honored verbatim). -
#move_to(x : Int, z : Int, stuck_timeout_ticks : Int32 = 60)
Moves to the center of the given block column (
x + 0.5,z + 0.5). -
#move_to(stuck_timeout_ticks : Int32 = 10, &block : Vec3d -> Vec3d)
Computes the destination location from the current feet location.
-
#nearest_entity(*, max_distance : Number | Nil = nil) : EntitySnapshot | Nil
Returns the nearest tracked entity, optionally bounded by distance.
-
#nearest_entity(*, max_distance : Number | Nil = nil, &predicate : EntitySnapshot -> Bool) : EntitySnapshot | Nil
Filters detached entity snapshots before choosing the nearest match.
-
#open_container(timeout : Time::Span = 5.seconds, &)
Opens a container (chest, barrel, etc.) and yields control for interaction.
-
#open_container_handle(timeout : Time::Span = 5.seconds, &)
Opens a container and yields a ContainerHandle for typed interaction.
-
#open_container_handle(command : String, timeout : Time::Span = 5.seconds, &)
Runs command, waits for it to open a container, then yields its handle.
-
#pick_item_from_block(pos : Vec3i, include_data : Bool = false)
Pick the item at the given block position (middle-click on a block).
-
#pitch
The current vertical look angle in degrees.
-
#pitch=(pitch : Float64)
Sets the vertical look angle in degrees and waits for it to reach the server.
-
#place_block_against(block : Vec3i, face : BlockFace)
Aims at face of block, then presses and releases use with the main hand.
-
#port
The configured Minecraft server port.
-
#recipe_registry
The synchronized recipe registry for the connected server.
-
#recipes_for(item_name : String) : Array(RecipeDisplayEntry)
Returns every synchronized recipe whose result matches item_name.
-
#respawn(timeout_ticks = 1200)
Revives a dead player and waits for its spawn confirmation.
-
#riding : Mount | Nil
A snapshot of the direct mount's type and location, or
nilwhen unmounted. -
#riding?(type : String | Nil = nil) : Bool
Whether the player is riding, optionally matching an exact entity type.
-
#run_command_with_confirmation(command : String, expected_message : String, max_tries : Int32 = 3, inverse_message : String | Nil = nil)
Runs a slash command and waits for a confirmation message from the server.
-
#saturation
Current saturation level.
-
#should_eat?
Whether
#eat!will attempt to consume food at the current health and hunger. -
#slowness_level
Current Slowness amplifier plus one, or zero when Slowness is absent.
-
#sneak(sneaking = true)
Enables or disables sneaking.
-
#sneaking?
Whether the player is currently sneaking.
-
#spawned?
Whether the server has completed player spawn and world state is ready.
-
#speed_level
Current Speed amplifier plus one, or zero when Speed is absent.
-
#sprint(sprinting = true)
Enables or disables sprinting.
-
#sprinting?
Whether the player is currently sprinting.
-
#start_digging(target : Vec3d | Nil | Look | Nil = nil)
Optionally aims at target, then holds the attack button to begin digging.
-
#start_jump
Queues a jump for the next tick on which the player is on the ground.
-
#start_using_hand(hand : Hand = :main_hand)
Holds the use button for hand.
-
#stop_digging
Releases an active dig action immediately.
-
#stop_jump : Nil
Clears a pending jump without changing other movement inputs.
-
#stop_moving
Cancels
#move_to, releases movement keys, and clears a pending jump. -
#stop_using_hand
Releases an active use action immediately.
-
#subscribe(event_class : Class)
Forwards events of event_class emitted by the underlying client to this bot.
-
#swap_hands(timeout : Time::Span = 5.seconds) : Nil
Closes any container and waits for the server to confirm both hands.
-
#total_experience : UInt32
The player's server-reported total experience.
-
#unsneak
Disables sneaking.
-
#unsprint
Disables sprinting.
-
#use_hand(target : Vec3d | Nil | Look | Nil = nil, hand : Hand = :main_hand)
Queues one press and release of use in hand, optionally aiming at target first.
-
#username
The player name, or
nilbefore login completes. -
#uuid
The authenticated player UUID, or
nilbefore login completes. -
#wait_tick
Waits for one client game tick, returning the event or
nilafter one second. -
#wait_ticks(ticks : Int32)
Waits for ticks client game ticks.
-
#world : Dimension
The current dimension, including its live chunks and entities.
-
#x
The feet-position x coordinate.
-
#y
The feet-position y coordinate.
-
#yaw
The current horizontal look angle in degrees.
-
#yaw=(yaw : Float64)
Sets the horizontal look angle in degrees and waits for it to reach the server.
-
#z
The feet-position z coordinate.
Instance methods inherited from class Rosegold::EventEmitter
emit_event(event : Event)
emit_event,
event_handlers : Handlers
event_handlers,
off(event_type : T.class, id : UUID) forall T
off,
on(event_type : T.class, id : UUID = UUID.random, &block : T -> ) forall T
on,
once(event_type : T.class, &block : T -> ) forall T
once,
wait_for(event_type : T.class, timeout : Time::Span = 5.seconds) forall Twait_for(event_type : T.class, timeout : Time::Span = 5.seconds, &) forall T wait_for
Constructor Detail
Creates a bot for address without connecting it.
Call #join_game before issuing world operations.
Wraps an existing client. The client may be connected later with #join_game.
Class Method Detail
Connects to address and waits until the player has joined the world. Raises if joining does not complete within timeout_ticks game ticks.
Joins address and runs the block with a fresh bot after each reconnect.
A server disconnect or network error retries with backoff; authentication
failures honor provider cooldowns. Other script errors propagate.
Return while connected or call Bot#disconnect to stop. The block must
check #connected? or perform network operations to notice a disconnect.
Re-establish script-owned state each time the block runs.
Instance Method Detail
Optionally aims at target, then presses and releases attack immediately.
Whether a death automatically starts a background #respawn attempt.
Enabled by default.
Whether a death automatically starts a background #respawn attempt.
Enabled by default.
Returns received block state, or nil outside loaded chunks and world height. Properties use the versioned game data's string values.
Floors fractional coordinates, including negative coordinates, to a block.
Whether the player inventory has one complete set of ingredients for recipe.
Returns false for recipe display types that cannot be crafted in a grid.
Sends a chat message or slash command without waiting for a response.
Returns true when sent, false if sending fails or a chat message exceeds
256 bytes. A successful send does not confirm server acceptance.
Opens and authenticates a connection. It returns once packet processing has
started, before the player is necessarily spawned. Use #join_game when
the next operation needs world state.
Whether the connection exists and has not been closed. Returns nil before connecting.
The class of the currently open non-player menu, or nil for the player inventory.
Attempts count recipe placements producing item_name. Each placement may produce several items; count is not an item count.
Waits for recipe placement and output slot updates. Supply table for a
recipe that needs a crafting table. Raises CraftingError when no recipe,
materials, or required table position is available. It can stop early when
no output appears within ten ticks or the inventory cannot accept the output.
Inspect inventory counts when the exact produced amount matters.
Attempts count placements of a specific synchronized recipe.
Each placement may produce several result items.
Waits for recipe placement and output slot updates. Raises CraftingError
if materials or a required crafting table position are unavailable.
Crafts the maximum possible amount of a craftable recipe producing item_name.
Raises CraftingError when no usable recipe, materials, or table position exists.
Crafts the maximum possible amount from a specific synchronized recipe.
Raises CraftingError if its requirements cannot be met.
Crafts by manually placing the named items from pattern into the grid. Use this for custom recipes or recipes absent from the recipe book.
The pattern is at most 3 by 3; nil leaves a grid cell empty. Provide
table for patterns larger than 2 by 2. Raises CraftingError for an
invalid pattern, missing item, or missing table position.
bot.craft_pattern([
["iron_ingot", "iron_ingot", "iron_ingot"],
[nil, "stick", nil],
[nil, "stick", nil],
], table: crafting_table_position)
Optionally aims at target, holds attack for ticks, then releases it. Waits exactly ticks client ticks after starting the dig.
The server-supplied close reason, or nil while connected or before a connection exists.
Best-effort version of #eat!. Logs a warning if eating raises, including
when no allowed food is available, and returns nil without re-raising.
Uses the same hunger thresholds and food selection as #eat!.
This blocks while eating; returning does not guarantee hunger was restored.
Eats allowed food from inventory when #should_eat? is true.
Does nothing at 18+ food, or at 15+ food with full health. Otherwise,
blocks until food reaches 18, the held food runs out, or eating times out.
Raises when no allowed food is available and propagates interaction errors.
A timeout only logs a warning. Use #eat for best-effort eating instead.
Finds an active status effect by its display name, ignoring case and spaces.
Returns nil when the effect is absent.
Enchants one matching inventory item using option (0 through 2).
The caller must face a reachable table, with no container open and an empty
cursor. Opens, supplies, enchants, collects, and closes the table within
timeout, returning a detached server-confirmed result. Books expose their
enchantments through Slot#stored_enchantments.
enchanted = bot.enchant("diamond_pickaxe", option: 2)
A timeout does not undo a server-applied enchantment. This does not retry, discover a table, or predict enchantments beyond the displayed offer clue. A timed-out opening closes a late table response. Another enchant attempt is rejected until a response, acknowledgement, or disconnect settles it.
Enchants the first inventory item for which the block returns truthy.
Detached snapshots of entities currently tracked in this dimension.
Returns a detached entity snapshot, or nil if the entity is not tracked.
Estimates how many ticks it will take this bot to break the named block.
Uses the bot's current main-hand item and live player state (Haste,
gamemode, on_ground, etc.), so the estimate reflects what the bot would
actually experience right now — not a fresh Player.new baseline.
buffer_ticks is added on top of the computed mining time to absorb network latency and server tick variance; tune it down to 0 for a pure client-side estimate, or up if you're seeing the bot release dig too early.
Raises ArgumentError if block_name isn't in the active version's MCData.
bot.estimated_break_ticks("stone") # => e.g. 160
bot.estimated_break_ticks("stone", buffer_ticks: 0) # => e.g. 150
The player's server-reported progress toward the next experience level.
Returns the nearest matching loaded block within the required radius.
Searches loaded blocks within a spherical radius, nearest first. Distances use block coordinates. Equal distances sort by x, y, then z.
Selects a main-hand hotbar slot, numbered 1 through 9.
Raises ArgumentError for an index outside that range.
The inventory facade for the player and currently open menu.
Connects and waits for a spawned player, returning the underlying Client.
Raises if joining exceeds timeout_ticks or the connection closes.
Connects, yields the underlying Client after spawning, then disconnects when
the block returns normally. If it raises, the exception propagates without
disconnecting; use an explicit ensure for unconditional cleanup.
Queues a jump and waits until the feet are height blocks above their start. Raises if the player cannot rise or does not reach that height before timeout_ticks. It does not wait for landing.
Waits until the player's feet y coordinate stops changing. Raises if this does not happen within timeout_ticks.
Computes the new look from the current look. The block receives the
current Look (yaw/pitch in degrees) and must return a new Look,
e.g. bot.look { |l| l.with_yaw(l.yaw + 90) }.
Waits for the new look to be sent to the server.
Sets the look direction. Look is a yaw/pitch pair in degrees
(see Rosegold::Look for the angle convention and constants like
Look::NORTH, Look::SOUTH.down, etc.).
Waits for the new look to be sent to the server.
Aims the look at a world position. Equivalent to #look_at(vec).
Waits for the new look to be sent to the server.
Aims from the eyes at a known world position and waits for the look update.
Ignores y coordinate; useful for looking straight while moving. Waits for the new look to be sent to the server.
Moves straight towards the exact #location (decimal coordinates are
honored verbatim).
Waits for arrival.
stuck_timeout_ticks specifies how many consecutive stuck ticks before throwing MovementStuck.
Moves to the center of the given block coordinate (x + 0.5,
z + 0.5), preserving the bot's current feet #y. Use a Vec3d overload
if you need to land on an exact non-centered position.
Moves straight towards the exact (x, z) (decimal coordinates are
honored verbatim). #y is taken from the bot's current feet location.
Waits for arrival.
stuck_timeout_ticks specifies how many consecutive stuck ticks before throwing MovementStuck.
Moves to the center of the given block column (x + 0.5, z + 0.5).
Use the Float overload to target an exact non-centered position.
Computes the destination location from the current feet location.
Moves straight towards the destination.
Waits for arrival.
stuck_timeout_ticks specifies how many consecutive stuck ticks before throwing MovementStuck.
Returns the nearest tracked entity, optionally bounded by distance.
Filters detached entity snapshots before choosing the nearest match.
Opens a container (chest, barrel, etc.) and yields control for interaction. Automatically uses the main hand, waits for container content to load, executes the provided block, then closes the container.
bot.open_container do
bot.inventory.deposit_at_least(10, "diamond")
bot.inventory.withdraw_at_least(5, "emerald")
end
Caller must already be looking at the container block. Raises
ContainerOpenError if its content does not arrive within timeout.
The container is closed even if the block raises.
Opens a container and yields a ContainerHandle for typed interaction. The handle provides intent-level operations (withdraw, deposit) and typed menu access (as_chest, as_furnace, etc.).
bot.open_container_handle do |handle|
handle.deposit("diamond", 10)
handle.withdraw("emerald", 5)
if chest = handle.as_chest
chest.contents.each { |slot| puts slot.name }
end
end
Caller must already be looking at the container block. Raises
ContainerOpenError if its content does not arrive within timeout.
The handle is closed even if the block raises.
Runs command, waits for it to open a container, then yields its handle.
This is for servers that expose a container through a command rather than a
block interaction. Raises ContainerOpenError on timeout and closes the
handle even if the block raises.
Pick the item at the given block position (middle-click on a block). The server finds the matching item in the player's inventory, moves it to the hotbar, and sends the appropriate slot update packets.
Sets the vertical look angle in degrees and waits for it to reach the server.
Aims at face of block, then presses and releases use with the main hand. It queues the placement attempt without waiting for confirmation.
Returns every synchronized recipe whose result matches item_name.
Revives a dead player and waits for its spawn confirmation. Does nothing while alive. Raises if spawning exceeds timeout_ticks.
A snapshot of the direct mount's type and location, or nil when unmounted.
Unknown entity type IDs have a nil type. No other entity data is exposed.
Whether the player is riding, optionally matching an exact entity type.
Accepts names with or without the minecraft: prefix.
Runs a slash command and waits for a confirmation message from the server.
Each attempt waits up to five seconds. Retries after a timeout or an inverse message. Use only when replaying the command is acceptable: a missing confirmation does not prove the server failed to execute it.
The expected_message is matched after stripping formatting codes. If inverse_message is provided and received, the command will retry, which is useful for toggle commands where the bot may be in the wrong state.
Returns true if the expected message is received within max_tries
attempts, false otherwise.
bot.run_command_with_confirmation(
"/ignoregroup !",
"You stopped ignoring !.",
3,
"You are now ignoring !"
)
Enables or disables sneaking. The next client tick sends the changed input state.
Enables or disables sprinting. The next client tick sends the changed input state.
Optionally aims at target, then holds the attack button to begin digging.
Call #stop_digging to release it.
Holds the use button for hand. Call #stop_using_hand to release it.
Forwards events of event_class emitted by the underlying client to this bot.
This is primarily useful when extending Bot; normal consumers subscribe
with #on to the events already forwarded during initialization.
Closes any container and waits for the server to confirm both hands. Unchanged stacks need no confirmation. A timeout does not undo the swap.
Queues one press and release of use in hand, optionally aiming at target first. Releases any held use action. Repeated calls before a tick coalesce into one press. The target raytrace happens on the next tick eligible under the use cooldown. This does not wait for a world-result confirmation.
Waits for one client game tick, returning the event or nil after one second.
A timeout does not raise, including when disconnected.
Waits for ticks client game ticks. Each tick has the same one-second timeout
as #wait_tick.
The current dimension, including its live chunks and entities.
Sets the horizontal look angle in degrees and waits for it to reach the server.