Biomes API
Mods register biome types for the world generator.
Constants: realms
Voxelius uses a single world "dimension". Vertical range is split into realms instead. Each biome belongs to a realm. A realm is a horizontal slice of the world with its own terrain generation model.
| Name | Y-Range | Description |
|---|---|---|
biomes.REALM_SKY | 256..767 | Rare, large, ore-rich floating islands above the highest surface points |
biomes.REALM_SURFACE | -64..255 | Common terrain and biomes. Players and most playable structures spawn here |
biomes.REALM_UNDERGROUND | -256..-63 | Classic cave systems, underground rivers, and solid ore amounts |
biomes.REALM_THE_DEPTHS | -512..-255 | Vast dark caverns. Ore-rich if players take risks |
Constant: null biome
biomes.NULL_BIOME is an empty, undefined, or otherwise invalid biome ID. Treat it as a void biome for gameplay and gamedev.
Functions
Function: biomes.add(name, def) -> integer
Registers a new biome.
Arguments
nameis the namespaced biome IDdefis the biome definition table
Return value
Returns the numeric biome ID.
Biome definition
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
realm | integer | yes | N/D | One of biomes.REALM_XXXX constants |
temperature | integer | no | 50 | Target temperature in climate space, 0 to 99 |
humidity | integer | no | 50 | Target humidity in climate space, 0 to 99 |
continentalness | integer | no | 50 | Target continentalness, 0 to 99. Low values correspond to oceans |
erosion | integer | no | 50 | Target erosion, 0 to 99. High values are flat terrain, low values are mountainous |
weirdness | integer | no | 50 | Target weirdness or ridges, 0 to 99. Drives biome variants and peaks-vs-valleys terrain offset |
priority | integer | no | 0 | If two biomes claim the same climate target during setup, the higher priority keeps the point. The engine nudges the loser until the point becomes unique |
offset | number | no | 0 | The engine adds this value to climate distance when it picks a biome. Larger values make the biome harder to win and effectively smaller |
palette | table | no | {} | Biome block palette |
scatter | table[] | no | {} | List of features to scatter |
tints | table | no | {} | Tint group override colors |
Palette table
| Field | Description |
|---|---|
basic | Basic block type, eg builtin:stone |
filler | Filler block type, eg builtin:dirt |
surface | Surface block type, eg builtin:grass |
fluid | Fluid block type, eg builtin:water |
Palette entry
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | yes | N/D | Block name |
states | table | no | {} | Block states |
Scatter entry
The engine evaluates scatter entries in list order. If several entries pass the roll on the same column, the last entry in the list wins. The engine skips the other entries for that column.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
feature | string | yes | N/D | Feature to place |
chance | number | no | 0.5 | Chance of a placement attempt per column |
need_above | integer[] | no | {} | List of blocks.TAG_XXXX constants. The block above the origin must have at least one listed tag |
need_below | integer[] | no | {} | List of blocks.TAG_XXXX constants. The origin block (surface) must have at least one listed tag |
padding | integer | no | 0 | Minimum block clearance between this feature's bounding box and another placement in the same padding family. The engine uses expanded-box separation: it grows the current box by padding blocks, then tests for intersection |
group | string | no | "" | Padding family name. Entries with the same non-empty group share padding. An empty group pads only against the same scatter entry |
edge | integer | no | 0 | Extra blocks beyond the feature's XZ bounds that must still belong to the same biome. The engine always checks the feature AABB footprint. edge grows that check, so large decorations stay clear of biome borders |
Example
biomes.add("plains", {
realm = biomes.REALM_SURFACE,
temperature = 50,
humidity = 50,
continentalness = 55,
erosion = 70,
weirdness = 50,
priority = 0,
offset = 0,
palette = {
empty = { name = "air" },
basic = { name = "stone" },
filler = { name = "dirt" },
surface = { name = "stone_slab", states = { orientation = "bottom" } },
fluid = { name = "water" },
},
scatter = {
{
feature = "oak_tree",
chance = 0.0625,
need_above = { blocks.TAG_GAS },
need_below = { blocks.TAG_TURF },
},
{
feature = "bush",
chance = 0.25,
need_above = { blocks.TAG_GAS },
need_below = { blocks.TAG_TURF },
}
}
})
Climate / multi-noise
Biome placement uses a sparse multi-noise model aligned with Minecraft 1.18+. At generation time the engine samples five continuous climate noises: temperature, humidity, continentalness, erosion, and weirdness. The engine picks a biome whose target point in that space is nearest.
During mod loading, each biome defines a nucleation point at its target coordinates (0..99 per axis). If two biomes collide, the higher priority keeps the cell. The engine nudges the loser randomly until it gets a free slot.
Climate axes
| Axis | Terrain role | Biome role |
|---|---|---|
| Temperature | none | Climate bands, frozen ocean |
| Humidity | none | Forests, swamps, jungles |
| Continentalness | Base height, oceans vs land | Ocean / inland biomes |
| Erosion | Flat vs mountainous relief | Peaks, meadows, shattered terrain |
| Weirdness | Peaks-and-valleys offset via PV transform | Biome variants |