Nucleation
Nucleation is a high-performance Minecraft schematic engine written in Rust, with generated bindings for C, C++, JavaScript/TypeScript (WASM), Kotlin/JVM, Python, and PHP.
What it does
- Schematic formats: read and write
.litematic, Sponge.schem, WorldEdit.schematic, Bedrock.mcstructure, structure.nbt, and a fast binary snapshot format (.nusn), with format auto-detection. - World import and export: parse whole worlds (Anvil
.mcaregion files, zipped or on-disk world folders, optionally bounded to a coordinate box) into a schematic, and export schematics back out as playable worlds. A streaming API processes worlds chunk by chunk in constant memory. - Cross-version conversion: convert block, block-entity, item, and entity data between Minecraft data versions (a Rust port of PaperMC's DataConverter), with loss reports on lossy down-converts.
- Schematic building: a template system for building schematics from ASCII or Unicode layer art, a procedural building tool (spheres, cuboids, cylinders, bezier curves, and more, filled by solid, gradient, or shaded brushes), and SDF-based shape and terrain generation.
- Redstone simulation: tick circuits headlessly via MCHPRS, inject and read signals at arbitrary positions, and drive circuits through a typed executor with named, typed inputs and outputs (booleans, integers, floats, ASCII).
- Meshing and rendering: turn schematics into GLB/glTF or USDZ meshes using any resource pack, and render PNG previews on the GPU, headlessly.
- Diffing and fingerprinting: structural diffs between schematics (added, removed, changed, swapped views), translation-invariant fingerprints, signatures, and duplicate detection.
- Auto-stack: detect the repeating lattice in a build and re-stamp it to a new size, for example a 4-bit adder to 8-bit, or a 32x32 screen to 64x64.
- Storage: a pluggable byte store (in-memory, filesystem, and S3, Redis, or Postgres behind feature flags) for moving schematics and renders around with a single URI.
- Embedded scripting: generate schematics from Lua or JavaScript scripts.
- Block database: a vendored copy of blockpedia (
nucleation::blockpedia) — Minecraft block facts with texture-derived colors, palette and gradient generation, block-state queries and transforms, and Java-Bedrock blockstate and block-entity translation via Geyser mappings.
One API, seven languages
Since v0.3.0 every language binding is generated from a single annotated-Rust source of truth
(src/bridge/) using Diplomat. The bindings are
committed under bindings/, regenerated and diffed in CI so they can never go stale, and every
language exposes the same types and methods with per-language casing and idioms:
| Language | Package | Errors | Naming |
|---|---|---|---|
| Rust | nucleation crate (native API) |
Result |
snake_case |
| C | Release archive (include/ + library) |
result structs | Schematic_set_block |
| C++ | Release archive (header-only over C ABI) | diplomat::result |
set_block |
| JavaScript | npm install nucleation |
exceptions | setBlock |
| Kotlin/JVM | Release JAR (JNA) | kotlin.Result |
setBlock |
| Python | pip install nucleation |
exceptions | set_block |
| PHP | Release archive (php/ + FFI) |
DiplomatError |
setBlock |
Installation
# Rust
# JavaScript / TypeScript (Node >= 18 or a bundler)
# Python (CPython 3.12+)
For C, C++, Kotlin, and PHP, download the platform archive or JAR from Releases, or build locally:
What ships in the published packages
Published artifacts (npm, PyPI, release archives, JAR) contain the core feature set: schematics, formats, world import/export and streaming, builder, building tool, definition regions, diff/fingerprint, autostack, NBT helpers, SDF, and the in-memory/filesystem store.
Meshing, rendering, simulation, and scripting are compiled in when you build the native library
yourself with --features bridge-full (or any subset, for example --features bridge,simulation).
Simulation and meshing also work on WASM. See the per-language docs for details.
Quick start
Rust
use UniversalSchematic;
JavaScript
import from "nucleation";
const schematic = ;
schematic.;
console.log; // "minecraft:stone"
// Serialize to litematic bytes (base64 across the WASM boundary)
const bytes = Uint8Array.;
const loaded = ;
Python
=
# "minecraft:stone"
=
Kotlin
import at.schem.nucleation.*
val schematic = Schematic.create("demo")
schematic.setBlock(1, 2, 3, "minecraft:stone").getOrThrow()
println(schematic.getBlockName(1, 2, 3).getOrThrow()) // "minecraft:stone"
PHP
C
int
Documentation
Full documentation lives in docs/:
- Documentation index
- Per-language references: Rust, JavaScript, Python, Kotlin, PHP, C, C++
- Feature guides (concepts, data models, and JSON schemas shared by all bindings)
Development
# Regenerate the committed bindings from src/bridge/ (requires the diplomat-tool fork)
# End-to-end smoke tests for the generated bindings
CI regenerates the bindings and fails on any diff, checks coverage of the full pre-0.3.0 FFI surface, and runs the smoke tests on every push.
Minecraft block data
The block database (formerly the standalone blockpedia crate) lives in-tree at
src/blockpedia/. Its data ships as gzipped snapshots in data/blockpedia/ — currently pinned
to Minecraft 26.2 (Java block states from Mojang's own data generator, official block
semantics — kind/base-block/tags/full-cube geometry, Bedrock block states, Geyser blockstate
mappings, and a color cache derived from the vanilla texture pack) — and build.rs bakes them
into static PHF tables at compile time. Normal builds never touch the network.
To refresh the Java data for a new Minecraft version (needs a JRE new enough for the server
jar on PATH; MC 26.x wants Java 25+):
# 1. Vanilla report converter: downloads the server jar, runs Mojang's data
# generator (--reports), and rebuilds prismarinejs_blocks.json.gz — the
# report is authoritative for the block list, properties and state ids;
# enrichment fields (transparency, hardness, light, ...) carry forward
# from the previous snapshot, and blocks new in the version are enriched
# from an analogue block or a model-shape heuristic over the client jar
# (the run prints the added/removed diff and every derived fact).
# Also rebuilds block_semantics.json.gz from official data only:
# - kind + base block: the report's definition.type / definition.base_state
# (stairs), plus a model-texture linkage for the other shape variants
# (oak_slab renders with block/oak_planks, owned by oak_planks)
# - tags: every data/minecraft/tags/block/** tag from the server jar's
# inner (bundler) jar, nested #tag refs resolved
# - full_cube: blockstate models root in a cube-family template or carry
# a full 16x16x16 element
# These drive BlockFacts::{kind, base_block, has_tag, is_full_cube},
# blocks_by_tag/variants_of, and the BlockFilter/only_solid classifiers
# (which no longer guess from name substrings).
# 2. Texture colors: downloads the client jar, extracts block textures,
# regenerates color_cache.json.gz (alpha-weighted averages + biome tints).
Both tools take the version as an optional trailing arg (-- 26.2) and default to the
manifest's latest release, so a routine bump needs no code edits. A normal cargo build
afterwards bakes the new tables in.
The PrismarineJS blocks.json schema is kept as the on-disk format (PrismarineJS itself has
no 26.x data). tests/blockpedia_data_refresh.rs guards data currency.
Java ↔ Bedrock mappings
-
geyser_mappings.json.gz— regenerated from GeyserMC/mappings (blocks.nbt@efe0f2c, "Mappings for Minecraft Java 26.2"). GeyserMC retired the oldmappings-generatorJSON dumps; the canonical data is now gzipped NBT: abedrock_mappingslist with one compound per Java blockstate in runtime state-id order (java side implicit by index;bedrock_identifierabsent ⇒ same name as Java,stateabsent ⇒ bedrock default state).refresh-bedrock-mappingsconverts that back into the JSON schemabuild.rsconsumes, reconstructing the java side fromprismarinejs_blocks.json.gz(state-id enumeration validated 32,366/32,366 against the vanilla 26.2 report). All 32,366 Java 26.2 states are mapped (was 29,671 at the 1.21.x pin; all carried-over entries identical, +2,695 gained, none lost), so the identity fallback for unmapped blocks is currently unused: -
bedrock_block_states.json.gz— PrismarineJSdata/bedrock/1.26.30/blockStates.jsongzipped verbatim (content-identical to the previous snapshot; the per-stateversionfield1.21.60.33is Bedrock's state-format version, which hasn't bumped since — the palette content is current and includes the 26.x cinnabar/sulfur blocks). Everybedrock_identifieremitted by the mappings exists in this palette.
License
MIT. See LICENSE.