Skip to main content

A high-performance Minecraft schematic parser and utility library

Project description

Nucleation for Python

PyPI

Python bindings for Nucleation, a high-performance Minecraft schematic engine. Read, edit, build, simulate, and mesh .schematic, .litematic, .nbt, and .mcstructure files — at native speed.

The core is written in Rust and compiled to a CPython extension via PyO3 (abi3-py38), so a single wheel works on every CPython 3.8+ on your platform — no Rust toolchain required to install.


Install

pip install nucleation

Pre-built wheels are published for:

  • Linux x86_64 and aarch64
  • macOS x86_64 (Intel) and arm64 (Apple Silicon)
  • Windows x86_64

If your platform isn't covered, pip will fall back to the source distribution and build locally (requires a Rust toolchain).


Quick start

from nucleation import Schematic, sign, text

# Three explicit constructors (legacy `Schematic("file.schem")` still works):
schem = Schematic.open("example.litematic")        # load from disk
fresh = Schematic.new("my_schematic")              # blank
templ = Schematic.from_template("ab\ncd")          # ASCII template

# Polished set_block: tuple coords, structured state and NBT, chainable.
schem.set_block((0, 0, 0), "minecraft:repeater",
                state={"delay": 4, "facing": "east"})
schem.set_block((0, 1, 0), "minecraft:oak_sign",
                state={"rotation": 8},
                nbt=sign([text("Hello", color="gold"), "world"]))

# Format inferred from extension.
schem.save("out.litematic")

Hot loops

For placing many blocks, prefer the batch and fast-path APIs:

# 30+ M placements/sec — one native call.
schem.set_blocks([(x, 0, 0) for x in range(1_000_000)], "minecraft:stone")

# 10+ M placements/sec — pre-resolve once, place by index.
stone = schem.prepare_block("minecraft:stone")
place = schem.place
for x, y, z in positions:
    place(x, y, z, stone)

Tile-entity helpers

from nucleation import Schematic, chest, sign, text, Item

schem = Schematic.new("loot_room")

schem.set_block((0, 0, 0), "minecraft:chest",
                state={"facing": "north"},
                nbt=chest([
                    Item("minecraft:diamond", count=64),
                    Item("minecraft:elytra"),
                ]))

schem.set_block((0, 1, 0), "minecraft:oak_sign",
                nbt=sign([text("Loot", color="gold"), "this way →"]))

For lossless, fully-typed reads/writes (64-bit NBT, item components), use the SNBT accessors: get_block_entity_snbt(x, y, z) / set_block_entity(x, y, z, id, snbt) and get_entities_snbt() / add_entity_from_snbt(snbt).

Version conversion (datafixers)

Convert block / block-entity / item / entity data between Minecraft data versions — a Rust port of PaperMC's DataConverter. Forward conversion is lossless; down-converting to an older version returns a JSON loss report so you can warn before saving. Importers capture the source data version (set it manually for versionless formats; classic .schematic1343).

import json

schem = Schematic.open("modern.litematic")
print(schem.get_source_data_version())              # e.g. 3953 (1.21)
print(Schematic.canonical_data_version())           # 4790 (in-memory target)

# Save a copy for 1.16.5 (data version 2586); schem itself is untouched.
data, loss = schem.to_litematic_for_version(2586)
report = json.loads(loss)                            # [] when lossless
for e in report:                                    # {version, kind, severity, path, detail}
    print(f"[{e['severity']}] {e['path']}: {e['detail']}")

# Or convert in place using the captured source version:
loss = schem.convert_to_version(Schematic.canonical_data_version())

Remote storage

Schematic.open and schem.save work transparently against remote backends — no extra object, no manual byte-shuffling. The same calls you use for local files take a scheme'd URI or an explicit Store:

from nucleation import Schematic, Store

# local file (unchanged)
schem = Schematic.open("build.schem")
schem.save("build.litematic")

# transparent remote: a scheme'd URI, no Store object needed
schem = Schematic.open("s3://my-bucket/builds/adder.schem")
schem.save("s3://my-bucket/out/adder.schem")
schem.save("file:///tmp/adder.litematic")   # file:// = local path

# explicit Store + key: works for ANY backend (incl. redis/postgres)
# and reuses a single connection
store = Store.open("redis://localhost:6379")
schem = Schematic.open(store, "builds/adder.schem")
schem.save(store, "out/adder.schem")

The format is inferred from the key/path extension (.schem, .litematic, .mcstructure); pass format="litematic" etc. to save to override it.

The single-string form works for path-like backends — s3://bucket/key (and file:// → local). redis:// and postgres:// single-strings raise ValueError, because their URL path is the database, leaving no slot for the key; open those with an explicit store instead: Schematic.open(Store.open(url), key).

Which backends are reachable depends on the store-* features the extension was built with. The default wheel ships mem:// + file://; for S3/Redis/Postgres rebuild it:

maturin develop --features python,store-s3,store-redis,store-pg

Raw byte store. When you want raw bytes rather than schematics — PNG renders, arbitrary artifacts — use the Store class directly (get/put/exists/delete/list/health).


Diff & Fingerprint

Canonically fingerprint a build, dedup near-duplicates, and compute a structural diff between two builds — all under a configurable equivalence ruleset chosen by preset name:

  • exact — material- and orientation-sensitive (identical blockstates only).
  • shape — occupancy only; palette and orientation ignored.
  • structural — functional shape, rotation- and material-agnostic.
  • redstone_computational (alias redstone) — redstone-logic equivalence, rotation-agnostic, cosmetic-material-agnostic.
  • redstone_survival — like redstone, but keeps survival material constraints.

diff additionally accepts opt-in overrides: per-edit cost weights (cost_add / cost_delete / cost_change / cost_swap) and a symmetry group.

from nucleation import Schematic

a = Schematic.open("a.litematic")
b = Schematic.open("b.litematic")

# 32-hex canonical hash (rotation/translation/palette-agnostic per preset).
print(a.fingerprint("structural"))

# Cheap exact-equivalence dedup, and fuzzy FFT shape distance (0.0 == same shape).
if a.is_duplicate_of(b, "structural"):
    print("duplicate build")
print("footprint distance:", a.footprint_distance(b, "structural"))

# Dims + token histogram as JSON.
print(a.signature("structural"))

# Structural diff (optionally pass cost_*/symmetry overrides).
d = a.diff(b, "redstone")
print("distance:", d.distance())
# support = fraction of the larger build's cells that aligned (confidence,
# NOT a similarity %).
print("support:", d.support())

# Each delta as its own Schematic.
d.added(); d.removed(); d.changed(); d.swapped(); d.markers()

# Lossless JSON round-trips via Diff.from_json; summary_json() is compact.
from nucleation import Diff
full = d.to_json()
restored = Diff.from_json(full)
print(d.summary_json())

The glowing-overlay GLB requires the meshing feature in your wheel:

# `after_glb` is the meshed "after" build (bytes); returns a new GLB.
glb = d.to_overlay_glb(after_glb)
with open("diff_overlay.glb", "wb") as f:
    f.write(glb)

Documentation

Full reference, including simulation, meshing, and resource-pack rendering, lives in the main repository:


Why Rust?

Nucleation's core is shared across Rust, WebAssembly/JS, Python, and C/PHP — one engine, one set of behaviour, one set of tests. The Python package you install is the same engine that powers the JS and Rust libraries; you get native throughput for free.

License

MIT. See the main repository for details.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nucleation-0.2.15.tar.gz (5.6 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

nucleation-0.2.15-cp38-abi3-win_amd64.whl (6.8 MB view details)

Uploaded CPython 3.8+Windows x86-64

nucleation-0.2.15-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.2 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

nucleation-0.2.15-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.2 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

nucleation-0.2.15-cp38-abi3-macosx_11_0_arm64.whl (5.9 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

nucleation-0.2.15-cp38-abi3-macosx_10_12_x86_64.whl (6.3 MB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file nucleation-0.2.15.tar.gz.

File metadata

  • Download URL: nucleation-0.2.15.tar.gz
  • Upload date:
  • Size: 5.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for nucleation-0.2.15.tar.gz
Algorithm Hash digest
SHA256 45e8662c9f2f2be2202c567430e9fce3df80b79db21237f406cb5695eef55f8a
MD5 ff6ac299989a77ac1739af633e4d2def
BLAKE2b-256 6491c444026c05bc145f0e151fb2b102cd80af75a5d4e5c8f1fc23035749fc44

See more details on using hashes here.

File details

Details for the file nucleation-0.2.15-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: nucleation-0.2.15-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 6.8 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for nucleation-0.2.15-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 da103651809913eba6d3f0f065a32f71e7632903077f4770af77949a451f9cc4
MD5 41837b71a5b8fc810b78bbf1f52a59b5
BLAKE2b-256 8dd38e3669974363b5982712951e6c2e5d92b33e447a84df089826c5fcd7aa55

See more details on using hashes here.

File details

Details for the file nucleation-0.2.15-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for nucleation-0.2.15-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 faf45f43c91df26c242678172bb97b7bfda5beeefca3e0e1b95bfc569ea45467
MD5 8f2a255fc826e8d7fcaa32079f00bb6c
BLAKE2b-256 bc5d945e99ca3355db70bb244146ff449442ee5a279921c5da3c8b608317b35a

See more details on using hashes here.

File details

Details for the file nucleation-0.2.15-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for nucleation-0.2.15-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 04e6c74ebade01a8fbe4d77533cd13a3aeff33c059008f3c635f11dc819d878b
MD5 48c2f03dcd3f193c072d5bf997842f5c
BLAKE2b-256 fcf0b0384250930f676de1caa6c359842bb5496798dcac220529b74d2c9abe54

See more details on using hashes here.

File details

Details for the file nucleation-0.2.15-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for nucleation-0.2.15-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 79f2fee8211f62836c28db0303fecfc1c901ec2eef5deb3e33bc3049292aa360
MD5 c7bc95fb8eca9ae5d25d7aa6bcd13010
BLAKE2b-256 674f01f8446a32c25bc35cb7747f948aad64ad806e573fab6082042db6b485b1

See more details on using hashes here.

File details

Details for the file nucleation-0.2.15-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for nucleation-0.2.15-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f6e71e2cec99824453cd4e33965ce4d52757254b56d37a7b31bba9ae87f5878c
MD5 8f7a387f7aceb2f8dcc83e4d56933bb8
BLAKE2b-256 03d55031d1a82026d6b7c4c01f4101158cfde16651fe98b8eadf0af364108049

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page