Host calls
Blocks
On this page
Reading and writing blocks, block entities and whole boxes of blocks, and reserving and guarding blocks.
Generated by tools/gen_api_docs.py; do not edit by hand. See host calls
for how a call is made and how values are encoded. Each example shows the shape of a Wasm
request with its required fields; the values in it are illustrative.
| Call | What it does |
|---|---|
destroy_block | Level.destroyBlock(pos, false): the block breaks -- its break particles and sound, the fluid it held left behind, BLOCK_DESTROY heard -- and drops nothing. |
block_at | The block at a position, by name, or None if that chunk is not readable. |
reserve_blocks | Reserves block states in one world for this plugin's own blocks: each of states is a state or a pattern (minecraft:note_block[instrument=banjo,note=3] is every state with those, whatever else; a bare name is every state of the block). |
release_blocks | Gives back states reserve_blocks took, by the same patterns; all of the plugin's in that world for none. |
guard_zones | Adds or replaces put and removes remove in the guard's table for one world, what the game's own forces ask natively: fluids, pistons, hoppers, dispensers, fire, growth, blasts and creatures. |
guard_hold | Holds every block as protected, or lets go: what a plugin sets while it loads its zones. |
guard_world_defaults | Sets what the guard allows of forces nobody controls in one world's blocks that no zone covers, as a zone's flags bits (1 blasts, 2 creatures, 4 fire): with Some(0) none of them in the wild. |
block_state_at | The whole state at a position, with its properties (minecraft:oak_stairs[facing=east,...]), or None if that chunk is not readable: what a plugin needs to put a block back exactly, through set_block. |
biome_at | The biome at a position, as the player standing there is in it (minecraft:plains): the game's computed biome, through the same zoom the client is told of. |
fluid_at | What fluid is at a position: "minecraft:water", "minecraft:lava", or None. |
block_property | The value of one of a block state's properties, as the game spells it. |
block_is | Whether the block there has one of the game's own per-state facts. |
set_block | Puts a block there. |
set_blocks | set_block for many blocks in one call: each position set to its state (properties and all, as set_block takes one), in the order given, each as set_block sets it. |
read_blocks | Every cell of the box between two corners, in one call: what an edit reads before it writes. |
write_blocks | Writes the box between two corners in one call: each cell an index into palette, x fastest, then z, then y, and KEEP_CELL for a cell left as it is. |
check_blocks | Whether every name is a block state this build knows: an error naming the first that is not. |
set_block_data | Merges snbt, a compound, into the block entity there, as /data merge block does: a compound field merged into the one held, any other field replacing it. |
set_blocks_data | set_block_data for many positions in one call, in the order given, each as set_block_data writes it: a landmark's signs at once. |
block_data | The block entity there as SNBT, as /data get block reads it: its id and what its type saves, with no position. |
blocks_are | block_is for many positions in one call: one answer per position, in order, each None where block_is would answer None (a chunk that is not readable). |
destroy_block
fn destroy_block(world: &World, at: BlockPos) -> bool
Level.destroyBlock(pos, false): the block breaks -- its break particles and sound, the
fluid it held left behind, BLOCK_DESTROY heard -- and drops nothing. Returns whether
anything was there to break.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
Reply: {"ok": ...} holding the Rust return value bool, encoded as in conventions.
{"call": "destroy_block", "world": "minecraft:overworld", "at": [10, 64, -3]}
block_at
fn block_at(world: &World, at: BlockPos) -> Option<String>
The block at a position, by name, or None if that chunk is not readable.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
Reply: {"ok": ...} holding the Rust return value Option<String>, encoded as in conventions.
{"call": "block_at", "world": "minecraft:overworld", "at": [10, 64, -3]}
reserve_blocks
fn reserve_blocks(plugin: &str, world: &World, states: &[String], break_ticks: Option<u32>, drops: &[BlockDrop]) -> Result<u32, String>
Reserves block states in one world for this plugin's own blocks: each of states is a
state or a pattern (minecraft:note_block[instrument=banjo,note=3] is every state with
those, whatever else; a bare name is every state of the block). In that world the server
then never changes a reserved state by itself: no shape or neighbour update (a note
block is not re-tuned, a mushroom block's faces are not worked out again), no redstone, no
note played or tuned by a punch or a click. A survival player breaks one on the server's
clock in break_ticks (the crack shown to everybody, their own client kept from finishing
it), through the usual block_break event, and it drops drops instead of its loot
table; with break_ticks None it never breaks and the plugin handles hits on it. A
creative player's swing breaks a breakable one outright. Place them with
set_block. Released when the plugin is unloaded. Answers how many states the
plugin now holds in that world; an error for a pattern that names no block or property,
a state another plugin holds, a bad drop, or more than 4096 states.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
states | list of block-state strings | no |
break_ticks | whole number, 0 or more | no |
drops | list | no |
Shape and limits, as the router words its errors: "break_ticks should be a whole number of ticks, not …"; "drops should be a list of …".
Router notes: plugin is never sent by a Wasm guest: the server fills it in from the manifest name.
Reply: {"ok": ...} holding the Rust return value Result<u32, String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "reserve_blocks", "world": "minecraft:overworld"}
release_blocks
fn release_blocks(plugin: &str, world: &World, states: &[String]) -> Result<u32, String>
Gives back states reserve_blocks took, by the same patterns; all of the
plugin's in that world for none. How many were given back.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
states | list of block-state strings | no |
Router notes: plugin is never sent by a Wasm guest: the server fills it in from the manifest name.
Reply: {"ok": ...} holding the Rust return value Result<u32, String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "release_blocks", "world": "minecraft:overworld"}
guard_zones
fn guard_zones(plugin: &str, world: &World, put: &[GuardZone], remove: &[u64]) -> Result<u32, String>
Adds or replaces put and removes remove in the guard's table for one world, what the
game's own forces ask natively: fluids, pistons, hoppers, dispensers, fire, growth, blasts
and creatures. Each zone is a full-height rectangle; see GuardZone. Answers how many
zones that world holds now. Released when the plugin is unloaded. One plugin holds the
table at a time; an error for another, or a zone with its corners reversed or wider than
262,144 blocks.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
put | list | no |
remove | list | no |
Shape and limits, as the router words its errors: "a zone's … should be a whole block coordinate"; "a zone's … should be a whole number"; "a zone's flags should fit 32 bits"; "put should be a list of zones"; "remove should be a list of zone ids".
Router notes: plugin is never sent by a Wasm guest: the server fills it in from the manifest name.
Reply: {"ok": ...} holding the Rust return value Result<u32, String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "guard_zones", "world": "minecraft:overworld"}
guard_hold
fn guard_hold(plugin: &str, held: bool) -> Result<(), String>
Holds every block as protected, or lets go: what a plugin sets while it loads its zones.
Wasm request
| Field | Type | Required |
|---|---|---|
held | true or false | yes |
Shape and limits, as the router words its errors: "held should be true or false".
Router notes: plugin is never sent by a Wasm guest: the server fills it in from the manifest name.
Reply: {"ok": ...} holding the Rust return value Result<(), String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "guard_hold", "held": true}
guard_world_defaults
fn guard_world_defaults(plugin: &str, world: &World, flags: Option<u32>) -> Result<(), String>
Sets what the guard allows of forces nobody controls in one world's blocks that no zone
covers, as a zone's flags bits (1 blasts, 2 creatures, 4 fire): with Some(0) none of
them in the wild. None goes back to the default, everything allowed. Zones are not
changed, nor what may cross a zone's line. Released when the plugin is unloaded. An error
for a world that is not there, or when another plugin holds the guard's table.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
flags | whole number, 0 or more | no |
Shape and limits, as the router words its errors: "flags should be a whole number that fits 32 bits, or null".
Router notes: plugin is never sent by a Wasm guest: the server fills it in from the manifest name.
Reply: {"ok": ...} holding the Rust return value Result<(), String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "guard_world_defaults", "world": "minecraft:overworld"}
block_state_at
fn block_state_at(world: &World, at: BlockPos) -> Option<String>
The whole state at a position, with its properties (minecraft:oak_stairs[facing=east,...]),
or None if that chunk is not readable: what a plugin needs to put a block back exactly,
through set_block.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
Reply: {"ok": ...} holding the Rust return value Option<String>, encoded as in conventions.
{"call": "block_state_at", "world": "minecraft:overworld", "at": [10, 64, -3]}
biome_at
fn biome_at(world: &World, at: BlockPos) -> Option<String>
The biome at a position, as the player standing there is in it (minecraft:plains): the
game's computed biome, through the same zoom the client is told of. Never loads a chunk: a
chunk in memory is read as it is, and anywhere else the world's biome source answers what
generation would put there. None for a world with neither.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
Reply: {"ok": ...} holding the Rust return value Option<String>, encoded as in conventions.
{"call": "biome_at", "world": "minecraft:overworld", "at": [10, 64, -3]}
fluid_at
fn fluid_at(world: &World, at: BlockPos) -> Option<String>
What fluid is at a position: "minecraft:water", "minecraft:lava", or None.
Not derivable from block_at, and that is the whole reason it exists.
block_at answers with a block's name, so a waterlogged staircase comes back as
"minecraft:oak_stairs" -- and the game holds that a body with its eyes in one is
under water and drowning. A rule that asked for the block name and compared it to
"minecraft:water" would let a player breathe inside half the blocks in an ocean
monument.
Flowing counts. isInLava and isEyeInFluid both read the fluid state rather than
the block, so the thin edge of a lava flow burns exactly as the source does.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
Reply: {"ok": ...} holding the Rust return value Option<String>, encoded as in conventions.
{"call": "fluid_at", "world": "minecraft:overworld", "at": [10, 64, -3]}
block_property
fn block_property(world: &World, at: BlockPos, property: &str) -> Option<String>
The value of one of a block state's properties, as the game spells it.
None for a chunk that is not readable, a block that has no such property, or a
name this build does not know -- all three mean "nobody can say", and a rule that
treated them differently would be inventing an answer.
For example block_property(world, at, "lit") tells a lit campfire, which hurts whoever
stands in it, from an unlit one, which does not.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
property | string | yes |
Reply: {"ok": ...} holding the Rust return value Option<String>, encoded as in conventions.
{"call": "block_property", "world": "minecraft:overworld", "at": [10, 64, -3], "property": "facing"}
block_is
fn block_is(world: &World, at: BlockPos, fact: BlockFact) -> Option<bool>
Whether the block there has one of the game's own per-state facts.
The table's facts, not the state's properties. block_property answers what
the blockstate says -- lit, waterlogged, facing. This answers what the generated block table says about the state as a whole, and
the two are different questions with different answers for the same block: a lit
campfire and an unlit one differ in block_property and agree in every BlockFact.
None for a chunk that is not readable or a state this build does not know, which are
both "nobody can say" -- and a rule that read that as false would have a body walk
into an unloaded chunk rather than suffocate in it.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
fact | solid, falls, requires-tool, replaceable, propagates-skylight, suffocating or air | yes |
Router notes: The fact is named, not numbered: a guest never depends on the order of an enum.
Reply: {"ok": ...} holding the Rust return value Option<bool>, encoded as in conventions.
{"call": "block_is", "world": "minecraft:overworld", "at": [10, 64, -3], "fact": "solid"}
set_block
fn set_block(world: &World, at: BlockPos, block: &str) -> bool
Puts a block there. Returns whether anything changed.
The name may carry properties the way a command does —
"minecraft:oak_door[half=upper]" — because a plugin that can only place default
states cannot place half the blocks in the game.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
block | block state, e.g. minecraft:oak_stairs[facing=east] (an old name is renamed) | yes |
Reply: {"ok": ...} holding the Rust return value bool, encoded as in conventions.
{"call": "set_block", "world": "minecraft:overworld", "at": [10, 64, -3], "block": "minecraft:stone"}
set_blocks
fn set_blocks(world: &World, blocks: &[(BlockPos, String)]) -> Result<u32, String>
set_block for many blocks in one call: each position set to its state (properties
and all, as set_block takes one), in the order given, each as set_block sets it. At most
MAX_BULK (constants) at once. Answers how many changed.
Checked before anything is written: an error, setting nothing, for too many or for a state
this build does not know (the error names it). Ok(0) for a world this server does not have.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
blocks | list | yes |
Shape and limits, as the router words its errors: "blocks should be a list of …"; "at most … blocks at once, not …".
Router notes: Every state through the rename table, as set_block's one is.
Reply: {"ok": ...} holding the Rust return value Result<u32, String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "set_blocks", "world": "minecraft:overworld", "blocks": []}
read_blocks
fn read_blocks(world: &World, min: BlockPos, max: BlockPos) -> Result<crate::BlockBox, String>
Every cell of the box between two corners, in one call: what an edit reads before it writes.
At most MAX_BULK (constants) cells, MAX_BOX_COLUMNS (constants)
columns and MAX_BOX_ENTITY_BYTES (constants) of block entities: a box past
any of these is an error, not a part of its contents.
Never generates. A box reaching a column that has never been generated answers those
columns in missing and no cells; a plugin queues them with queue_chunks and asks again.
A column on disk is read in. An error for a box inside out, too big, past the world's floor
or ceiling, in a world this server does not have, or reaching a column that cannot be read.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
min | [x, y, z], whole numbers | yes |
max | [x, y, z], whole numbers | yes |
Router notes: A section is 8 KiB of indices: JSON numbers would be four times that, and it is the guest that parses them, on its fuel.
Reply: {"ok": ...} holding the Rust return value Result<crate::BlockBox, String>, encoded as in conventions; objects in it carry palette, cells, data, at, snbt. An Err arrives as {"error": "..."}.
{"call": "read_blocks", "world": "minecraft:overworld", "min": [0, 60, 0], "max": [15, 70, 15]}
write_blocks
fn write_blocks(world: &World, min: BlockPos, max: BlockPos, palette: &[String], cells: &[u16]) -> Result<crate::BlocksWritten, String>
Writes the box between two corners in one call: each cell an index into palette, x
fastest, then z, then y, and KEEP_CELL (constants) for a cell left as it is.
Exactly the states named, and nothing else happens. No shape, neighbour, tick or fluid
update, no drops, no redstone recalculated, no entity moved: this is an edit, not a player
building. A tick already waiting on a cell finds another block there and does nothing. Block entities still come and go
with their blocks (their data is set_blocks_data's), a screen open on a replaced container
is closed first, and water written to a dimension that evaporates it goes as any other
write's. Players are told as for any change, a section at a time. Light follows when the
edit has left the column, a few columns a tick, and only for cells whose light changed.
Checked before anything is written: an error, setting nothing, for a name this build does
not know, a cell past the palette, the wrong number of cells, or a box read_blocks
would refuse. Never generates: missing names the columns and nothing is written.
Wasm request
| Field | Type | Required |
|---|---|---|
palette | list of block-state strings | yes |
world | world name, e.g. minecraft:overworld | yes |
cells | string | yes |
min | [x, y, z], whole numbers | yes |
max | [x, y, z], whole numbers | yes |
Shape and limits, as the router words its errors: "cells is not base64: …"; "cells should be two bytes a cell".
Reply: {"ok": ...} holding the Rust return value Result<crate::BlocksWritten, String>, encoded as in conventions; objects in it carry changed, missing. An Err arrives as {"error": "..."}.
{"call": "write_blocks", "palette": ["minecraft:air", "minecraft:stone"], "world": "minecraft:overworld", "cells": "AAABAA==", "min": [0, 60, 0], "max": [15, 70, 15]}
check_blocks
fn check_blocks(palette: &[String]) -> Result<(), String>
Whether every name is a block state this build knows: an error naming the first that is not.
Wasm request
| Field | Type | Required |
|---|---|---|
palette | list of block-state strings | yes |
Reply: {"ok": ...} holding the Rust return value Result<(), String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "check_blocks", "palette": ["minecraft:air", "minecraft:stone"]}
set_block_data
fn set_block_data(world: &World, at: BlockPos, snbt: &str) -> Result<bool, String>
Merges snbt, a compound, into the block entity there, as /data merge block does: a
compound field merged into the one held, any other field replacing it. For a sign's text --
{front_text:{messages:["Strongroom","","",""],color:"orange",has_glowing_text:1b}} -- a
banner's patterns, a chest's Items or loot table, a spawner's, a command block's line. The
block is not changed; set it first with set_block.
The block entity's own type decides what is read, as the game's loadWithComponents does:
x, y, z and components are ignored, and an id must be the block entity's own type.
An error, writing nothing, for SNBT that is not a compound, a block with no block entity, an
id naming another type, or a field this server does not write for that type (the error
names it). Players watching are sent the block entity, and it is saved with the world.
Ok(true) when the data changed, Ok(false) when it already held what was given, the chunk
is not loaded (what set_block does there) or the world is not one this server has.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
snbt | string | yes |
Router notes: The SNBT is the block entity's own, passed as it is: names inside it (a chest's items) are the version's own, which is what /data merge reads too.
Reply: {"ok": ...} holding the Rust return value Result<bool, String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "set_block_data", "world": "minecraft:overworld", "at": [10, 64, -3], "snbt": "{}"}
set_blocks_data
fn set_blocks_data(world: &World, entries: &[(BlockPos, String)]) -> Result<u32, String>
set_block_data for many positions in one call, in the order given, each as
set_block_data writes it: a landmark's signs at once. At most MAX_BULK (constants).
Answers how many changed.
Checked before anything is written: an error, writing nothing, for too many, or for any
entry set_block_data would refuse (the error names its position). Ok(0) for a world this
server does not have.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
entries | list | yes |
Shape and limits, as the router words its errors: "entries should be a list of …"; "at most … entries at once, not …".
Reply: {"ok": ...} holding the Rust return value Result<u32, String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "set_blocks_data", "world": "minecraft:overworld", "entries": []}
block_data
fn block_data(world: &World, at: BlockPos) -> Option<String>
The block entity there as SNBT, as /data get block reads it: its id and what its type
saves, with no position. None for a block with no block entity or a chunk not loaded.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
at | [x, y, z], whole block coordinates | yes |
Reply: {"ok": ...} holding the Rust return value Option<String>, encoded as in conventions.
{"call": "block_data", "world": "minecraft:overworld", "at": [10, 64, -3]}
blocks_are
fn blocks_are(world: &World, positions: &[BlockPos], fact: BlockFact) -> Result<Vec<Option<bool>>, String>
block_is for many positions in one call: one answer per position, in order, each
None where block_is would answer None (a chunk that is not readable). At most
MAX_BULK (constants) positions; an error for more.
Wasm request
| Field | Type | Required |
|---|---|---|
world | world name, e.g. minecraft:overworld | yes |
fact | solid, falls, requires-tool, replaceable, propagates-skylight, suffocating or air | yes |
positions | list | yes |
Shape and limits, as the router words its errors: "positions should be a list of [x, y, z]"; "at most … positions at once, not …".
Reply: {"ok": ...} holding the Rust return value Result<Vec<Option<bool>>, String>, encoded as in conventions. An Err arrives as {"error": "..."}.
{"call": "blocks_are", "world": "minecraft:overworld", "fact": "solid", "positions": []}
From docs/api/reference/host-calls/blocks.md in the RustMC repository at bbd81209ad.