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.

CallWhat it does
destroy_blockLevel.destroyBlock(pos, false): the block breaks -- its break particles and sound, the fluid it held left behind, BLOCK_DESTROY heard -- and drops nothing.
block_atThe block at a position, by name, or None if that chunk is not readable.
reserve_blocksReserves 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_blocksGives back states reserve_blocks took, by the same patterns; all of the plugin's in that world for none.
guard_zonesAdds 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_holdHolds every block as protected, or lets go: what a plugin sets while it loads its zones.
guard_world_defaultsSets 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_atThe 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_atThe 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_atWhat fluid is at a position: "minecraft:water", "minecraft:lava", or None.
block_propertyThe value of one of a block state's properties, as the game spells it.
block_isWhether the block there has one of the game's own per-state facts.
set_blockPuts a block there.
set_blocksset_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_blocksEvery cell of the box between two corners, in one call: what an edit reads before it writes.
write_blocksWrites 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_blocksWhether every name is a block state this build knows: an error naming the first that is not.
set_block_dataMerges 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_dataset_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_dataThe block entity there as SNBT, as /data get block reads it: its id and what its type saves, with no position.
blocks_areblock_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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
stateslist of block-state stringsno
break_tickswhole number, 0 or moreno
dropslistno

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
stateslist of block-state stringsno

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
putlistno
removelistno

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

FieldTypeRequired
heldtrue or falseyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
flagswhole number, 0 or moreno

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes
propertystringyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes
factsolid, falls, requires-tool, replaceable, propagates-skylight, suffocating or airyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes
blockblock 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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
blockslistyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
min[x, y, z], whole numbersyes
max[x, y, z], whole numbersyes

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

FieldTypeRequired
palettelist of block-state stringsyes
worldworld name, e.g. minecraft:overworldyes
cellsstringyes
min[x, y, z], whole numbersyes
max[x, y, z], whole numbersyes

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

FieldTypeRequired
palettelist of block-state stringsyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes
snbtstringyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
entrieslistyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
at[x, y, z], whole block coordinatesyes

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

FieldTypeRequired
worldworld name, e.g. minecraft:overworldyes
factsolid, falls, requires-tool, replaceable, propagates-skylight, suffocating or airyes
positionslistyes

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.