structura-render
Turn a Minecraft Structure NBT into a real photo or a 3D file — using your own game's actual textures and block shapes, not guesses.
No fake textures, no hardcoded block shapes, no bundled game files. Point it at your own Minecraft client and get pixel-accurate PNGs and USDZ out the other end.
This isn't a lookup table of ~50 common blocks with guessed shapes. The resolver walks the same blockstate → multipart/variant → model → element rotation → UV pipeline the Minecraft client itself uses, so ordinary vanilla blocks — stairs, doors, fences, plants, redstone and the rest — come from the game's data rather than per-block guesses. Vanilla's non-model renderers (chests, banners, heads, shulker boxes, conduit, bell, decorated pots, portals and fluids) share a compact textured compound-model layer.
Why it's worth using
- Data-driven where vanilla is. JSON-modelled blocks use the same blockstate/model data and PNGs as the game. Dynamic blocks use their real entity textures on compact state-aware compound geometry.
- One mesh, every output. Geometry is resolved once and shared between PNG renders and USDZ export, so what you preview is exactly what you get in 3D — nothing drifts between formats.
- Clean by design. Zero Mojang assets in this repo or its releases — can't, EULA forbids it. You always supply your own client, so there's no legal grey area to worry about.
- Version-flexible. Point it at a
.jarfrom Minecraft 1.13 through the latest release and it just works — verified end to end on both 1.21.1 and the newest 26.2. New blocks resolve automatically; no waiting on us to add support. - Light by default. Core install is just NumPy, Pillow and SciPy. PyVista/USD only get pulled in if you actually ask for hero renders or USDZ export.
- Self-updating classification. Which blocks are solid cubes (for occlusion) is computed from real model geometry, not a hand-maintained name list — it doesn't go stale as new blocks ship.
What it does
block_model.py— generic blockstate/model resolver: variants, multipart conditions, parent chains, element rotations, UV rotation and UV locking. Builds real geometry for every JSON-modelled vanilla block.textures.py— resolves#variabletexture references and samples the real PNG, including per-pixel alpha for correct occlusion (glass, leaves, iron bars).projections.py— six-view orthographic PNGs (top/bottom/N/S/E/W) with envelope/aura/terrain-pod/glass-dome mask overlays, for engineering QA rather than looks.hero.py(heroextra) — one real-textured, real-lit PyVista render of the finished structure — the kind of shot above.usdz.py(usdzextra) — a textured 3D mesh for AR Quick Look or any USDZ viewer, from the same mesh builder as the hero renderer.build_full_cube_list.py/build_opaque_blocks.py— data-derived block classification, described above.docs/block-render-audit-26.2.md— one row for every vanilla blockstate, including explicit dynamic-render limitations.legacy_input.py(legacyextra) — every entry point also accepts a legacy.schematic, sponge.schem,.litematic, or anything else amulet-core recognizes, and converts it to Structure NBT on the fly. No manual conversion step.
Quick start
No clone needed for either package, but structura-core isn't on PyPI yet,
so pip can't resolve it as a transitive dependency — install it
explicitly first, then structura-render:
export STRUCTURA_MINECRAFT_ASSETS="$HOME/Library/Application Support/minecraft/versions/1.21.1/1.21.1.jar"
pip install 'git+https://github.com/kirimba1024/structura-core.git'
pip install "structura-render[usdz] @ git+https://github.com/kirimba1024/structura-render.git"
structura-render-hero structure.nbt preview.png
Have a legacy .schematic/.schem/.litematic instead of Structure NBT?
Add the legacy extra ([usdz,legacy]) and pass it straight in — no
separate conversion step:
structura-render-hero house.schematic preview.png
Point STRUCTURA_MINECRAFT_ASSETS at a client .jar (any version from
1.13 up) or an already-extracted assets/minecraft directory. A .jar is
extracted once into $XDG_CACHE_HOME/structura-render/jar-assets
(~/.cache/... if unset), keyed by its path, size and mtime, so repeat
runs and multiple installed versions don't re-extract or collide. When the
variable is unset, the package searches parent folders and the current
directory for assets/minecraft.
This project's own datapack targets Minecraft Java 1.21.1 specifically
(structura_core.version.JAVA_VERSION); if you're previewing its
structures, match that version for a guaranteed-correct result. Anything
older than 1.13 uses a different asset layout entirely (pre-"flattening")
and isn't supported. On load, the package checks for heavy_core (added
in 1.21) and warns on stderr if it's missing, as a cheap signal that the
pointed-at client predates 1.21 — not exhaustive, just a sanity check.
Use the lighter hero extra when USDZ export isn't needed; plain
projection rendering skips PyVista and OpenUSD entirely.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file structura_render-0.1.0.tar.gz.
File metadata
- Download URL: structura_render-0.1.0.tar.gz
- Upload date:
- Size: 38.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e73dce9c78f5e2e310b72401465239e91b3ad43199fedc97c614d7bb97310e88
|
|
| MD5 |
b1e7d9e8238da5f4316985ba6cfc7446
|
|
| BLAKE2b-256 |
c6213962f4dcf66be5c5108ebfbf7e291d862717a37e5a78681b750758a1191a
|
Provenance
The following attestation bundles were made for structura_render-0.1.0.tar.gz:
Publisher:
publish.yml on kirimba1024/structura-render
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
structura_render-0.1.0.tar.gz -
Subject digest:
e73dce9c78f5e2e310b72401465239e91b3ad43199fedc97c614d7bb97310e88 - Sigstore transparency entry: 2694637358
- Sigstore integration time:
-
Permalink:
kirimba1024/structura-render@31c925f53adc987fc638bb4a01a166ed2fe3b638 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/kirimba1024
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@31c925f53adc987fc638bb4a01a166ed2fe3b638 -
Trigger Event:
release
-
Statement type:
File details
Details for the file structura_render-0.1.0-py3-none-any.whl.
File metadata
- Download URL: structura_render-0.1.0-py3-none-any.whl
- Upload date:
- Size: 41.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed7de19fd7bf80366377c0be109f2acfd7b0bc64d3a0ae8a29c2330a492a8e60
|
|
| MD5 |
2abc1fa8356348a9d3bcd36ac1d713e2
|
|
| BLAKE2b-256 |
d51283684397ddc20350a37cd6487c4891a54881bbe53c58a9e7b215b3f482cf
|
Provenance
The following attestation bundles were made for structura_render-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on kirimba1024/structura-render
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
structura_render-0.1.0-py3-none-any.whl -
Subject digest:
ed7de19fd7bf80366377c0be109f2acfd7b0bc64d3a0ae8a29c2330a492a8e60 - Sigstore transparency entry: 2694637404
- Sigstore integration time:
-
Permalink:
kirimba1024/structura-render@31c925f53adc987fc638bb4a01a166ed2fe3b638 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/kirimba1024
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@31c925f53adc987fc638bb4a01a166ed2fe3b638 -
Trigger Event:
release
-
Statement type: