voidmc-data)voidmc-data ships every static piece of vanilla Minecraft information the
server needs at runtime — registries, block-state ids, property enums, and
collision shapes — as fully typed, compile-time data. The crate is a build
artefact: its build.rs reads JSON assets shipped in void-data/assets/ and
emits Rust source that's include!-d from src/lib.rs. There is no JSON
parsing, no HashMap allocation, and no I/O at runtime.
build.rs runs once per cargo build and writes two files into OUT_DIR:
| File | Contents |
|---|---|
registries.rs |
REGISTRIES, TAGS static slices — NBT blobs for every entry. |
blocks.rs |
vXX_Y_Z::{props, blocks, state, shapes} modules per version. |
src/lib.rs includes both via include!. The compiler sees them as ordinary
Rust source — every constant becomes a const, every match becomes a const fn, no static initialisers run.
Registry entries (biomes, dimensions, painting variants, damage types, etc.)
are converted from JSON to NBT at build time and stored as raw byte arrays.
At runtime they're embedded via include_bytes!, so a registry lookup is a
slice-into-static-memory operation; the NBT is parsed lazily on first access
and cached behind a OnceLock.
The high-level RegistryDataStore API on the server side rebuilds these into
RegistryEntry values during configuration. See
Registry System for the runtime API; the
data shipped here is what default_registry_data() returns.
Everything below lives under voidmc_data::v26_1_2::*. New supported
versions get their own sibling module (v1_21_9::*, etc.).
blocks — Default state idsOne pub const per block — the value is the default block-state id for that
block in the targeted protocol version.
Use these whenever you need a block id and don't care about properties (spawn world generation, hotbar palette defaults, world fill commands, etc.).
props — Deduplicated property enumsVanilla blocks share a small set of properties — facing, half, axis,
shape, … — but the value sets differ between blocks (a piston's facing
has 6 values, a stair's only 4). The build script collects every distinct
(property name, value set) pair across all blocks and emits one enum
variant per unique set.
Naming rules:
Hinge, Tilt, Orientation).Facing4, Facing5, Facing6; Axis2, Axis3).Half2Top vs Half2Upper,
Type3Top vs Type3Single).Boolean-valued properties (e.g. waterlogged, lit, powered) are emitted
as plain bool fields — no enum is generated for them. Numeric ranges
(age, level, distance) become u8.
Each enum is #[repr(u8)], Copy, and exposes a from_index(u32) -> Option<Self> const fn.
state — Typed structs per stateful blockEvery block with at least one property gets a struct in
voidmc_data::v26_1_2::state. Each struct exposes:
MIN_STATE_ID, MAX_STATE_ID, DEFAULT_STATE_ID — const i32.DEFAULT: Self — vanilla default.to_state_id(self) -> i32 — encode to the global block-state id.from_state_id(i32) -> Option<Self> — decode, returning None for ids
outside the block's range.All four are const fn, so any usage is a compile-time computation when the
inputs are known.
The state-id encoding mirrors vanilla's lexicographic property iteration:
properties are listed in the same order Mojang reports them, and the
right-most property changes fastest. The per-property strides are computed
at codegen time and inlined into to_state_id.
shapes — Collision boxesshapes::for_state(state_id) -> &'static [Aabb] returns the axis-aligned
boxes (block-local, in [0,1]³) that make up a state's collision shape.
Distinct shape sets are deduplicated; consecutive states sharing a shape are
collapsed into single match arms. Unknown ids fall back to FULL_CUBE.
Shape data currently comes from prismarine 1.21.9 (see Asset Workflow
below). 26.1.2 blocks not present in 1.21.9 fall through to FULL_CUBE;
this is acceptable as a beta default but should be revisited once
prismarine ships its own 26.1.2 dataset.
Assets live under void-data/assets/<version>/ and are committed to the
repo. Building the crate never touches the network — the build script
reads files purely from disk. The refresh loop is:
What extract.sh does:
net.minecraft.data.Main --all to produce both
generated/data/minecraft/... (registries, tags) and
generated/reports/blocks.json (block-state palette).assets/<version>/.blocks.json straight from the report.PRISMARINE_REF
(default: master, override per-call) and copies
data/pc/$PRISMARINE_SHAPE_VERSION/blockCollisionShapes.json into the
asset directory.PROVENANCE.txt with timestamps, the jar URL, the prismarine
commit hash, and the shape-source version — this file is committed
alongside the JSONs so future maintainers can audit how the data was
produced.After extraction, cargo build -p voidmc-data regenerates everything from
the committed JSONs and the build is fully reproducible.
The branch pc_26_1_2 on PrismarineJS/minecraft-data only ships
protocol.json + version.json. Until block data lands there, override the
shape source explicitly:
The current assets/26.1.2/PROVENANCE.txt records this pairing.
extract.sh <new-version> <paper-jar-url> — assets land under
assets/<new-version>/.VERSIONS list at the top of
void-data/build.rs.Version enum in src/lib.rs and any version
helpers (Version::id()).cargo build -p voidmc-data — OUT_DIR/blocks.rs will gain a
vNEW::{...} module. No version-specific Rust needs to be hand-written.Copy and const-constructible.to_state_id / from_state_id / for_state are const fn.#[allow(clippy::identity_op, clippy::erasing_op, clippy::eq_op, dead_code)] — codegen frequently produces * 1 and
* 0 factors for single-value strides; tagging the module silences these
benign lints without poisoning user code.rustc compiles it cleanly in a single pass.&'static [u8] per entry; NBT parsed lazily into a
cached &'static Nbt on first access.const i32.imul / idiv ops per property.match jump and a &'static [Aabb] return.There is no global initialisation, no thread-local, and no allocation. The crate compiles into a few KB of code paths that only do arithmetic and table lookups.