Skip to content

API Block Shapes and Rendering

Piggo41 edited this page Oct 16, 2026 · 7 revisions

Block shapes and rendering

Lua API / Blocks / Shapes and rendering

On this page

Box definition

A box is { min = { x, y, z }, max = { x, y, z } }. Coordinates are local to the block, range 0–1. Every minimum must be strictly less than its matching maximum.

local post = { min = { 0.25, 0, 0.25 }, max = { 0.75, 1, 0.75 } }

collision.boxes

List of zero to sixteen boxes. Omitted collision uses normal full-block collision; an empty list has no collision boxes. Multiple boxes describe disjoint or overlapping collision volumes. With horizontal placement facing, author the boxes for the state.facing default; BetaMoon rotates them to follow each placed block's saved facing.

collision = { boxes = { post } }

selection

One box controlling the outline and selection bounds. Omitted uses normal selection behavior. With horizontal placement facing, author this box for the state.facing default; BetaMoon rotates it with the placed block.

selection = post

appearance

Optional model appearance table selecting exported geometry, textures, and animations. Use render.variants[metadata].appearance for a variant-dependent model. Collision and selection remain configured independently above.

render.preset

String, default "cube". Accepted values: cube, cuboid (cube renderer with bounds), cross (crossed planes).

render.bounds

Optional box for drawing bounds. With horizontal placement facing, author this box for the state.facing default; it rotates with the placed block. Rendering bounds do not automatically define collision or selection; configure each purpose separately.

render = { preset = "cuboid", bounds = post }

render.pass

Integer 0 or 1, default 0. Selects the rendering pass. Pass 1 is useful for translucent content; opacity and collision remain separate properties.

render.variants

Table keyed by metadata integers 0–15. Each entry supplies texture, tint, or appearance overrides for that exact metadata.

Variant field Type Default / meaning
texture integer 0–255 All-face atlas index; omitted uses base textures.
textures map of face names to integers 0–255 Overrides individual physical faces.
color integer 0–0xFFFFFF RGB tint; default 0xFFFFFF.
appearance appearance table or false Variant model appearance; omitted inherits the default.
render = {
    variants = {
        [0] = { texture = 1 },
        [1] = { texture = 4, color = 0x88CC88 }
    }
}

Variant texture values are atlas indices, not PNG paths. Base texture declarations accept custom paths. Variant face maps use individual faces, not the broad all/ sides assignments of the base map.

Example: Block shapes.

render.variants[metadata].appearance

Optional model appearance for that exact block metadata value. It applies to the placed block and its inventory, held, and dropped item presentation.

  • A table completely replaces the top-level appearance; nested fields are not merged.
  • Omit it to inherit the top-level appearance.
  • Set it to false to use ordinary block rendering, including the variant's textures and color.
-- Fields inside a block declaration; register the named assets first:
appearance = { model = "mymod:block/machine", texture = "mymod:block/machine_idle" },
render = {
    variants = {
        [1] = { appearance = {
            model = "mymod:block/machine", texture = "mymod:block/machine_active",
            animation = { asset = "mymod:block/machine", clip = "animation.machine.running" }
        } },
        [2] = { appearance = false, texture = 1 }
    }
}

Unlisted metadata uses the default appearance. If any appearance requires dynamic rendering, every state of the block type renders dynamically. Blocks with only static appearances remain static. See block rendering for the supported material settings.

Appearance hot reload rebuilds visuals without replacing blocks or changing metadata, Lua tile data, or inventories. See refresh and compatibility.

Clone this wiki locally