Nucleation
A Minecraft schematic engine in Rust — load, build, simulate, mesh, and render schematics from seven languages.
This volcano island is a JSON description — signed distance fields plus material rules. Every image on this page was built and rendered by nucleation itself, and every snippet ran for real (images · snippets + outputs).
Contents · Install · The basics · Build · Terrain · Redstone · Mesh & render · Analyze · Masked edits · Worlds & block data · Languages · Docs
Install
Kotlin/JVM, PHP, C, and C++ ship as archives on Releases — quickstarts below.
The basics
A Schematic is a named region of blocks (plus block entities, entities, and
metadata). Load one from any supported format, edit it with plain coordinates
and block strings, save it in any other:
= # any format, auto-detected
# (3, 3, 3)
# y=3: the region grows to fit
# "minecraft:glowstone"
# format from the extension
The same loop in JavaScript — the WASM build has no filesystem, so it's bytes in, bytes out:
import from "nucleation";
import from "node:fs";
const cube = ;
cube.;
;
Block-state strings with properties work anywhere a block is named —
"minecraft:lever[face=floor,facing=east]" — and every block string a
schematic can contain round-trips. Later Python snippets assume
from nucleation import * and an existing schematic s; each has a fully
runnable version with captured output in
docs/readme-snippets/.
Build: shapes, brushes, palettes
Spheres, tori, cones, pyramids, bezier ribbons — plus boolean combinators — filled by brushes that pick each block:
A gradient brush follows a shape's own parameter — around the ring of a torus, along a bezier — and snaps every color to a palette:
=
The shaded brush lights a base color by surface normal — 3D-lit forms out of flat blocks:
= # base color, light direction
And palettes turn colors into blocks. Ask for pure white → pure black in 24 steps and the engine picks the blocks itself — distinct, ordered, off-hue candidates penalized (bottom row; above it, the lightness-sorted wool, concrete, terracotta, and planks presets):
# 24 distinct blocks: white_wool ... iron_block ... deepslate_tiles ... black_concrete
Or build palettes from pure color logic over the block database — no names, just measured color values and block facts:
=
# near-neutral only
# mid-grays
= # 40+ blocks, picked by math
# everything lime-ish, nearest first: lime_concrete_powder (0.053), ...
And shapes aren't limited to the primitives — any SDF tree is a Shape,
so smooth-blended distance fields fill with every brush. Field-gradient
normals mean the shaded brush shades a blend continuously across the seam:
=
# masked fills work too
More in the guides: shapes & brushes · palettes, ramps, and pixel art.
Terrain from a JSON description
The same SDF trees that work as shapes scale up to whole terrains: sampled through declarative material rules (surface shells, depth bands, gradients, scatter) instead of a single brush. Deterministic: same JSON, same terrain, every language.
=
=
=
# → 29×18×29, 6,927 blocks
That's the minimal version; the volcano up top adds smooth-blended cones, a cylinder-cored lava crater, and noise-gated snow. Smooth booleans even animate into metaballs — recipes, node/rule schemas, and the gradient fill rules live in the SDF terrain guide.
Simulate redstone
Headless circuit simulation via MCHPRS's redpiler — and it runs in the browser, since simulation ships in the WASM build. Flip the lever, tick the world, and the lamp (and wire) light up:
import from "nucleation";
const world = ; // lever → wire → lamp
world.; // flip the lever
world.;
world.;
world.; // → true
Beyond poking blocks: a typed executor drives circuits through named, typed inputs and outputs (booleans, integers, floats, ASCII) with layout builders for buses — see the docs.
Mesh and render
Any schematic → GLB/glTF or USDZ using any vanilla-format resource pack, plus the headless GPU renderer that drew this page. The sphere-fit camera holds a rotation-stable frame — this turntable is 40 renders of the hero island:
=
= # magic b'glTF'
=
# rotation-stable framing
Analyze: diff, fingerprint, auto-stack
Structural diffs know what was added, removed, changed, and swapped — here as a ghost view, additions in green, removals in red:
= # distance 3; summary JSON with regions
# False (fingerprints are translation-invariant)
And nucleation can find the repetition in a build — the lattice of a tiling wall, a repeater bus, a pixel grid — and restamp it to a new size:
# {"mode": "1d", "vectors": [[4,0,0]], "coverage": 1.0}
= # 2 units → 6: (8,4,1) → (24,4,1)
Edit without collateral damage
Masked fills touch only what you allow: fill_only_air builds around
existing work; fill_replacing swaps listed blocks inside a shape — a
temple weathering into moss and cracks within a sphere of decay:
Worlds, versions, and the block database
Schematics round-trip through playable worlds — export a real world folder
(level.dat + region files), import any world back, bounded or streamed
chunk-by-chunk in constant memory:
=
The built-in DataConverter port migrates blocks, items, and entities across Minecraft data versions (loss reports on downgrades), and Java ↔ Bedrock translation runs on GeyserMC's mappings at full 26.2 parity.
Under it all sits a block database extracted from Mojang's own data generator and the vanilla jars — kinds, variant families, resolved tags, geometry, measured colors for all 1,196 Minecraft 26.2 blocks — which updates itself when Mojang ships a new version:
# {"kind": "minecraft:stair", "base_block": "minecraft:oak_planks",
# "tags": ["minecraft:mineable/axe", ...], "full_cube": false, ...}
# [oak_planks, oak_button, oak_fence, oak_fence_gate, oak_pressure_plate, oak_slab, ...]
One API, seven languages
Every binding is generated from one annotated-Rust source of truth
(src/bridge/) via
Diplomat — committed,
regenerated, and diffed in CI so they can never drift:
| Language | Package | Errors | Naming |
|---|---|---|---|
| Rust | nucleation crate (native API) |
Result |
snake_case |
| JavaScript | npm install nucleation |
exceptions | setBlock |
| Python | pip install nucleation |
exceptions | set_block |
| Kotlin/JVM | Release JAR (JNA, 5 platforms bundled) | kotlin.Result |
setBlock |
| PHP | Release archive (php/ + FFI) |
DiplomatError |
setBlock |
| C | Release archive (include/ + library) |
result structs | Schematic_set_block |
| C++ | Header-only over the C ABI | diplomat::result |
set_block |
What ships where:
| Channel | Surface |
|---|---|
| npm | full surface; WASM includes simulation + meshing (no GPU rendering) |
| PyPI | full surface, including simulation, meshing, rendering, scripting |
| Release archives + JAR | full surface, native, 5 platforms |
| crates.io | full surface except simulation* |
* MCHPRS isn't on crates.io — for simulation in Rust, use
nucleation = { git = "https://github.com/Schem-at/Nucleation", features = ["simulation"] }.
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"
int
Documentation & development
- Documentation index — per-language references and all feature guides (shapes & brushes, palettes, SDF terrain, scripting, block database)
docs/readme-snippets/— every snippet above with its verified output- Release notes
Also in the box: embedded Lua/JS scripting engines, pluggable storage (memory / filesystem / S3 / Redis / Postgres behind one URI), and layer-art templates (schematics from ASCII art).
CI regenerates bindings and fails on drift, exercises every built wheel and the assembled JAR before release, and smoke-tests all seven language bindings on every push.
License
MIT. See LICENSE.