Repository navigation
API Worldgen Structure Lua
Lua API / World generation / Structure documents / Lua authoring
Lua uses the same data model as JSON. Use a plain table when the document is already easy to read as data; use the builder when incremental mutation, loops, or helper functions make intent clearer.
| Form | Best for |
|---|---|
| JSON asset | Static content, schema assistance, sharing with external tools, and data-only packages. |
| Plain Lua table | Compact generated documents and reusable Lua modules where direct table syntax stays readable. |
| Builder | Incremental construction, loops, conditional authoring, and named helper functions. |
| Compiled handle | Validating once and reusing an immutable compiled structure in one or more registrations. |
structures:add snapshots Lua input. Mutating the original table or builder after registration does not change an
already registered structure.
local document = {
palette = {
stone = { block = 4, tags = { "structural" } }
},
elements = {
{
type = "fill",
from = { -2, 0, -2 },
to = { 2, 0, 2 },
state = "stone"
}
},
processors = {}
}
local platform = betamoon.worldgen.structures:add {
key = "mymod:platform",
template = document
}Lua may omit format; BetaMoon inserts betamoon_structure. If format is supplied, it must have that exact value.
Creates a mutable table-backed builder. initial is optional and is copied, so nested source tables can be reused
without sharing later mutations.
local builder = betamoon.worldgen.structures:builder {
bounds = { min = { -4, 0, -4 }, max = { 4, 8, 4 } }
}
builder:state("stone", {
block = 4,
tags = { "structural", "weatherable" }
})
for x = -3, 3 do
builder:block {
pos = { x, 0, 0 },
state = "stone",
tags = { "foundation" }
}
end
builder:processor {
type = "decay",
key = "edge_damage",
select = {
tags = { "weatherable" },
excludeTags = { "foundation" },
minExposedFaces = 2
},
chance = 0.08
}The builder remains an ordinary visible Lua table. Advanced code may inspect or edit builder.palette,
builder.templates, builder.elements, builder.processors, and builder.bounds directly. Helper methods copy the
supplied definition and return the builder for chaining.
| Method | Behavior |
|---|---|
state(name, definition) |
Sets palette[name]. |
block, fill, shell, frame, line, staircase
|
Appends the matching element type. |
cylinder, ellipsoid, voxelMap
|
Appends the matching shape; voxelMap writes type voxel_map. |
clear, replaceState
|
Appends clear or replace_state. |
template / use
|
Appends a template-use element. Define reusable templates through builder.templates. |
array, repeatElement
|
Appends array or repeat. |
chance, choice
|
Appends conditional composition. |
loot, marker
|
Appends loot or marker elements. |
processor(definition) |
Appends a root document processor. |
compile() |
Validates immediately and returns an immutable compiled structure handle. |
clone() |
Returns an independent deep-copied builder. |
Call methods with : so the builder is passed as the receiver.
local builder = betamoon.worldgen.structures:builder()
builder:state("stone", { block = 4 })
builder.templates.pillar = {
elements = {
{
type = "fill",
from = { 0, 0, 0 },
to = { 0, 4, 0 },
state = "material"
}
}
}
builder:array {
template = "pillar",
at = { -3, 0, -3 },
count = { 2, 1, 2 },
step = { 6, 0, 6 },
states = { material = "stone" }
}This retains table-like readability while allowing a Lua loop or helper to construct any nested list or state map.
local validated = builder:compile()
local first = betamoon.worldgen.structures:add {
key = "mymod:first_ruin",
template = validated
}
local variant = builder:clone()
variant:state("stone", { block = 48 })compile() is useful when one generated document is registered more than once or when validation should happen at a
specific point in initialization. A compiled handle is immutable and is not a general table.
Lua structure data must be serializable as one unambiguous JSON-compatible tree:
- maximum nesting depth: 48;
- maximum total values: 150,000;
- numeric values must be finite and within -1,000,000 through 1,000,000;
- arrays must be dense, one-based sequences;
- one table cannot mix array indexes and object keys;
- keys must be strings for objects;
- functions, userdata, threads, metatables as data, and table cycles are rejected.
Empty tables are interpreted from their known field context—for example, an empty elements list or empty object
where the document schema permits it.
Next: structure inventory loot.
- Installation
- Install scripts
- Getting started
- VS Code and LuaLS
- Examples
- Reload and compatibility
- Troubleshooting
- Changelog
Scripts and shared values
- Script lifecycle
- Packaged Lua mods
- Modules
- References and stacks
- Queries
- Overrides
- Minecraft constants
- Chat and positions
- Structured data
- Script configuration
- Particles
Blocks and items
- Multiblocks
- Blocks
- Block state and placement
- Block shapes and rendering
- Block callbacks
- Block ticks and redstone
- Items
- Fluids
- Item callbacks
- Tools and armor
- Materials
- Textures
Entities
- Entities
- Entity access and movement
- Entity lifecycle and data
- Entity health and loot
- Entity inventories and relationships
- Projectiles and pickups
- Entity presentation and sounds
- Living entities and AI
- Entity parts and sensors
Assets and audio
- Assets
- Models and animations
- Built-in Minecraft models
- Model appearances
- Blockbench workflow
- Audio
- Texture-pack overrides
Events and world actions
World generation
World systems
Inventories and screens
Recipes