diff --git a/README.md b/README.md index d4eb0dcf..2dd2eafd 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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` | diff --git a/ROADMAP.md b/ROADMAP.md index 786037df..4a936973 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -16,116 +16,338 @@ V1 `master`, tags, bundles, and website URLs must remain available. V2 targets ` ## Feature-parity matrix (V1 → V2) -| Feature | V1 | V2 today | Priority | -|---|---|---|---| -| Build & dev environment | webpack 4 per-feature IIFE bundles, works | Yarn 4 and tsup | complete | -| Packaging / npm hygiene | script-tag CDN | Browser/Node conditional exports, declarations, and a package files whitelist | complete | -| Clean import (no side effects) | window globals, telemetry beacon | Lazy platform initialization and Ticker; idle caches and queues let Node exit | complete | -| Browser/Node dual-target | browser-only by design | Separate entries register platform providers; Node canvas stays optional for browsers | complete | -| Renderer core | continuous loop, SSAA, fps limit, dispose() | Dirty-flag loop, start/stop, disposal, and resize invalidation; frame limiting; sRGB color handling | complete | -| Camera controls | built-in OrbitControls via `options.controls` | Opt-in renderer-owned OrbitControls or creative-style `FlyControls` (`controls.mode`), runtime switching, wheel speed, touch joystick, redraw, and disposal | complete | -| Skins — classic 64×64 | full, named toggleable parts | Vanilla dimensions, UVs, pivots, base opacity, and translucent overlays; model detection and named parts | complete | -| Skins — slim + legacy 64×32 | auto-detected, dedicated UVs | Classic/slim UVs and detection; legacy skins normalized with mirrored limbs and transparency rules | complete | -| Capes (vanilla/OptiFine/LabyMod) | full, 3 layouts, capes.dev | All three static layouts and capes.dev lookup; animated capes remain | medium | -| Block/item model rendering | full incl. tint, display transforms | UV locking, explicit per-index tints, automatic block preview colors, display poses, nested composite items, chest/bed/mob-head/player-head/shulker-box previews, patterned banners/shields, trident/conduit previews, decorated pots, copper-golem statue poses, and component-driven glint on ordinary/composite items, shields, and tridents, including vanilla item glint defaults, compass/clock projected glint, potion effect-derived colors, and vanilla durability/stack-size defaults | high | -| Blockstate resolution | variants + weighted random + multipart AND/OR | Default states and model initialization awaited; multipart AND/OR and weighted alternatives supported; placement preserves rotations | complete | -| Animated textures | frametime honored | Frame grids, sequences, durations, RGBA interpolation, and stationary-camera redraw | complete | -| Entity rendering | 76 hosted models, mirror, inheritance | Versioned dataset, nested parts, mirrored UVs, conditional passes, render-mode materials, scrolling effects, and dataset transforms; runtime gameplay state selection remains | high | -| GUI / inventory / recipes | full GuiRender + Positions + recipe() | Texture/item layers with count labels and durability bars, container presets, recipes, sprite scaling, styled bitmap and Unihex text, supplied-text tooltips, boss bars, and book layouts; TrueType fonts, translations, and right-to-left shaping remain | medium | -| Structure (.nbt) loading | works via ModelConverter | Bounded placement, signed coordinates, slot cleanup, DataVersion and entity NBT preservation; supported block entities render, with opt-in saved mobs and selected appearance fields | high | -| Legacy .schematic | full incl. AddBlocks nibbles | Numeric block IDs, metadata, AddBlocks, custom mappings, and block/entity NBT parsed; strict by default, with opt-in lenient fallback | complete | -| Combined multi-renderer scene | CombinedRender wrapper | Superseded by design (one scene hosts all types) — **at parity** | — | -| Screenshots, video & 3D export | toImage(trim,mime), toObj/toGLTF/toPLY | Fresh captures with trim/MIME/quality, real-time browser video recording, static OBJ/PLY, and textured browser glTF/GLB snapshots | complete | -| Asset loading & resource packs | swappable assetRoot, fallback | Ordered source selection, ZIP pack overlays and filters, failure-evicting caches, and contextual errors; defaults to 1.21.11, ZIPs browser-only | high | -| Per-frame animation API | `Render` CustomEvents | `onFrame` subscriptions with time/delta, FPS limiting, pause/resume, and disposal | complete | -| Entity keyframe animations | none | Native and sampled procedural clips with synchronized, layer-specific playback, additive clip weights, live weight changes, and caller-driven time; runtime state selection, visibility, and animated renderer transforms remain | partial | -| Scene documents & editor | n/a | Versioned scene JSON with item state, atomic document loading, and a browser editor with transforms, GUI layouts, import, and image, video, and model export | complete | -| Embeds & website | minerender.org + iframe embeds | V2 website, hosted playgrounds and scene editor, consumer examples, API reference, and scene-driven iframe embeds with editor copy support; embed Worker deployment remains | low | -| **Large-scale worlds (V2 goal)** | n/a | Paletted signed chunks, opt-in section meshes for static models of any shape built in a browser worker, grouped bulk placement, neighbor face culling, block visibility, camera-driven chunk streaming with bounded retention, and opt-in saved sky/block lighting, corner ambient occlusion, and biome blending; partial-shape ambient occlusion, light propagation, and LOD remain | high | -| **Anvil .mca / world formats (V2 goal)** | n/a | Numeric and paletted Java regions, Sponge v2/v3 schematics with local palettes, offsets, and preserved NBT, Litematica v5–7 named regions with relative placement, lazy multi-region world sources, separate entity regions, DataVersion, gzip/zlib/LZ4/uncompressed payloads, external `.mcc` payloads, and a local world-folder demo with dimension selection; no data fixing | high | -| **Node headless rendering (V2 goal)** | faked externally by MineRenderServer | DOM-free renderer with injected WebGL 2, native `NodeRenderer.create()`, PNG buffers, and a scene-document HTTP API | complete | -| Bedrock geometry (V2 ambition) | n/a | Type declarations only | low | -| Instancing architecture | merged Geometry + instanced-mesh fork | Reusable slots, growing buffers, explicit mesh ownership, and per-placement references; shared-owner transforms affect all live instances, blockstate-level deduplication remains | high | +Details and remaining work for each row are in the [continuation plan](#continuation-plan-ordered). + +| Feature | V1 | V2 | Status | Priority | +|---|---|---|---|---| +| Build & dev environment | webpack 4 per-feature IIFE bundles | Yarn 4 and tsup | complete | — | +| Packaging / npm hygiene | script-tag CDN | Browser/Node conditional exports, declarations, files whitelist | complete | — | +| Clean import (no side effects) | window globals, telemetry beacon | Lazy platform setup and Ticker; idle Node processes exit | complete | — | +| Browser/Node dual-target | browser-only | Per-platform entries; Node canvas optional for browsers | complete | — | +| Renderer core | continuous loop, SSAA, fps limit, dispose() | Dirty-flag loop, frame limit, disposal, sRGB output | complete | — | +| Camera controls | OrbitControls via `options.controls` | Opt-in OrbitControls or `FlyControls` (`controls.mode`) | complete | — | +| Skins — classic 64×64 | named toggleable parts | Vanilla dimensions, UVs, pivots, overlays, named parts | complete | — | +| Skins — slim + legacy 64×32 | auto-detected | Slim/legacy UVs and detection; legacy skins normalized | complete | — | +| Capes (vanilla/OptiFine/LabyMod) | 3 layouts, capes.dev | All three static layouts and capes.dev lookup | partial | medium | +| Block/item model rendering | tints, display transforms | Tints, display poses, composite and special items, glint | partial | high | +| Blockstate resolution | variants, weighted, multipart | Variants, weighted alternatives, multipart AND/OR | complete | — | +| Animated textures | frametime | Frame grids, sequences, durations, interpolation | complete | — | +| Entity rendering | 76 hosted models, mirror | Versioned dataset, passes, render modes, transforms | partial | high | +| Entity keyframe animations | none | Native and sampled clips, layer playback, weights | partial | high | +| GUI / inventory / recipes | GuiRender, Positions, recipe() | Layers, containers, recipes, bitmap/Unihex text, layouts | partial | medium | +| Structure (.nbt) loading | via ModelConverter | Bounded placement, block entities, opt-in saved mobs | partial | high | +| Legacy .schematic | incl. AddBlocks nibbles | IDs, metadata, AddBlocks, custom mappings, lenient mode | complete | — | +| Combined multi-renderer scene | CombinedRender wrapper | Superseded: one scene hosts all types | complete | — | +| Screenshots, video & 3D export | toImage, toObj/toGLTF/toPLY | Trimmed captures, browser video, OBJ/PLY, textured glTF | complete | — | +| Asset loading & resource packs | swappable assetRoot | Ordered sources, ZIP overlays, version selection | partial | high | +| Per-frame animation API | `Render` CustomEvents | `onFrame` with time/delta, FPS limit, pause | complete | — | +| Scene documents & editor | n/a | Versioned scene JSON and a browser editor | complete | — | +| Embeds & website | minerender.org, iframe embeds | V2 site, playgrounds, editor, API reference, embeds | complete | — | +| **Large-scale worlds (V2 goal)** | n/a | Paletted chunks, section meshes, streaming, light, AO | partial | high | +| **Anvil .mca / world formats (V2 goal)** | n/a | Anvil regions, Sponge, Litematica, entity regions; ID renames only | partial | high | +| **Node headless rendering (V2 goal)** | MineRenderServer | `NodeRenderer`, PNG buffers, scene-document HTTP API | complete | — | +| Bedrock geometry (V2 ambition) | n/a | Type declarations only | not started | low | +| Instancing architecture | merged Geometry, instancing fork | Reusable slots, growing buffers, per-placement refs | partial | high | ## Continuation plan (ordered) ### 1–4. Build and platform support -- ~~Build tooling, package exports, import-time initialization, and browser/Node providers.~~ -- ~~Update cache and queue dependencies so idle imports let Node exit.~~ +Done: + +- Build tooling, package exports, import-time initialization, and browser/Node providers. +- Update cache and queue dependencies so idle imports let Node exit. +- Build the browser ESM output per module, and load optional object types, exporters, and storage on first use. ### 5. Renderer core -- ~~Fix start/stop, disposal, resize invalidation, and scene listeners.~~ -- ~~Integrate opt-in OrbitControls.~~ -- ~~Implement frame limiting.~~ -- ~~Align Three types and color spaces; fix direct/composer brightness.~~ -- ~~Compile the shaded model material for both instanced and non-instanced meshes.~~ +Done: + +- Fix start/stop, disposal, resize invalidation, and scene listeners. +- Integrate opt-in OrbitControls. +- Implement frame limiting. +- Align Three types and color spaces; fix direct/composer brightness. +- Compile the shaded model material for both instanced and non-instanced meshes. ### 6. Asset pipeline -- ~~Resolve sources in priority order and return the first defined asset.~~ -- ~~Initialize node-persist before use.~~ -- ~~Decode fetched image bytes without refetching them; reject invalid images and allow retry.~~ -- ~~Skip nullish persistent writes and evict missing or rejected async cache loads.~~ -- ~~Bound request concurrency, retries, cancellation, timeouts, and shutdown.~~ -- ~~Propagate hosted/archive and model initialization errors with source context.~~ -- ~~Default to 1.21.11 with static item definitions, animal texture paths, structure directory aliases, and versioned cache keys.~~ -- ~~Add an asset-version selection API.~~ -- ~~Load versioned registry and rendering data from `minerender-data`, replacing bundled runtime datasets; select a nearby published release when the exact registry version is unavailable.~~ -- ~~Read ZIP pack metadata, select version-applicable overlays, and filter lower-priority resources.~~ -- ~~Support chest, bed, mob-head, and shulker-box special item models, including shulker textures, openness, and six orientations.~~ ~~Render banner and shield items with supplied base colors and ordered banner patterns.~~ ~~Render held and throwing trident poses and static conduit items.~~ ~~Render decorated-pot items with four supplied sherd sides.~~ ~~Render player-head items from supplied profiles, including skin lookup, texture properties, resource-pack texture overrides, and default skins.~~ ~~Render copper-golem statue variants and poses from supplied block-state components.~~ ~~Resolve static/default item tint sources.~~ ~~Render nested composite items with each child's textures, display pose, lighting, and tints.~~ ~~Evaluate item properties from supplied data components, stack counts, display contexts, and overrides, with shared playground controls and bundle, bow, crossbow, and indexed custom-model-data presets.~~ ~~Resolve supplied dye, map, firework, potion custom-color, and indexed custom-model-data tints, including GUI item contexts and editable playground presets.~~ ~~Render animated enchantment glint on ordinary and composite items from supplied enchantments and explicit overrides, with playground controls.~~ ~~Render shield and held/throwing trident glint with the shared component controls.~~ ~~Apply vanilla 1.21.11 glint defaults by item ID, retaining explicit overrides and resource-pack model replacements.~~ ~~Render projected glint on compasses, recovery compasses, and clocks; derive normal-compass glint from supplied lodestone tracking and provide direction/time presets.~~ ~~Resolve potion and tipped-arrow colors from supplied potion IDs and visible custom effects using vanilla 1.21.11 data, with a playground potion selector and color overrides.~~ ~~Apply vanilla durability and stack-size defaults to model selectors and GUI bars, with editable playground overrides.~~ Composite items and items with glint do not use instancing. Other special-renderer glint, other special renderers, team colors, other item registry defaults, and automatic calculation of world/player state remain. -- ~~Fix `WrappedImage` frame math.~~ +Done: + +- Resolve sources in priority order and return the first defined asset. +- Initialize node-persist before use. +- Decode fetched image bytes without refetching them; reject invalid images and allow retry. +- Skip nullish persistent writes and evict missing or rejected async cache loads. +- Bound request concurrency, retries, cancellation, timeouts, and shutdown. +- Propagate hosted/archive and model initialization errors with source context. +- Default to 1.21.11 with static item definitions, animal texture paths, structure directory aliases, and versioned cache keys. +- Add an asset-version selection API. +- Load versioned registry and rendering data from `minerender-data`, replacing bundled runtime datasets. + The nearest published release is used when the exact registry version is unavailable. +- Replace renamed block, item, and saved-entity IDs through the optional versioned `renames` dataset. +- Read ZIP pack metadata, select version-applicable overlays, and filter lower-priority resources. +- Fix `WrappedImage` frame math. + +Done (item rendering): + +- Chest, bed, mob-head, and shulker-box items, including shulker textures, openness, and six orientations. +- Banner and shield items with supplied base colors and ordered banner patterns. +- Held and throwing trident poses, static conduits, and decorated pots with four supplied sherd sides. +- Player-head items from supplied profiles: skin lookup, texture properties, resource-pack texture overrides, and default skins. +- Copper-golem statue variants and poses from supplied block-state components. +- Nested composite items with each child's textures, display pose, lighting, and tints. +- Item properties from supplied data components, stack counts, display contexts, and overrides. + Shared playground controls include bundle, bow, crossbow, and indexed custom-model-data presets. +- Static and default item tint sources. +- Supplied dye, map, firework, potion custom-color, and indexed custom-model-data tints, including GUI item contexts. +- Potion and tipped-arrow colors from supplied potion IDs and visible custom effects, with a playground potion selector. +- Animated enchantment glint on ordinary and composite items, shields, and held or throwing tridents, with explicit overrides. +- Vanilla glint defaults by item ID, retaining explicit overrides and resource-pack model replacements. +- Projected glint on compasses, recovery compasses, and clocks; normal-compass glint from supplied lodestone tracking. +- Vanilla durability and stack-size defaults in model selectors and GUI bars, with editable playground overrides. + +Composite items and items with glint do not use instancing. + +Remaining: + +- Glint on other special renderers. +- Other special renderers. +- Team colors (only declared defaults are used). +- Other item registry defaults. +- Automatic calculation of world and player state. +- ZIP resource packs outside the browser (archive sources are browser-only). ### 7. Model/blockstate correctness — complete -Small, high-impact: (1) ~~`Axis.X = "X"` → lowercase (x-rotations silently no-op)~~; (2) ~~await `BlockStates.getDefaultState`~~; (3) ~~texPosition-undefined crash~~; (4) ~~ModelMerger: child `elements` must override, not concat~~; (5) ~~remove the 150ms rotation workaround and preserve multipart rotations during placement~~; (6) ~~multipart AND/OR + `apply` arrays + weighted variants~~; (7) ~~`AssetKey.parse` extension fallback + broken `isAssetKey`~~. Then ~~tintindex with explicit colors~~, ~~automatic block preview colors~~, ~~uvlock~~, ~~display transforms~~. + +Done (small, high-impact fixes): + +- `Axis.X = "X"` → lowercase (x-rotations silently no-op). +- Await `BlockStates.getDefaultState`. +- Fix the texPosition-undefined crash. +- `ModelMerger`: child `elements` override the parent's instead of concatenating. +- Remove the 150ms rotation workaround and preserve multipart rotations during placement. +- Multipart AND/OR, `apply` arrays, and weighted variants. +- `AssetKey.parse` extension fallback and the broken `isAssetKey`. + +Done (follow-ups): + +- `tintindex` with explicit colors. +- Automatic block preview colors. +- `uvlock`. +- Display transforms. +- Honor element `shade: false` in block models and world sections; item previews keep directional shading. ### 8. Skins and capes — medium -~~Correct slim arm/sleeve UVs and preserve named parts, poses, visibility, and shared resources when switching classic/slim.~~ ~~Add 64×32 legacy layout and slim/legacy auto-detection.~~ ~~Match vanilla base opacity, overlay blending, dimensions, UVs, and joint pivots.~~ Consider sharing geometry construction with `EntityObject`. ~~Add vanilla cape meshes wired to the existing `Skins.ts` resolvers.~~ ~~Add OptiFine/LabyMod layouts and capes.dev lookup.~~ Animated capes remain. + +Done: + +- Correct slim arm/sleeve UVs; preserve named parts, poses, visibility, and shared resources when switching classic/slim. +- Add the 64×32 legacy layout and slim/legacy auto-detection. +- Match vanilla base opacity, overlay blending, dimensions, UVs, and joint pivots. +- Add vanilla cape meshes wired to the existing `Skins.ts` resolvers. +- Add OptiFine/LabyMod layouts and capes.dev lookup. + +Remaining: + +- Animated capes. +- Consider sharing geometry construction with `EntityObject`. ### 9. Entity rendering completion — high -~~Recurse `ModelPart.children`.~~ ~~Implement `mirror`.~~ ~~Verify the face UVs and pivot translation.~~ ~~Compose selected entity layers with separate textures and named groups (e.g. sheep body and wool).~~ ~~Support dataset render passes, emissive and scrolling materials, tint overrides, and renderer-specific root transforms.~~ ~~Render supported block entities during block placement.~~ -Default textures and root transforms come from the versioned entity dataset; callers can override textures and select conditional passes. `flip: false` explicitly keeps raw model space rather than applying the dataset transform. +Done: + +- Recurse `ModelPart.children`. +- Implement `mirror`. +- Verify the face UVs and pivot translation. +- Compose selected entity layers with separate textures and named groups (e.g. sheep body and wool). +- Support dataset render passes, emissive and scrolling materials, tint overrides, and renderer-specific root transforms. +- Render supported block entities during block placement. +- Play native and sampled procedural clips with synchronized, layer-specific playback. +- Blend clips within a layer with explicit weights, and update weights without restarting playback. +- Store clip blends in scene documents and edit them in the scene editor. +- Publish the `1.21.11` entity dataset with the procedural clips from + [minecraft-entity-models #7](https://github.com/InventivetalentDev/minecraft-entity-models/pull/7). +- Load entity geometry, lists, animations, and the block-entity index from the nearest published dataset version. + Textures keep the requested version. + +Default textures and root transforms come from the versioned entity dataset. Callers can override textures and select conditional passes. +`flip: false` explicitly keeps raw model space rather than applying the dataset transform. -~~Play native and sampled procedural clips with synchronized, layer-specific playback.~~ ~~Blend clips within a layer with explicit weights and update weights without restarting playback.~~ Runtime gameplay state selection, visibility changes, and animated renderer transforms remain. +Remaining: -Regenerate and publish the `1.21.11` entity dataset with the procedural clips from [minecraft-entity-models #7](https://github.com/InventivetalentDev/minecraft-entity-models/pull/7), then verify hosted clips through `Entities.getAnimations`. As checked on 2026-10-09, the published branch predates that merge and contains only 17 native animation files, with no `animations/minecraft/chest.json`. +- Runtime gameplay state selection, visibility changes, and animated renderer transforms. ### 10. Instance lifecycle overhaul — high (prerequisite for worlds) -~~Limit `InstancedMesh.count` to allocated slots~~; ~~add a free-list so removal reclaims slots~~; ~~grow capacity on demand instead of silent out-of-bounds writes~~; ~~provide per-placement transforms through `InstanceReference`s~~; ~~replace the `children[0]`-is-the-InstancedMesh assumption with a stored reference~~. Shared-owner transforms still affect all live instances; changing that API remains separate work. Extend dedup beyond `assetType === "models"` to blockstate level. + +Done: + +- Limit `InstancedMesh.count` to allocated slots. +- Add a free-list so removal reclaims slots. +- Grow capacity on demand instead of silent out-of-bounds writes. +- Provide per-placement transforms through `InstanceReference`s. +- Replace the `children[0]`-is-the-InstancedMesh assumption with a stored reference. + +Remaining: + +- Shared-owner transforms still affect all live instances; changing that API is separate work. +- Extend deduplication beyond `assetType === "models"` to blockstate level. ### 11. World subsystem redesign for scale — high (the V2 differentiator) -Immediate fixes: ~~fix `getChunkAt` to use `Map.get(key)`~~; ~~remove the 4×4×4 bound and negative-coordinate rejection~~; ~~remove hardcoded debug wireframes~~; ~~fix `BatchedExecutor`'s missing setInterval delay + add `stop()`~~; ~~place structures and chunks in bounded batches with one final neighbor-culling pass~~. Then the redesign: ~~palette + typed-array section storage~~, ~~opt-in merged meshes and bounded atlas pages per chunk section for models of any shape, including cutout, translucent, multipart, and animated models, plus fluid surfaces~~ (block entities retain per-block objects), ~~neighbor face culling via model `cullface` against opaque full cubes~~ (vanilla's same-block and connected-block rules from the `blockCulling` dataset also hide shared faces; partial-shape rules remain), ~~explicit chunk load/unload~~, ~~`await world.unloadChunkColumns(positions)` removes columns together and refreshes surviving neighbors once; the streamer requires this method, which `MineRenderWorld` provides, for eviction and disposal~~, ~~per-block visibility without deleting block data~~, ~~camera-driven streaming~~. ~~Opt-in baked per-vertex ambient occlusion from opaque full cubes, with runtime toggling.~~ Exact partial-shape ambient occlusion, chunk-level visibility management, and LOD remain. Section meshes already have bounds for Three.js frustum culling. -~~Sort transparent model and fluid quads back to front within each atlas page.~~ Intersecting surfaces and quad ordering across pages or sections remain approximate. +Done (immediate fixes): + +- Fix `getChunkAt` to use `Map.get(key)`. +- Remove the 4×4×4 bound and negative-coordinate rejection. +- Remove hardcoded debug wireframes. +- Fix `BatchedExecutor`'s missing setInterval delay and add `stop()`. +- Place structures and chunks in bounded batches with one final neighbor-culling pass. + +Done (redesign): + +- Palette and typed-array section storage. +- Opt-in merged meshes and bounded atlas pages per chunk section, for models of any shape and for fluid surfaces. + This covers cutout, translucent, multipart, and animated models; block entities keep per-block objects. +- Neighbor face culling via model `cullface` against opaque full cubes. + Vanilla's same-block and connected-block rules from the `blockCulling` dataset also hide shared faces. +- Explicit chunk load/unload. +- `await world.unloadChunkColumns(positions)` removes columns together and refreshes surviving neighbors once. + The streamer requires this method, which `MineRenderWorld` provides, for eviction and disposal. +- Per-block visibility without deleting block data. +- Camera-driven streaming. +- Opt-in baked per-vertex ambient occlusion on axis-aligned boundary faces, with runtime toggling. + It honors model opt-outs and refreshes edited or streamed neighbors. +- Seed weighted blockstate alternatives by world position, so unloading and reloading a chunk preserves its appearance. + Individual blocks and section meshes share vanilla-identical selection from absolute block coordinates. + Standalone previews remain random unless given `variantPosition`. +- Pick individual world blocks through `world.raycast`, including merged terrain. + The world demo inspects their coordinates, properties, and saved biome. +- Pick rendered mobs through `world.raycastEntities`; the world demo inspects their type and saved position. +- Resolve each block state once per placement group and yield to the event loop instead of a timer-driven batch queue. +- Build section geometry in a browser worker. +- Group ready streamed columns with a four-column read window and refresh shared borders once per placement group. +- Sort transparent model and fluid quads back to front within each atlas page. + +Done (biomes and light): + +- Preserve modern Anvil biome palettes during import and placement, including air-only sections, with world-coordinate lookup. +- Apply biome colors to grass, foliage, dry foliage, and water in both rendering modes. + This includes merged fluid sections, resource-pack colormaps, and dark forest/swamp grass modifiers. +- Opt-in biome color blending in section meshes, with a runtime radius, cached color averaging, and border refreshes after biome edits or streaming. +- Import saved sky/block light and apply opt-in flat lighting to blocks and fluids in section meshes. + +Done (fluids): + +- Render sloped water/lava surfaces with still/flow textures and waterlogged blocks. +- Cover intrinsic water in kelp, seagrass, and bubble columns. + +Remaining: + +- Exact partial-shape ambient occlusion. +- Light propagation. The published `blockLighting` dataset is not read yet. +- Intersecting surfaces and quad ordering across pages or sections remain approximate. +- Per-position flower offsets. The published `blockAppearance` offsets are not read yet. +- Draw glass and panes on the translucent page, as vanilla's render layers do (`blockAppearance` render layers); + they currently use the solid/cutout page. +- Chunk-level visibility management and LOD. Section meshes already have bounds for Three.js frustum culling. +- Older numeric biome arrays (the published `legacyBiomes` dataset is not read yet) and world-seed-based biome sampling. +- Region decoding still runs on the main thread. Wasm or worker-side chunk parsing remains a scale option once placement stops dominating. +- Measure real-world decoding, placement, frame stalls, and retained memory before choosing further worker or LOD work. + Use the [world-streaming benchmark](./apps/web/benchmarks/README.md): it records fixed local-save routes with cold and warm asset passes, + operation timings, frame-callback gaps, and JavaScript heap samples. +- Fluid parity: read the published `fluidStates` dataset (fluid definitions, face-occlusion shapes, solidity and flow-blocking flags) + and add water overlays against glass/leaves. + +Keep 1 block = 16 units. -~~Preserve modern Anvil biome palettes during import and placement, including air-only sections, with world-coordinate lookup.~~ ~~Apply biome colors to grass, foliage, dry foliage, and water in both rendering modes, including merged fluid sections, resource-pack colormaps, and dark forest/swamp grass modifiers.~~ ~~Add opt-in biome color blending in section meshes with a runtime radius, cached color averaging, and border refreshes after biome edits or streaming.~~ Older numeric biome arrays and world-seed-based biome sampling remain unsupported. ~~Import saved sky/block light and apply opt-in flat lighting to blocks and fluids in section meshes.~~ ~~Add opt-in ambient occlusion to axis-aligned boundary block faces in section meshes, honoring model opt-outs and refreshing edited or streamed neighbors.~~ Exact partial-shape ambient occlusion and light propagation remain. Measure real-world decoding, placement, frame stalls, and retained memory before choosing further worker or LOD work. The [world-streaming benchmark](./apps/web/benchmarks/README.md) records fixed local-save routes with cold and warm asset passes, operation timings, frame-callback gaps, and JavaScript heap samples. +### 12. Node headless rendering entry point — high -~~Seed weighted blockstate alternatives by world position so unloading and reloading a chunk preserves its appearance.~~ Individual blocks and section meshes share vanilla-identical weighted selection from absolute block coordinates. Standalone previews remain random unless given `variantPosition`. +Done: -~~Pick individual world blocks through `world.raycast`, including merged terrain, and inspect their coordinates, properties, and saved biome in the world demo.~~ +- Make `Renderer` constructible without DOM through an injected canvas and WebGL 2 context. +- Add `renderOnce()` and Node-only `NodeRenderer.renderToBuffer()` for fresh frames and PNG buffers without the animation loop. +- Add a V2 HTTP rendering service. -~~Pick rendered mobs through `world.raycastEntities` and inspect their type and saved position in the world demo.~~ +`NodeRenderer.create({ width, height, ...options })` owns a native context from optional `gl@9.0.0-rc.10` (experimental WebGL 2). +The Node entry uses `canvas` 3 for texture preparation. Injected contexts remain caller-owned. +See [platform setup and usage](./packages/minerender/reference/platforms.md). -~~Resolve each block state once per placement group and yield to the event loop instead of a timer-driven batch queue.~~ ~~Build section geometry in a browser worker.~~ ~~Group ready streamed columns with a four-column read window and refresh shared borders once per placement group.~~ Region decoding still runs on the main thread; wasm or worker-side chunk parsing remains a scale option once placement stops dominating. +[`apps/api`](./apps/api/README.md) accepts versioned scene documents at `POST /v1/renders` and serves render metadata and PNG images: -~~Render sloped water/lava surfaces with still/flow textures and waterlogged blocks.~~ ~~Cover intrinsic water in kelp, seagrass, and bubble columns.~~ For remaining fluid parity, obtain vanilla block-state fluid definitions, face-occlusion shapes, and solidity/flow-blocking flags; add water overlays against glass/leaves. Keep 1 block = 16 units. +- Rendering uses a pool of isolated processes with reusable asset caches, bounded concurrency, deadlines, and an expiring PNG cache. +- V2 deliberately replaces the V1 `GET /render/skin/:texture`, `GET /render/model/:type/:model`, and `minerender-options` contract. +- Returned PNG URLs can be embedded while cached; GET requests do not create renders. -### 12. Node headless rendering entry point — high -~~Make `Renderer` constructible without DOM through an injected canvas and WebGL 2 context.~~ ~~Add `renderOnce()` and Node-only `NodeRenderer.renderToBuffer()` for fresh frames and PNG buffers without the animation loop.~~ `NodeRenderer.create({ width, height, ...options })` owns a native context from optional `gl@9.0.0-rc.10` (experimental WebGL 2); the Node entry uses `canvas` 3 for texture preparation. Injected contexts remain caller-owned. See [platform setup and usage](./packages/minerender/reference/platforms.md). +Remaining: -~~Add a V2 HTTP rendering service.~~ [`apps/api`](./apps/api/README.md) accepts versioned scene documents at `POST /v1/renders` and serves render metadata and PNG images. Rendering uses a pool of isolated processes with reusable asset caches, bounded concurrency, deadlines, and an expiring PNG cache. V2 deliberately replaces the V1 `GET /render/skin/:texture`, `GET /render/model/:type/:model`, and `minerender-options` contract. Returned PNG URLs can be embedded while cached; GET requests do not create renders. Hosting and persistent render storage remain separate work. +- Hosting and persistent render storage. ### 13. Anvil region (.mca) + schematic loaders — high -~~Add a world-format layer feeding chunk storage: `.mca` sector tables, section palettes and DataVersion; preserve NBT type/compression metadata; implement legacy `.schematic` ID/metadata and AddBlocks conversion; retain structure entities and DataVersion.~~ ~~Support custom legacy schematic mappings and opt-in lenient parsing.~~ ~~Decode Anvil LZ4 block streams with checksum validation.~~ ~~Read external `.mcc` payloads through caller-supplied readers and local world-folder imports.~~ ~~Decode pre-1.13 numeric Anvil chunks with shared schematic mappings, custom overrides, and opt-in lenient parsing.~~ ~~Load Sponge v2/v3 `.schem` files with local palettes, block states, offsets, block/entity NBT, and DataVersion; add playground and editor imports.~~ ~~Load Litematica v5–7 `.litematic` files with named regions, signed dimensions, relative placement, and preserved block/entity NBT; add playground and editor imports.~~ ~~Add opt-in rendering of supported saved mobs at their positions and yaw, with cleanup on column replacement, unloading, and world clearing.~~ Sponge biome and metadata import and DataVersion-based migration remain. ~~Load modern worlds' separate `entities/*.mca` files alongside terrain with shared cache limits and cancellation, including entity-only columns and world-folder imports.~~ + +Done: + +- Add a world-format layer feeding chunk storage: `.mca` sector tables, section palettes, and DataVersion. + Preserve NBT type/compression metadata, implement legacy `.schematic` ID/metadata and AddBlocks conversion, + and retain structure entities and DataVersion. +- Support custom legacy schematic mappings and opt-in lenient parsing. +- Decode Anvil LZ4 block streams with checksum validation. +- Read external `.mcc` payloads through caller-supplied readers and local world-folder imports. +- Decode pre-1.13 numeric Anvil chunks with shared schematic mappings, custom overrides, and opt-in lenient parsing. +- Load Sponge v2/v3 `.schem` files with local palettes, block states, offsets, block/entity NBT, and DataVersion; + add playground and editor imports. +- Load Litematica v5–7 `.litematic` files with named regions, signed dimensions, relative placement, and preserved block/entity NBT; + add playground and editor imports. +- Add opt-in rendering of supported saved mobs at their positions and yaw, with cleanup on column replacement, unloading, and world clearing. +- Load modern worlds' separate `entities/*.mca` files alongside terrain with shared cache limits and cancellation, + including entity-only columns and world-folder imports. +- Read structure palettes saved with either `Name`/`Properties` or the Minecraft 26.x `id`/`properties` fields. + +Remaining: + +- Sponge biome and metadata import. +- DataVersion-based block-state and NBT migration. Renamed IDs are already replaced (section 6). ### 14. GUI renderer parity — medium -~~Implement `GuiObject`: layered textured planes with UV crop, pixel positioning, and ordered layers.~~ ~~Wire `scene.addGui(...)`, `inventorySlot`, and a chest demo with camera fitting.~~ ~~Add item models in the GUI display pose.~~ ~~Draw stack counts and supplied-component durability bars, preserve recipe output counts, and add an inventory-slot playground preview.~~ ~~Add shaped/shapeless recipe layouts and update crafting for the newer recipe format.~~ ~~Add modern GUI sprite scaling (stretch, tile, nine-slice).~~ ~~Render styled bitmap text and tooltips from supplied lines.~~ ~~Update V1's boss bar and book layouts for the newer texture paths, expose chest/crafting presets, and add playground controls.~~ ~~Load vanilla and resource-pack Unihex providers with size overrides, shared atlas pages, and matching text metrics.~~ TrueType providers, translated text, and right-to-left shaping remain. -### 15. Polish: exports, animation API, inspector, demos, docs — medium -~~Port toObj/toGLTF and toImage trim/mime.~~ ~~Add a per-frame callback integrated with the dirty flag (replaces V1's CustomEvent contract).~~ ~~Fix `SceneInspector` raycast normalization and select individual instances.~~ ~~Fix `SceneStatsDisplay`'s leaked interval.~~ ~~Fix animated-texture timing, frame grids/sequences, and stationary-camera redraw for all scenes sharing an atlas, respecting `fpsLimit`; stop unused atlas tickers.~~ ~~Add texture interpolation.~~ +Done: + +- Implement `GuiObject`: layered textured planes with UV crop, pixel positioning, and ordered layers. +- Wire `scene.addGui(...)`, `inventorySlot`, and a chest demo with camera fitting. +- Add item models in the GUI display pose. +- Draw stack counts and supplied-component durability bars, preserve recipe output counts, and add an inventory-slot playground preview. +- Add shaped/shapeless recipe layouts and update crafting for the newer recipe format. +- Add modern GUI sprite scaling (stretch, tile, nine-slice). +- Render styled bitmap text and tooltips from supplied lines. +- Update V1's boss bar and book layouts for the newer texture paths, expose chest/crafting presets, and add playground controls. +- Load vanilla and resource-pack Unihex providers with size overrides, shared atlas pages, and matching text metrics. -~~Build the V2 website with live examples.~~ ~~Rework the demos into configurable playgrounds.~~ ~~Add portable scene documents and a browser scene editor.~~ ~~Add TypeDoc/VitePress reference tooling and library API JSDoc.~~ ~~Host the playgrounds and editor on Cloudflare.~~ ~~Add browser video export with recording controls.~~ +Remaining: + +- TrueType providers. +- Translated text. +- Right-to-left shaping. + +### 15. Polish: exports, animation API, inspector, demos, docs — medium -~~Add scene-driven iframe embeds with shorthand URLs, portable scene links, and editor copy support.~~ Deploy the embed Worker at its configured V2 routes. ~~Remove unused V1 website files from the V2 tree while preserving V1 delivery URLs.~~ Extend existing regression coverage as remaining model and blockstate features land; keep the consumer API contract in AGENTS.md as the beta compatibility baseline. +Done: + +- Port toObj/toGLTF and toImage trim/mime. +- Add a per-frame callback integrated with the dirty flag (replaces V1's CustomEvent contract). +- Fix `SceneInspector` raycast normalization and select individual instances. +- Fix `SceneStatsDisplay`'s leaked interval. +- Fix animated-texture timing, frame grids/sequences, and stationary-camera redraw for all scenes sharing an atlas, respecting `fpsLimit`. + Stop unused atlas tickers. +- Add texture interpolation. +- Build the V2 website with live examples. +- Rework the demos into configurable playgrounds. +- Add portable scene documents and a browser scene editor. +- Add TypeDoc/VitePress reference tooling and library API JSDoc. +- Host the playgrounds and editor on Cloudflare. +- Add browser video export with recording controls. +- Add scene-driven iframe embeds with shorthand URLs, portable scene links, and editor copy support. +- Remove unused V1 website files from the V2 tree while preserving V1 delivery URLs. +- Deploy the embed Worker at `beta.minerender.org/embed/`. +- Route library logging through leveled per-component loggers; only warnings and errors print by default. + +Remaining: + +- Extend existing regression coverage as remaining model and blockstate features land. +- Keep the consumer API contract in AGENTS.md as the beta compatibility baseline. diff --git a/packages/minerender/README.md b/packages/minerender/README.md index b956e3d3..76869581 100644 --- a/packages/minerender/README.md +++ b/packages/minerender/README.md @@ -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/). @@ -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: @@ -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). diff --git a/packages/minerender/reference/.vitepress/config.mts b/packages/minerender/reference/.vitepress/config.mts index d6f79344..f20f032f 100644 --- a/packages/minerender/reference/.vitepress/config.mts +++ b/packages/minerender/reference/.vitepress/config.mts @@ -11,8 +11,9 @@ 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: [ @@ -20,7 +21,7 @@ export default defineConfig({ 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" } ] diff --git a/packages/minerender/reference/concepts.md b/packages/minerender/reference/concepts.md index d0a637e8..1806e38c 100644 --- a/packages/minerender/reference/concepts.md +++ b/packages/minerender/reference/concepts.md @@ -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 @@ -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//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//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. @@ -115,7 +113,11 @@ 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 @@ -123,13 +125,21 @@ With model instancing enabled, scene methods can return an [InstanceReference](/ 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 @@ -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//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. diff --git a/packages/minerender/reference/index.md b/packages/minerender/reference/index.md index c68cd8dd..6571814e 100644 --- a/packages/minerender/reference/index.md +++ b/packages/minerender/reference/index.md @@ -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. diff --git a/packages/minerender/reference/platforms.md b/packages/minerender/reference/platforms.md index 05f4fbe9..5b604886 100644 --- a/packages/minerender/reference/platforms.md +++ b/packages/minerender/reference/platforms.md @@ -34,6 +34,8 @@ import { Renderer } from "minerender"; Rollup, which Vite uses for production builds, keeps every exported class in that chunk when the application uses `await import("minerender")`. +World section meshing starts its Web Worker with `new Worker(new URL("./section.worker.mjs", import.meta.url))`. Bundlers that recognize this pattern emit the worker file with your build; check that a `section.worker` file appears in the output. Without it, and in the CommonJS and script-tag builds, which have no `import.meta.url`, sections build synchronously on the main thread. + ## Platform requirements The supported environments have these requirements: @@ -100,7 +102,7 @@ Use the environment that supports the operation: | ZIP resource packs | [BrowserArchiveProxy](/api/index/classes/BrowserArchiveProxy) | No Node-specific archive proxy is provided | | glTF and GLB export | Supported through [SceneExporter](/api/index/classes/SceneExporter) | Requires browser canvas and `FileReader` | | Video export | `Renderer.toVideo()` requires canvas `captureStream()` and `MediaRecorder`; formats depend on the browser | Requires a browser environment | -| World section meshing | Geometry builds in a Web Worker when the ESM build's `section.worker` file ships beside the module; the IIFE bundle and bundlers that drop it build synchronously | Synchronous | +| World section meshing | Geometry builds in a Web Worker when the ESM build's `section.worker` file ships beside the module; the CommonJS and IIFE builds and bundlers that drop the file build synchronously | Synchronous | `Renderer.toImage()` returns a data URL from its browser canvas. `NodeRenderer.renderToBuffer()` returns PNG bytes. DOM controls, displays, and glTF/GLB export remain browser-only; importing the Node build does not supply those browser APIs. diff --git a/packages/minerender/scripts/typedoc-navigation.mjs b/packages/minerender/scripts/typedoc-navigation.mjs index 2d620293..5ceb5294 100644 --- a/packages/minerender/scripts/typedoc-navigation.mjs +++ b/packages/minerender/scripts/typedoc-navigation.mjs @@ -36,6 +36,11 @@ const sections = [ primary: ["GuiObject", "GuiObjectOptions", "GuiLayer", "GuiHelper", "GuiRecipe"], description: "Compose ordered texture and item layers in GUI pixel coordinates." }, + { + id: "scenes", title: "Scene documents", match: /^scene\//, + primary: ["SceneDocument", "SceneDocumentLoader", "encodeSceneDocument", "decodeSceneDocument", "SceneItemContext"], + description: "Validate, load, and share versioned scene JSON." + }, { id: "assets", title: "Assets & resource packs", match: /^(assets\/(?!ModelTextures\.ts)|MinecraftAsset\.ts|ListAsset\.ts)/, primary: ["AssetLoader", "AssetKey", "HostedAssetSource", "ArchiveAssetSource", "BrowserArchiveProxy"], @@ -48,9 +53,9 @@ const sections = [ description: "Work with image decoding, texture atlases, animated textures, and shared materials." }, { - id: "platforms", title: "Platforms & lifecycle", match: /^(env\/|Env\.ts|shutdown\.ts|Disposable\.ts|cache\/|request\/)/, - primary: ["Env", "EnvProvider", "BrowserEnv", "NodeEnv", "shutdown"], - description: "Inspect platform providers, shared caches, request queues, and final shutdown. Browser and Node entry points add their own providers." + id: "platforms", title: "Platforms & lifecycle", match: /^(env\/|Env\.ts|shutdown\.ts|Disposable\.ts|cache\/|request\/|util\/log\.ts)/, + primary: ["NodeRenderer", "Env", "EnvProvider", "Logging", "shutdown"], + description: "Render in Node, inspect platform providers, configure logging, and manage shared caches, request queues, and final shutdown. Browser and Node entry points add their own providers." }, { id: "utilities", title: "Utilities & supporting types", match: /.*/, diff --git a/packages/minerender/src/world/MineRenderWorld.ts b/packages/minerender/src/world/MineRenderWorld.ts index 8000a78b..0d50f660 100644 --- a/packages/minerender/src/world/MineRenderWorld.ts +++ b/packages/minerender/src/world/MineRenderWorld.ts @@ -826,7 +826,7 @@ export class MineRenderWorld { export interface MineRenderWorldOptions { /** Render supported saved mobs at their position and yaw, including supported appearance fields. Defaults to false. */ renderEntities?: boolean; - /** Merge static opaque cubes into section meshes. Merged blocks have no individual object. */ + /** Merge block models of any shape and fluid surfaces into per-section meshes; block entities keep individual objects. Merged blocks have no individual object. */ sectionMeshing?: SectionMeshing; /** Shade blocks and fluids with saved sky/block light. Missing or invalid data keeps preview brightness. Defaults to false. Requires `sectionMeshing`. */ savedLighting?: boolean; @@ -836,6 +836,6 @@ export interface MineRenderWorldOptions