API
World generation
Ores, trees, flowers, structures and biomes that appear by themselves in the world. You declare what and where, and new chunks get it.
Ores
block "ruby_ore" { hardness: 3, tool: "pickaxe", tier: "iron" }
ore "ruby_ore" {
replaces: "stone_and_deepslate"
size: 9
per_chunk: 8
height: [-60, 60]
}| Property | Values | Default |
|---|---|---|
block |
the block to place: "mymod:other" |
the block named like the ore |
replaces |
stone, deepslate, stone_and_deepslate (overworld), netherrack (Nether) or end_stone (End) |
stone_and_deepslate |
size |
blocks per vein, 1–64 | 8 |
per_chunk |
veins tried per chunk | 8 |
height |
[min, max], height range |
[-64, 64] |
biomes |
only in these biomes, by id or by tag | every biome where its rock is |
Without biomes, the ore appears in every biome of the dimension that replaces belongs to; an end_stone ore, in every biome of the End. The block itself is declared like any other, with its hardness, tool and loot; see Blocks, items and recipes.
ore "void_ore" {
replaces: "end_stone"
size: 5
per_chunk: 6
height: [10, 80]
biomes: ["mymod:crystal_glade"]
}Trees
A tree is a straight trunk with a ball of leaves. Declare the two blocks, then the tree.
block "ruby_log" { hardness: 2, tool: "axe", sound: "wood" }
block "ruby_leaves" { hardness: 0.2, transparent: true, sound: "grass" }
tree "ruby_tree" {
trunk: "ruby_log"
leaves: "ruby_leaves"
height: 6
height_variation: 2
leaves_radius: 2
per_chunk: 2
biomes: ["#minecraft:is_forest", "minecraft:plains"]
}| Property | Values | Default |
|---|---|---|
trunk |
the log block, from the mod or the game: "ruby_log", "minecraft:oak_log" |
— |
leaves |
the leaves block | — |
height |
trunk height, in blocks | 5 |
height_variation |
how much the height varies from tree to tree | 2 |
leaves_radius |
radius of the ball of leaves, in blocks | 2 |
per_chunk |
trees tried per chunk | 1 |
biomes |
biomes where it appears, by id or by tag | — |
Biomes are listed by id (minecraft:plains) or by tag (#minecraft:is_forest), mixed freely. Trunk and leaves can be blocks of the mod or of the game.
Plants and patches
A plant is a block drawn as two crossed images, like a flower: nothing collides with it and light goes through. Its texture is textures/block/ruby_flower.png, with a transparent background.
block "ruby_flower" { plant: true, hardness: 0 }
patch "ruby_flowers" {
block: "ruby_flower"
biomes: ["#minecraft:is_overworld"]
rarity: 4
size: 32
spread: 7
}A patch scatters plants over the world:
| Property | Values | Default |
|---|---|---|
block |
the plant block | — |
biomes |
biomes where it appears, by id or by tag | — |
rarity |
one patch every this many chunks | 4 |
size |
plants each patch tries to place | 32 |
spread |
farthest distance from the center of the patch, in blocks | 7 |
Plants are placed only in the air, on the overworld's ground (grass, dirt, moss and mud). For plants on other ground, on walls or hanging from ceilings, write a feature: see Generation by code.
Structures
A structure is a building you make yourself:
- Build it in the game.
- Save it with a structure block.
- Copy the
.nbtfile into the mod'sstructures/folder: next to the scripts in a CraftScript mod, or inassets/<mod id>/structures/in a Kotlin or Java jar.
Then declare it:
structure "ruby_shrine" {
file: "ruby_shrine"
biomes: ["#minecraft:is_overworld"]
spacing: 24
separation: 8
buried: false
}| Property | Values | Default |
|---|---|---|
file |
name of the .nbt file, without extension | the first variant, or the structure's name |
biomes |
biomes where it appears, by id or by tag | — |
spacing |
about one structure every this many chunks | 24 |
separation |
never closer than this many chunks; smaller than spacing | 8 |
buried |
true sinks it into the ground, for ruins | false |
offset_y |
blocks up from the surface it stands on; negative sinks it | 0 |
adapt_ground |
true fills the ground under it and clears it around; false places it as it is | true |
heights |
[min, max]: at a random height in this range wherever the surface is, instead of on the surface (a house in the sky) |
on the surface |
Find it with /locate structure <mod id>:ruby_shrine and place it with /place structure <mod id>:ruby_shrine.
Variants, replacements and decay
One structure can come from several files, and its blocks can change as it is placed. This makes ruins that are never quite the same:
structure "old_ruins" {
variants: [{ file: "ruins_small", weight: 3 }, "ruins_tower"]
biomes: ["#minecraft:is_forest"]
spacing: 20
separation: 6
offset_y: -2
skip: ["minecraft:air"]
replace: [{ block: "minecraft:stone_bricks", with: "minecraft:cracked_stone_bricks", chance: 0.3 }]
decay: { left: 0.8, blocks: ["minecraft:stone_bricks", "minecraft:cracked_stone_bricks"] }
}| Property | Values | Default |
|---|---|---|
variants |
files it is one of: names, or { file, weight }; one is picked at random, by weight |
just file, weight 1 |
skip |
blocks of its files that aren't placed. "minecraft:air" keeps the world's blocks where the file has air |
— |
replace |
[{ block, with, chance }]: a block of its files becomes another at that chance (more than 0, up to 1) |
chance 1 |
decay |
{ left, blocks }: only left (0–1) of blocks (ids or tags) is kept; without blocks, of any block |
all is kept |
Structures of joining pieces
A village or a dungeon is made of pieces that join: a street leads to a house, a corridor to a room. Each piece is a file with the game's jigsaw blocks in it, and each jigsaw block names the pool the next piece comes from, as <mod id>:<pool>. Declare the pools; the structure starts from the first one.
structure "hamlet" {
biomes: ["minecraft:plains"]
spacing: 34
separation: 8
depth: 6
pools: [
{ name: "hamlet/square", pieces: [{ file: "hamlet/square" }] },
{ name: "hamlet/streets", fallback: "hamlet/street_ends",
pieces: [{ file: "hamlet/street_straight", weight: 3, follows_ground: true },
{ file: "hamlet/street_corner", follows_ground: true }],
replace: [{ block: "minecraft:stone_bricks", with: "minecraft:oak_planks", where: "minecraft:water" }] },
{ name: "hamlet/street_ends", pieces: [{ file: "hamlet/street_end", follows_ground: true }] },
{ name: "hamlet/houses", none: 2,
pieces: [{ file: "hamlet/house_small", weight: 4 }, { file: "hamlet/house_big" }] },
]
}| Property | Values | Default |
|---|---|---|
pools |
the pools of pieces; the first one is where it starts | one piece, from variants or file |
depth |
how many pieces away from the first one it reaches | 1 |
Each pool has:
| Key | Values | Default |
|---|---|---|
name |
the name its jigsaw blocks use, like hamlet/streets |
— |
pieces |
[{ file, weight, follows_ground }]. follows_ground: true bends the piece to the ground under it, for streets and paths; false keeps it straight, for houses |
weight 1, false |
features |
[{ id, weight }]: a feature as a piece, yours or the game's (minecraft:chorus_plant) |
— |
none |
weight of no piece at all, for an empty plot | 0 |
fallback |
the pool used where no piece fits, such as a street's end | nothing |
skip, replace |
as for a single structure. In a pool, a replacement can add where: only where the world already has that block (a street's bricks over water become planks) |
— |
All pieces stay within 80 blocks of the first one.
Two options are only in Kotlin for now: salt, a number that picks where in its stretch of spacing chunks the structure falls (two structures with the same spacing and salt fall in the same places; without it, one is made from the structure's id), and aboveBottom, how many blocks above the world's bottom its pieces must stay (where one would reach lower, the structure isn't made).
Structures your code builds block by block are on the Generation by code page.
Biomes
A biome of your own takes a share of the places of a game biome. It keeps what grows, lives and is carved there, and brings its own climate and colors.
biome "ruby_meadow" {
replaces: "minecraft:plains"
share: 0.5
temperature: 0.8
downfall: 0.4
precipitation: true
grass_color: "#d05070"
foliage_color: "#c04060"
sky_color: "#ff9fb0"
fog_color: "#ffd0d8"
water_color: "#ff6080"
water_fog_color: "#a03050"
}| Property | Values | Default |
|---|---|---|
replaces |
the game biome whose places it takes: "minecraft:plains" |
"minecraft:plains" |
share |
fraction of those places it takes, more than 0 and up to 1 | 0.5 |
temperature |
temperature of the climate | 0.8 |
downfall |
how much it rains | 0.4 |
precipitation |
true for rain, false for none |
true |
grass_color |
grass color, #rrggbb |
the replaced biome’s |
foliage_color |
leaves color | the replaced biome’s |
sky_color |
sky color | the replaced biome’s |
fog_color |
fog color | the replaced biome’s |
water_color |
water color | #3f76e4 |
water_fog_color |
color of the fog under water | the replaced biome’s |
share is spread evenly over the places where the replaced biome would be: 0.5 takes half of them, one in every two. The new biome inherits what grows, lives and is carved there (vegetation, ores, caves, creatures, music) and whatever other mods add to that biome. Colors you leave out stay those of the replaced biome.
Several biomes can replace the same one: they share its places. Find yours with /locate biome <mod id>:ruby_meadow.
Sound, ground and creatures
A biome can also have its own music and air, cover its ground with a block of yours, and choose who lives there:
biome "glow_marsh" {
replaces: "minecraft:swamp"
share: 0.4
music: "mymod:music.marsh"
ambient_sound: "mymod:ambient.marsh_hum"
particle: { id: "minecraft:glow", chance: 0.005 }
surface: "mymod:glow_moss"
spawns: [
{ creature: "minecraft:frog", weight: 10, group: [2, 5] },
{ creature: "mymod:marsh_wisp", weight: 4, group: [1, 2] },
]
}| Property | Values | Default |
|---|---|---|
music |
a sound id, played as the biome's music | the replaced biome’s |
ambient_sound |
a sound that plays on and on there (wind, a hum) | the replaced biome’s |
particle |
{ id, chance }: a particle floating in its air; chance per spot near the player each tick (0.001 is a few) |
the replaced biome’s; chance 0.01 |
surface |
the block its ground is covered with (the top block of each floor) | the dimension's usual ground |
spawns |
[{ creature, weight, group }]: the creatures that live there; when it names any, these and no others |
the replaced biome’s; weight 10, group [1, 4] |
inherits |
false: only what is given to this biome generates there (its features, its carvers, what mods place in it), not what generates in the replaced biome |
true |
features |
[{ id, step }]: features that already exist, the game's or of data, placed in it. step is lakes, surface, ores, underground or vegetation |
— |
carvers |
ids of carvers that hollow its caves, yours or the game's; they run in the order given, before the replaced biome's | — |
With inherits: false the biome still takes the replaced biome's places, and its creatures and sounds unless you give your own; only what grows and is carved there stops coming along. A ground made block by block and carvers of your own are on the Generation by code page.
Biomes of the End
In the End, a biome takes whole regions, about 200 blocks across, instead of climate places. Replacing minecraft:end_highlands it takes all the island land of its regions (highlands, midlands and barrens); replacing minecraft:small_end_islands, the void between the islands. The central island stays the game's, and the regions are different in every world.
biome "crystal_glade" {
replaces: "minecraft:end_highlands"
share: 0.3
sky_color: "#2a1840"
fog_color: "#3c2a5a"
surface: "mymod:crystal_moss"
inherits: false
features: [{ id: "minecraft:end_gateway_return", step: "surface" }]
}Good to know
- Only new chunks. Chunks that were already generated don’t change; only chunks generated after the mod is installed get ores, trees, plants, structures and biomes. Explore new terrain to find them.
- Missing names are left out. A biome or tag in
biomesthat doesn't exist (say, another mod's that isn't installed) is skipped, not an error. - No ground, no structure. A structure that stands on the surface isn't made where its column has no ground at all, such as the void between End islands.
- Features, structures, land, biome maps, carvers and grounds written in code are on the Generation by code page.
- Whole worlds of your own are on the Dimensions page.
In Kotlin
ore("ruby_ore") {
replaces = OreHost.STONE_AND_DEEPSLATE
size = 9
perChunk = 8
minY = -60
maxY = 60
}
ore("void_ore") {
replaces = OreHost.END_STONE
biome("mymod:crystal_glade")
}
tree("ruby_tree") {
trunk = "ruby_log"
leaves = "ruby_leaves"
height = 6
perChunk = 2
biome("#minecraft:is_forest")
}
block("ruby_flower") { plant = true }
patch("ruby_flowers") {
block = "ruby_flower"
rarity = 4
biome("#minecraft:is_overworld")
}
structure("old_ruins") {
variant("ruins_small", weight = 3)
variant("ruins_tower")
biome("#minecraft:is_forest")
spacing = 20
offsetY = -2
skip("minecraft:air")
replace("minecraft:stone_bricks", "minecraft:cracked_stone_bricks", chance = 0.3)
decay(0.8, "minecraft:stone_bricks", "minecraft:cracked_stone_bricks")
salt = 120457
}
structure("hamlet") {
biome("minecraft:plains")
spacing = 34
depth = 6
pool("hamlet/square") { piece("hamlet/square") }
pool("hamlet/streets") {
piece("hamlet/street_straight", weight = 3, followsGround = true)
piece("hamlet/street_corner", followsGround = true)
fallback = "hamlet/street_ends"
replace("minecraft:stone_bricks", "minecraft:oak_planks", where = "minecraft:water")
}
pool("hamlet/street_ends") { piece("hamlet/street_end", followsGround = true) }
pool("hamlet/houses") {
piece("hamlet/house_small", weight = 4)
piece("hamlet/house_big")
none = 2
}
}
biome("glow_marsh") {
replaces = "minecraft:swamp"
share = 0.4
music = "mymod:music.marsh"
ambientSound = "mymod:ambient.marsh_hum"
particle("minecraft:glow", chance = 0.005)
surface = "mymod:glow_moss"
spawn("minecraft:frog", weight = 10, group = 2..5)
}
biome("crystal_glade") {
replaces = "minecraft:end_highlands"
share = 0.3
surface = "mymod:crystal_moss"
inherits = false
feature("minecraft:end_gateway_return", FeatureStep.SURFACE)
}