Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

A TypeScript library for rendering Minecraft skins, models, blocks, entities, and worlds.
This monorepo contains the `minerender` package, demo pages, and examples.
V2 is in beta; see [ROADMAP.md](./ROADMAP.md) for progress and remaining work,
including headless Node rendering.
V2 is in beta; see [ROADMAP.md](./ROADMAP.md) for progress and remaining work.
Live examples: [beta.minerender.org](https://beta.minerender.org/).
API reference: [beta-docs.minerender.org](https://beta-docs.minerender.org/).

## Develop locally

Expand All @@ -22,6 +23,8 @@ Choose a workspace to work on:
| [packages/minerender](./packages/minerender) | Public library | `yarn build:watch` |
| [apps/web](./apps/web) | Demo and manual test pages | `yarn dev:web` |
| [apps/site](./apps/site) | V2 website with live examples and docs | `yarn dev:site` |
| [apps/embed](./apps/embed) | Scene-driven iframe embed page | `yarn dev:embed` |
| [apps/api](./apps/api) | HTTP rendering service for scene documents | `yarn build:api && yarn start:api` |
| [examples/vite](./examples/vite) | Vue/Vite example | `yarn dev:vite` |
| [examples/script-tag](./examples/script-tag) | Plain HTML example | `yarn dev:script-tag` |

Expand Down
368 changes: 295 additions & 73 deletions ROADMAP.md

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion packages/minerender/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MineRender V2

A TypeScript library for interactive Minecraft skins, models, blocks, entities, and worlds.
A TypeScript library for interactive Minecraft skins, models, blocks, entities, GUIs, and worlds.
V2 is in beta. See the [roadmap](https://github.com/InventivetalentDev/MineRender/blob/main/ROADMAP.md) for feature parity and remaining work.

Live examples and usage docs: [beta.minerender.org](https://beta.minerender.org/). API reference: [beta-docs.minerender.org](https://beta-docs.minerender.org/).
Expand Down Expand Up @@ -29,6 +29,11 @@ an injected WebGL 2 context or the optional native `gl` backend. See

Requires Node.js 22.12+ or a browser with WebGL 2, Fetch, `AbortSignal.any()`, and `AbortSignal.timeout()`.

The library prints only warnings and errors. To see debug output, call
`Logging.configure({ level: "debug" })`, or set the `minerender:log` localStorage key
in a browser or the `MINERENDER_LOG` environment variable in Node. See
[Logging](https://beta-docs.minerender.org/concepts#logging).

## Resource-pack ZIPs

Register a browser `File` or `Blob` before loading models or textures:
Expand Down Expand Up @@ -123,3 +128,7 @@ Supported object types are `skin`, `block`, `item`, `model`, `entity`, and `gui`
Positions use model units (16 per block); JSON rotations use radians.

Callers apply the saved camera settings and select the matching asset version.

`encodeSceneDocument` and `decodeSceneDocument` convert a document to and from the compact
link format used by the editor. To show a scene on another page without bundling the library,
use the [iframe embed page](https://beta-docs.minerender.org/embeds).
5 changes: 3 additions & 2 deletions packages/minerender/reference/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ export default defineConfig({
themeConfig: {
nav: [
{ text: "API reference", link: "/" },
{ text: "Behavior", link: "/concepts" },
{ text: "Concepts", link: "/concepts" },
{ text: "Browser & Node", link: "/platforms" },
{ text: "Embeds", link: "/embeds" },
{ text: version, link: "https://github.com/InventivetalentDev/MineRender/releases" }
],
sidebar: [
{
text: "Reference",
items: [
{ text: "Overview", link: "/" },
{ text: "Rendering & ownership", link: "/concepts" },
{ text: "Core concepts", link: "/concepts" },
{ text: "Browser & Node", link: "/platforms" },
{ text: "Iframe embeds", link: "/embeds" }
]
Expand Down
26 changes: 19 additions & 7 deletions packages/minerender/reference/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ Use the units expected by the API you call:

For GUI camera fitting, use [GuiObject](/api/index/classes/GuiObject)'s `bounds`. It includes item-model overhang as well as layer rectangles, in GUI coordinates.

GUI text accepts literal Unicode strings or styled text runs. [Fonts](/api/index/classes/Fonts) loads bitmap, Unihex, space, and reference providers from the selected assets and resource packs. Unihex ZIPs use vanilla glyph metrics and size overrides, with shared atlas pages allocated as glyphs are drawn. A Unihex file downloads only when text needs a character that earlier providers lack, so plain ASCII text in the default font never loads `unifont.zip`. TrueType fonts, translation keys, and right-to-left shaping remain unsupported.

`render.pixelRatio` sets drawing-buffer pixels per CSS pixel, with a default of `1`. It changes image-export resolution; layout and inspector picking use CSS pixels.

## Await initialization
Expand All @@ -34,7 +32,7 @@ With `sectionMeshing: true`, changed sections rebuild after the placement promis

## Versioned registry data

`AssetLoader.setVersion(version)` selects both vanilla assets and the registry data used for item defaults, potion colors, block properties, preview tints, fluids, dyes, legacy numeric mappings, and renamed IDs. These datasets load from `assets.mcasset.cloud/<version>/minerender-data/` when needed.
`AssetLoader.setVersion(version)` selects both vanilla assets and the registry data used for item defaults, potion colors, block properties, preview tints, face culling rules, fluids, dyes, legacy numeric mappings, and renamed IDs. These datasets load from `assets.mcasset.cloud/<version>/minerender-data/` when needed.

When the exact dataset version is missing, MineRender selects the nearest published patch in the same release line, preferring the older patch on a tie. Otherwise it uses the latest earlier published release. Releases older than the published data use the oldest available release; an unpublished snapshot rejects. Models and textures retain the requested asset version. A missing dataset or failed request rejects rather than returning an empty registry.

Expand Down Expand Up @@ -115,21 +113,33 @@ await scene.addGui([{ item: "minecraft:item/shield", context: { components: {
} } }]);
```

Bundled vanilla 1.21.11 stack-size, durability, and glint defaults apply unless overridden by supplied components. Supply any other components a selector reads. GUI item layers and scene-document item definitions take the same `context`; documents name item references by item ID. Explicit `tints` still override automatic colors. See the [AGENTS.md item notes](https://github.com/InventivetalentDev/MineRender/blob/main/AGENTS.md#gotchas) for the supported components and renderers.
The selected version's stack-size, durability, and glint defaults from [ItemDefaults](/api/index/classes/ItemDefaults) apply unless overridden by supplied components. Supply any other components a selector reads. GUI item layers and scene-document item definitions take the same `context`; documents name item references by item ID. Explicit `tints` still override automatic colors. See the [AGENTS.md item notes](https://github.com/InventivetalentDev/MineRender/blob/main/AGENTS.md#gotchas) for the supported components and renderers.

## GUI text

GUI text accepts literal Unicode strings or styled text runs. [Fonts](/api/index/classes/Fonts) loads bitmap, Unihex, space, and reference providers from the selected assets and resource packs. Unihex ZIPs use vanilla glyph metrics and size overrides, with shared atlas pages allocated as glyphs are drawn. A Unihex file downloads only when text needs a character that earlier providers lack, so plain ASCII text in the default font never loads `unifont.zip`. TrueType fonts, translation keys, and right-to-left shaping remain unsupported.

## Objects and instance references

With model instancing enabled, scene methods can return an [InstanceReference](/api/index/classes/InstanceReference) instead of a separate model object. Use the reference's transform methods to change that placement. Changing the underlying shared object's transform can affect its other instances.

Calling `removeFromScene()` or `dispose()` on an instance reference releases its slot. A released reference rejects transform access; create another placement to obtain a usable reference.

With `sectionMeshing: true`, [MineRenderWorld](/api/index/classes/MineRenderWorld) merges eligible blocks into section meshes. A merged block has no individual `BlockInfo.object`. Edit it through the world or chunk setters so geometry and neighbor culling update together.
Block model elements with `shade: false` skip directional face shading in separate, merged, and instanced models, including world section meshes. Tints, saved world light, and ambient occlusion still apply. Item previews keep directional shading because vanilla's item renderer ignores the flag. Omitted or `true` values retain directional shading; GUI items with `gui_light: "front"` disable it for the whole model.

World placement selects weighted block models from absolute block coordinates, so unloading and reloading preserves their appearance in both rendering modes. Standalone `scene.addBlock` previews remain random unless you supply `variantPosition: [x, y, z]` in block units. The position is copied at construction; moving the object does not change its selection. The pick is vanilla-identical for the same coordinates and ordered weights. Position-based selection rejects total weights above 2,147,483,647.

## World section meshes

With `sectionMeshing: true`, [MineRenderWorld](/api/index/classes/MineRenderWorld) merges the block models in each 16 × 16 × 16 section into a few meshes. This includes cutout, translucent, multipart, and animated models, plus fluid surfaces. Solid, translucent, and fluid geometry use separate atlas pages of at most `maxAtlasSize` pixels per side, 2048 by default, with one mesh per page; animated textures get their own pages. Block entities keep individual objects.

A merged block has no individual `BlockInfo.object`. Edit it through the world or chunk setters so geometry and neighbor culling update together.

Translucent blocks and water in a section mesh draw back to front. Perspective views sort them by distance from the camera and re-sort when the camera enters another block; orthographic views sort by view depth. Separate section meshes rely on Three.js sorting the meshes as whole objects, and intersecting surfaces can still blend incorrectly.

Block model elements with `shade: false` skip directional face shading in separate, merged, and instanced models, including world section meshes. Tints, saved world light, and ambient occlusion still apply. Item previews keep directional shading because vanilla's item renderer ignores the flag. Omitted or `true` values retain directional shading; GUI items with `gui_light: "front"` disable it for the whole model.
In both rendering modes, a face whose model `cullface` touches an opaque full cube is hidden. The selected version's `blockCulling` dataset adds vanilla's other rules: glass, ice, slime, and similar blocks hide faces toward the same block, mangrove roots toward the same block above or below, and connected panes or bars toward each other. Leaves keep their faces.

World placement selects weighted block models from absolute block coordinates, so unloading and reloading preserves their appearance in both rendering modes. Standalone `scene.addBlock` previews remain random unless you supply `variantPosition: [x, y, z]` in block units. The position is copied at construction; moving the object does not change its selection. The pick is vanilla-identical for the same coordinates and ordered weights. Position-based selection rejects total weights above 2,147,483,647.
`await world.setBlockVisibleAt(position, false)` hides a block without deleting its data and reveals its neighbors' faces. Replacing or removing the block resets its visibility.

## Inspecting world blocks

Expand Down Expand Up @@ -230,6 +240,8 @@ Numeric and paletted Java chunks support gzip, zlib, LZ4, and uncompressed paylo

Numeric mappings do not reconstruct states that depend on neighbors or block-entity NBT, such as paired doors or bed colors. DataVersion migration remains unsupported.

## Biomes, light, and ambient occlusion

Modern Anvil sections retain their biome palettes as 64 IDs in `section.biomes`, ordered by `x + z * 4 + y * 16`. Each sample covers 4×4×4 blocks. `placeChunk` copies these samples, including in air-only sections. Call `world.getBiomeAt(x, y, z)` with integer world block coordinates to read the saved ID, or `undefined` when biome data is absent. Block edits preserve samples; replacing or unloading the column removes its previous biome data.

World blocks use these samples for grass, foliage, dry foliage, and water colors in both rendering modes, including multiple water colors within a merged section. Biome definitions come from the selected version's `data/<namespace>/worldgen/biome/` directory, with colors sampled from resource-pack colormaps or explicit biome effects. Grass colors include dark forest and swamp modifiers; swamp colors use world block coordinates. Waterlogged blocks keep separate model and water colors. Missing biome data or definitions retain preview colors; source errors reject placement. Older numeric `Biomes` arrays and world-seed-based biome sampling remain unsupported.
Expand Down
17 changes: 10 additions & 7 deletions packages/minerender/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,25 @@ Start with the main API for the content you want to render. Related options and

| Feature | Main APIs |
| --- | --- |
| [Rendering and scenes](/api/rendering) | [Renderer](/api/index/classes/Renderer), [RendererOptions](/api/index/interfaces/RendererOptions), [MineRenderScene](/api/index/classes/MineRenderScene) |
| [Rendering and scenes](/api/rendering) | [Renderer](/api/index/classes/Renderer), [RendererOptions](/api/index/interfaces/RendererOptions), [MineRenderScene](/api/index/classes/MineRenderScene), [FlyControls](/api/index/classes/FlyControls) |
| [Player skins and capes](/api/skins) | [Skins](/api/index/classes/Skins), [SkinObject](/api/index/classes/SkinObject), [SkinObjectOptions](/api/index/interfaces/SkinObjectOptions) |
| [Blocks and item models](/api/models) | [Models](/api/index/classes/Models), [ItemModelContext](/api/index/interfaces/ItemModelContext), [BlockStates](/api/index/classes/BlockStates), [ModelObject](/api/index/classes/ModelObject), [BlockObject](/api/index/classes/BlockObject) |
| [Blocks and item models](/api/models) | [Models](/api/index/classes/Models), [ItemModelContext](/api/index/interfaces/ItemModelContext), [BlockStates](/api/index/classes/BlockStates), [ModelObject](/api/index/classes/ModelObject), [BlockObject](/api/index/classes/BlockObject), [ItemDefaults](/api/index/classes/ItemDefaults), [ItemTints](/api/index/classes/ItemTints) |
| [Entities and animation](/api/entities) | [Entities](/api/index/classes/Entities), [EntityObject](/api/index/classes/EntityObject), [EntityAnimation](/api/index/interfaces/EntityAnimation) |
| [Worlds and file formats](/api/worlds) | [MineRenderWorld](/api/index/classes/MineRenderWorld), [WorldStreamer](/api/index/classes/WorldStreamer), [AnvilWorldSource](/api/index/classes/AnvilWorldSource), [StructureParser](/api/index/classes/StructureParser), [SchematicParser](/api/index/classes/SchematicParser), [SpongeSchematicParser](/api/index/classes/SpongeSchematicParser), [LitematicaParser](/api/index/classes/LitematicaParser), [AnvilParser](/api/index/classes/AnvilParser) |
| [GUI layers, text, and layouts](/api/guis) | [GuiObject](/api/index/classes/GuiObject), [GuiLayer](/api/index/type-aliases/GuiLayer), [GuiHelper](/api/index/classes/GuiHelper), [GuiText](/api/index/type-aliases/GuiText) |
| [Assets and resource packs](/api/assets) | [AssetKey](/api/index/classes/AssetKey), [AssetLoader](/api/index/classes/AssetLoader), [HostedAssetSource](/api/index/classes/HostedAssetSource), [ArchiveAssetSource](/api/index/classes/ArchiveAssetSource) |
| Images, videos, and model exports | [Renderer](/api/index/classes/Renderer), [VideoExportOptions](/api/index/interfaces/VideoExportOptions), [SceneExporter](/api/index/classes/SceneExporter), [SceneGLTFExportOptions](/api/index/interfaces/SceneGLTFExportOptions) |
| Scene documents | [SceneDocument](/api/index/interfaces/SceneDocument), [SceneDocumentLoader](/api/index/classes/SceneDocumentLoader) |
| [GUI layers, text, and layouts](/api/guis) | [GuiObject](/api/index/classes/GuiObject), [GuiLayer](/api/index/type-aliases/GuiLayer), [GuiHelper](/api/index/classes/GuiHelper), [GuiText](/api/index/type-aliases/GuiText), [Fonts](/api/index/classes/Fonts), [layoutGuiText](/api/index/functions/layoutGuiText) |
| [Assets and resource packs](/api/assets) | [AssetKey](/api/index/classes/AssetKey), [AssetLoader](/api/index/classes/AssetLoader), [HostedAssetSource](/api/index/classes/HostedAssetSource), [ArchiveAssetSource](/api/index/classes/ArchiveAssetSource), [MineRenderData](/api/index/classes/MineRenderData), [Renames](/api/index/classes/Renames), [Biomes](/api/index/classes/Biomes) |
| [Images, videos, and model exports](/api/rendering) | [Renderer](/api/index/classes/Renderer), [VideoExportOptions](/api/index/interfaces/VideoExportOptions), [SceneExporter](/api/index/classes/SceneExporter), [SceneGLTFExportOptions](/api/index/interfaces/SceneGLTFExportOptions) |
| [Scene documents](/api/scenes) | [SceneDocument](/api/index/interfaces/SceneDocument), [SceneDocumentLoader](/api/index/classes/SceneDocumentLoader), [encodeSceneDocument](/api/index/functions/encodeSceneDocument), [decodeSceneDocument](/api/index/functions/decodeSceneDocument) |
| [Node rendering, logging, and lifecycle](/api/platforms) | [NodeRenderer](/api/index.node/classes/NodeRenderer), [RendererSurface](/api/index/interfaces/RendererSurface), [Logging](/api/index/classes/Logging), [shutdown](/api/index/functions/shutdown) |

## Shared behavior

[Core concepts](./concepts.md) explains coordinate units, asynchronous initialization, redraws, item state, world streaming, and cleanup. Read it when a change does not appear on screen or when several objects share rendering resources.
[Core concepts](./concepts.md) explains coordinate units, asynchronous initialization, versioned registry data, redraws, animation, item state, world rendering and streaming, logging, and cleanup. Read it when a change does not appear on screen or when several objects share rendering resources.

[Browser and Node.js](./platforms.md) explains package imports, native PNG rendering with `NodeRenderer`, and the capabilities each environment provides.

[Iframe embeds](./embeds.md) explains the `/embed/` page's URL parameters, scene links, and size limits.

## Reading the API

Feature groups keep classes with their options and supporting types. Use search to find an exact symbol or method name.
Expand Down
Loading
Loading