From 793cb519b6307d3fce50dade8322046a4652c87f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Haylee=20Sch=C3=A4fer?= Date: Sat, 17 Oct 2026 20:13:13 +0200 Subject: [PATCH] Refresh website copy for embeds, world lighting, and logging Correct the world note that claimed no lighting or biome blending, the GUI note that called Unihex unsupported, and the fence snippet's `state` field (`properties`). Add an embeds card and article, a logging article, world lighting, ambient occlusion, biome blending, and raycast options, animation weights, and renamed-ID resolution. Co-Authored-By: Claude Opus 5.5 --- apps/site/index.html | 69 ++++++++++++++++++++++++++++++----- apps/site/src/examples/gui.ts | 6 +-- apps/site/src/icons.ts | 10 +++++ 3 files changed, 72 insertions(+), 13 deletions(-) diff --git a/apps/site/index.html b/apps/site/index.html index 880211de..abc820d8 100644 --- a/apps/site/index.html +++ b/apps/site/index.html @@ -137,7 +137,7 @@

Layered asset sources

Any game version

-

Defaults to Minecraft 1.21.11, including modern item definitions. Switch versions with one call; item defaults, potion colors and block tints follow the selected version, and caches are keyed by version.

+

Defaults to Minecraft 1.21.11, including modern item definitions. Switch versions with one call; item defaults, potion colors and block tints follow the selected version, older block, item and entity IDs resolve to their renamed replacements, and caches are keyed by version.

Choosing a game version
@@ -185,7 +185,7 @@

Fluids and animated textures

Worlds, not just structures

-

Loads structure, schematic, Litematica and Anvil region files, streams chunk columns around the camera, and colors grass, foliage and water from saved biomes. Optional section meshing merges each 16³ section into a few meshes with hidden faces culled.

+

Loads structure, schematic, Litematica and Anvil region files, streams chunk columns around the camera, and colors grass, foliage and water from saved biomes. Optional section meshing merges each 16³ section into a few meshes and can add saved light, ambient occlusion and biome blending. Raycasts find the block or mob under the pointer.

See structures and worlds
@@ -193,7 +193,7 @@

Worlds, not just structures

GUIs with items, text and recipes

-

Build inventory screens and HUD elements from textures, bitmap text and item models with stack counts and durability bars. Helpers lay out crafting recipes, container backgrounds, boss bars, book pages and tooltips.

+

Build inventory screens and HUD elements from textures, bitmap and Unihex text and item models with stack counts and durability bars. Helpers lay out crafting recipes, container backgrounds, boss bars, book pages and tooltips.

See GUIs
@@ -209,10 +209,18 @@

Images, video and 3D exports

Typed and tree-shakeable

-

TypeScript declarations, ESM and CommonJS builds, no work at import time, and a classic script-tag bundle for pages without a build step.

+

TypeScript declarations, per-module ESM and CommonJS builds, no work at import time, and a classic script-tag bundle for pages without a build step. Model, entity and GUI code loads on first use.

Install
+
  • + +
    +

    Embeds from a URL

    +

    An iframe page renders a skin, block, item, entity or full scene from URL parameters. The scene editor copies an embed link for the current scene.

    + Embed a scene +
    +
  • @@ -256,13 +264,16 @@

    Examples

    Assets and versions Worlds and files Exporting + Embeds Lifecycle + Logging Node Performance Reference API reference Behavior notes Browser & Node + Embed URLs
    @@ -387,13 +398,16 @@

    Scene and objects

    properties: { "minecraft:bundle/has_selected_item": true }, itemReferences: { "minecraft:bundle/selected_item": apple } // AssetKey of the item drawn inside }); -

    Mobs with keyframe animations (warden, frog, camel, breeze, armadillo, sniffer, bat and others) expose them through Entities.getAnimations. The entity owns no clock, so advance it from a frame callback.

    +

    Mobs with keyframe animations (warden, frog, camel, breeze, armadillo, sniffer, bat and others) expose them through Entities.getAnimations. The entity owns no clock, so advance it from a frame callback. playAnimations plays several clips on one clock and adds their weighted offsets.

    const animations = await Entities.getAnimations(key);   // undefined without any
     warden.playAnimation(animations!.roar, { loop: true, speed: 1 });
     const stop = renderer.onFrame(({ delta }) => warden.advanceAnimation(delta));
     warden.setAnimationTime(1.5);   // or pose at an explicit time
    -warden.stopAnimation();         // restores the default pose
    -

    GUIs take ordered texture, item and text layers in GUI pixels, with y growing down. Item layers draw stack counts and durability bars from their context; set decorations: false to hide both. gui.bounds reports the drawn area for fitting an orthographic camera, GuiHelper.inventorySlot turns a slot index into a position, and GuiHelper.recipe lays out a crafting recipe, including the result count. Text layers draw bitmap fonts from the resource pack, and GuiHelper.container, bossBar, book and tooltip return ready layer lists.

    +warden.stopAnimation(); // restores the default pose + +warden.playAnimations([animations!.roar, animations!.sniff], { weights: [1, 0.5] }); +warden.setAnimationWeights([1, 0.25]); // without restarting playback +

    GUIs take ordered texture, item and text layers in GUI pixels, with y growing down. Item layers draw stack counts and durability bars from their context; set decorations: false to hide both. gui.bounds reports the drawn area for fitting an orthographic camera, GuiHelper.inventorySlot turns a slot index into a position, and GuiHelper.recipe lays out a crafting recipe, including the result count. Text layers draw the resource pack's bitmap and Unihex fonts, and GuiHelper.container, bossBar, book and tooltip return ready layer lists.

    const gui = await scene.addGui([
         { texture: "minecraft:gui/container/generic_54", crop: [0, 0, 176, 222] },
         { item: "minecraft:item/apple", position: GuiHelper.inventorySlot(0, [8, 18]), context: { count: 16 } },
    @@ -450,14 +464,14 @@ 

    Assets and versions

    Worlds and files

    -

    MineRenderWorld stores blocks in 16³ chunks with signed coordinates and keeps faces against opaque neighbors from being drawn. With sectionMeshing, block models of any shape, animated textures, and fluid surfaces are merged into solid, translucent, and fluid meshes per section; block entities stay individual objects.

    +

    MineRenderWorld stores blocks in 16³ chunks with signed coordinates. Faces against opaque neighbors are not drawn, nor are faces between touching glass, ice or connected panes, as in vanilla. With sectionMeshing, block models of any shape, animated textures, and fluid surfaces are merged into solid, translucent, and fluid meshes per section; block entities stay individual objects.

    import { AnvilParser, AnvilWorldSource, MineRenderWorld, NBTHelper, SchematicParser, StructureParser, WorldStreamer } from "minerender";
     
     const world = new MineRenderWorld(renderer.scene, { sectionMeshing: true });
     
     // Blocks from code
     await world.setBlockAt(0, 0, 0, { type: "minecraft:stone" });
    -await world.setBlockAt(0, 1, 0, { type: "minecraft:oak_fence", state: { north: "true" } });
    +await world.setBlockAt(0, 1, 0, { type: "minecraft:oak_fence", properties: { north: "true" } });
     
     // Vanilla structure files and legacy schematics
     const nbt = await NBTHelper.fromBuffer(bytes);
    @@ -480,7 +494,22 @@ 

    Worlds and files

    await streamer.updatePosition(renderer.orbitControls!.target); // call again whenever the view moves await streamer.dispose(); // unloads its columns

    The library also loads Sponge .schem files through SpongeSchematicParser and Litematica .litematic files through LitematicaParser. Anvil loading reads numeric and paletted chunks with gzip, zlib or LZ4 compression; the optional readExternalChunk and readEntityRegion callbacks add external .mcc payloads and the separate entity region files.

    -

    Bulk placement resolves each block state once and yields to the page every few milliseconds, and section meshes are built in a worker when your bundle keeps the package's section.worker file next to the module. Saved biomes supply grass, foliage and water colors. The world has no lighting, biome blending or level of detail.

    +

    Bulk placement resolves each block state once and yields to the page every few milliseconds, and section meshes are built in a worker when your bundle keeps the package's section.worker file next to the module. Saved biomes supply grass, foliage and water colors.

    +

    With section meshing, a world can also shade terrain from the light saved in Anvil chunks, darken corners with ambient occlusion and blend biome colors across borders. renderEntities draws supported saved mobs, and raycasts return the block or mob under the pointer. Light propagation and level of detail are not supported.

    +
    import { Raycaster } from "three";
    +
    +const world = new MineRenderWorld(renderer.scene, {
    +    sectionMeshing: true,
    +    savedLighting: true,      // sky and block light from the save
    +    ambientOcclusion: true,   // corner shading next to opaque blocks
    +    biomeBlendRadius: 3,      // average biome colors over 3 blocks
    +    renderEntities: true      // supported mobs at their saved positions
    +});
    +
    +const raycaster = new Raycaster();
    +raycaster.setFromCamera(pointer, renderer.camera);   // pointer in normalized device coordinates
    +const block = world.raycast(raycaster);              // { position, block, point, normal, distance }
    +const mob = world.raycastEntities(raycaster);        // { type, position, object, ... }
    @@ -498,6 +527,17 @@

    Exporting

    glTF export needs a browser. Custom shading is not baked into the exported materials. Video recording runs in real time through MediaRecorder, keeps the canvas size at the start, fills transparent pixels with black and can be cancelled with an AbortSignal.

    +
    +

    Embeds

    +

    To show a render on another page without bundling the library, use the embed page in an iframe. It takes one source: skin, block, item, entity, model, a scene link from the editor's Copy embed button, or an HTTPS src pointing to a scene document.

    +
    <iframe
    +  src="https://beta.minerender.org/embed/?item=minecraft:diamond_sword"
    +  title="Diamond sword"
    +  width="320" height="320" loading="lazy"
    +  style="border:0"></iframe>
    +

    The embed fits the scene to the iframe when no camera is given, and releases its WebGL context while scrolled out of view. The embed reference lists every URL parameter.

    +
    +

    Lifecycle

    stop() pauses the loop and start() resumes it. dispose() is final: it releases the WebGL context, the controls and owned helpers. Shared assets stay cached.

    @@ -510,6 +550,15 @@

    Lifecycle

    shutdown();
    +
    +

    Logging

    +

    The library prints only warnings and errors. Raise the level for one component while investigating a problem:

    +
    import { Logging } from "minerender";
    +
    +Logging.configure({ level: "warn", namespaces: { HostedAssetSource: "debug" } });
    +

    On a deployed page, set localStorage["minerender:log"] = "debug" and reload; in Node, set MINERENDER_LOG=debug. See logging for handlers and the setting format.

    +
    +

    Node

    NodeRenderer.create() opens a native WebGL 2 context without a browser DOM. renderToBuffer() draws a fresh frame and returns PNG bytes. Use Node.js 22.12 or later with working native canvas and gl dependencies; headless Linux also needs Mesa and an X server such as Xvfb. See the platform setup guide.

    diff --git a/apps/site/src/examples/gui.ts b/apps/site/src/examples/gui.ts index f84f2560..2c404128 100644 --- a/apps/site/src/examples/gui.ts +++ b/apps/site/src/examples/gui.ts @@ -254,7 +254,7 @@ const LAYOUTS: Record Promise const layouts: Example = { id: "gui-layouts", title: "Tooltips, boss bars and books", - description: "GuiHelper builds the layer lists for common screens from the active resource pack: tooltips sized around bitmap text, boss bars, book pages with arrows, and container backgrounds with their slot layout.", + description: "GuiHelper builds the layer lists for common screens from the active resource pack: tooltips sized around their text, boss bars, book pages with arrows, and container backgrounds with their slot layout.", renderer: GUI_RENDERER, placeholder: "/placeholder-block.png", async setup(context) { @@ -306,11 +306,11 @@ await renderer.scene.addGui([{ text: [{ text: "Bold", bold: true }, { text: " an export const guis: ExampleGroup = { id: "guis", title: "GUIs", - lead: "Inventory screens, HUD elements, tooltips and crafting recipes built from texture crops, bitmap text and item models, rendered flat with an orthographic camera.", + lead: "Inventory screens, HUD elements, tooltips and crafting recipes built from texture crops, bitmap and Unihex text and item models, rendered flat with an orthographic camera.", playgrounds: [{ url: "https://beta.minerender.org/demo/gui/", label: "GUI playground" }], examples: [chest, hotbar, recipe, layouts], notes: [ "Item layers draw stack counts and durability bars from their context; durability falls back to the selected version's vanilla value. Set decorations to false to hide both.", - "Text uses the resource pack's bitmap fonts. Unihex and TrueType providers, translations and right-to-left shaping are not supported; missing glyphs draw as boxes." + "Text uses the resource pack's bitmap and Unihex fonts. TrueType providers, translations and right-to-left shaping are not supported; missing glyphs draw as boxes." ] }; diff --git a/apps/site/src/icons.ts b/apps/site/src/icons.ts index 5073eff1..5a807aa6 100644 --- a/apps/site/src/icons.ts +++ b/apps/site/src/icons.ts @@ -142,6 +142,16 @@ const ICONS: Record = { ".k....k.", ".kkkkkk." ], + embed: [ + "........", + "..k..k..", + ".k....k.", + "k..gg..k", + "k..gg..k", + ".k....k.", + "..k..k..", + "........" + ], entity: [ "........", ".gggggg.",