Everything that decorates the land is a feature: ore veins, trees, flowers, grass, boulders, springs, coral. If it is not the basic terrain and not a mob, it is probably a feature.
To get a feature into the world you need two files:
- A feature says what to place: a vein of ore, a tree, a single block.
- A feature rule says where and how often: which biomes, how many times per chunk, at what height.
In this guide you will make ruby ore appear underground in every overworld biome.
The files
BP/
blocks/
ruby_ore.json
features/
ruby_ore_feature.json
feature_rules/
ruby_ore_rule.jsonStep 1: the ore block
You need a block to place first. Make a normal custom block called wiki:ruby_ore with a texture and a loot table. If you have not made a block yet, follow Your first custom block.
Step 2: the feature
{
"format_version": "1.13.0",
"minecraft:ore_feature": {
"description": {
"identifier": "wiki:ruby_ore_feature"
},
"count": 6,
"replace_rules": [
{
"places_block": "wiki:ruby_ore",
"may_replace": [
"minecraft:stone",
"minecraft:granite",
"minecraft:diorite",
"minecraft:andesite"
]
}
]
}
}- The root key, here
minecraft:ore_feature, is the feature type. Each file has exactly one. The table at the bottom of this page lists them all. countis how many blocks one vein tries to place. Diamonds use small veins, coal uses big ones.replace_rulessays which block goes where. The ore only replaces blocks listed inmay_replace, so it never floats in caves or eats through dirt.
A deepslate version
Add a second entry to replace_rules with "places_block": "wiki:deepslate_ruby_ore" and "may_replace": ["minecraft:deepslate"]. One vein then uses the right look in both layers, just like vanilla ores.
Naming rules
- One feature per file.
- The file name must match the name part of the identifier.
wiki:ruby_ore_featuregoes inruby_ore_feature.json. The namespace is not part of the match. - If two packs use the exact same identifier, the pack higher in the list wins. That is how you can replace a vanilla feature.
Step 3: the feature rule
A feature does nothing until a feature rule attaches it to biomes:
{
"format_version": "1.13.0",
"minecraft:feature_rules": {
"description": {
"identifier": "wiki:ruby_ore_rule",
"places_feature": "wiki:ruby_ore_feature"
},
"conditions": {
"placement_pass": "underground_pass",
"minecraft:biome_filter": [
{
"test": "has_biome_tag",
"operator": "==",
"value": "overworld"
}
]
},
"distribution": {
"iterations": 4,
"coordinate_eval_order": "zyx",
"x": {
"distribution": "uniform",
"extent": [0, 16]
},
"y": {
"distribution": "triangle",
"extent": [-48, 16]
},
"z": {
"distribution": "uniform",
"extent": [0, 16]
}
}
}
}The rule has three parts.
description
identifiernames the rule. Like features, the name part must match the file name.places_featureis the feature this rule places. One rule controls one feature.
conditions
minecraft:biome_filter picks the biomes. It is a list of filter tests, and the one you will use almost every time is has_biome_tag. Every biome checks the filter: the ones that pass get the feature.
You can combine tests with all_of and any_of. This one picks warm overworld biomes that are not oceans:
"minecraft:biome_filter": [
{ "test": "has_biome_tag", "operator": "==", "value": "overworld" },
{
"any_of": [
{ "test": "has_biome_tag", "operator": "==", "value": "desert" },
{ "test": "has_biome_tag", "operator": "==", "value": "mesa" }
]
},
{ "test": "has_biome_tag", "operator": "!=", "value": "ocean" }
]To put ruby ore only in the Ruby Grove, test for its own tag: "value": "ruby_grove".
placement_pass says when the feature is placed compared to others. Passes run in this order:
| Pass | Good for |
|---|---|
first_pass | Things everything else should build on. |
before_underground_pass, underground_pass, after_underground_pass | Ores, blobs of dirt or gravel, cave decorations. |
before_surface_pass, surface_pass, after_surface_pass | Trees, flowers, grass, boulders. |
before_sky_pass, sky_pass, after_sky_pass | Things up in the air. |
final_pass | Last touches, after everything else. |
pregeneration_pass | Cave carvers only. |
Features in the same pass have no fixed order between them.
distribution
This decides how many copies try to generate in each chunk and where.
| Field | What it does |
|---|---|
iterations | How many times to try per chunk. Here, 4 veins. |
x, y, z | Where each try lands. A fixed number, a range, or a Molang expression. |
scatter_chance | Optional chance for the whole chunk, like { "numerator": 1, "denominator": 4 } for 1 in 4 chunks. If it fails, no tries run at all. |
coordinate_eval_order | The order the coordinates are worked out in, like "xzy" (the default) or "zyx". Matters when one coordinate uses another. |
For a feature rule, x and z count from the corner of the chunk, so [0, 16] covers the whole chunk. y is the world height.
Each range has a distribution type that shapes where values land:
| Type | Result |
|---|---|
uniform | Every value equally likely. |
triangle | Most values near the middle of the range, fewer at the ends. Great for ores. |
gaussian | Bunched around the middle, like a bell. |
inverse_gaussian | Bunched at both ends, few in the middle. |
fixed_grid | Evenly spaced steps, set with step_size and grid_offset. |
jittered_grid | A grid with each point nudged a little at random. |
For things on the ground, like plants, set y with Molang so it lands on the surface:
"y": "query.heightmap(variable.worldx, variable.worldz)"Ore only in new chunks
Features generate once, when a chunk is first made. Explore far away or make a new world to see your ore. Already-explored land never gets it.
Testing
- Turn the pack on in a new world.
- Go into spectator mode with
/gamemode spectatorand fly underground near Y 0. - Look for the ruby texture in the stone. Too rare? Raise
iterationsorcount.
If nothing appears, open the Content Log. The usual causes are a file name that does not match the identifier, a wrong places_feature name, or a block name typo in places_block.
Every feature type
Each feature file uses exactly one of these as its root key. Some place blocks, others only choose between, move or repeat other features. Most vanilla decorations chain several together: for example a scatter feature that runs a search feature that runs a tree.
| Type | What it does |
|---|---|
minecraft:aggregate_feature | Places a list of features at the same spot, in no fixed order. |
minecraft:beards_and_shavers | Builds up or cuts away terrain to make a flat, clear spot for another feature, usually a structure. |
minecraft:cave_carver_feature | Digs overworld caves through this chunk and its neighbors. Needs pregeneration_pass. |
minecraft:conditional_list | Checks a list of features in order and places the first one whose condition passes. |
minecraft:fossil_feature | Builds a buried skeleton out of bone blocks plus an ore block you choose. |
minecraft:geode_feature | Makes a round geode with layered shells and an inner filling you can swap out. |
minecraft:growing_plant_feature | Grows a plant column up from the floor or down from the ceiling, with a body and a tip, like cave vines. |
minecraft:height_difference_filter_feature | Only lets another feature place if the ground around the spot passes height checks. |
minecraft:horizontal_tree_decoration_feature | Sticks a block onto the side of something facing a random direction, like shelf mushrooms on a log. |
minecraft:multi_block_feature | Places a block that is made of several parts, optionally turned in a random direction. |
minecraft:multiface_feature | Places thin blocks that cling to floors, walls or ceilings, like glow lichen. |
minecraft:multipart_block_column_feature | Stacks a column of up to four kinds of block (base, middle, narrowing part and tip), in any direction. |
minecraft:nether_cave_carver_feature | Digs caves in the Nether. Needs pregeneration_pass. |
minecraft:ore_feature | Places a vein of blocks that only replaces the blocks you allow. Used for every ore. |
minecraft:partially_exposed_blob_feature | Places a lump of a block mostly buried in the ground, with only one side showing. |
minecraft:rect_layout | Fills a chunk's surface with a grid of areas, each holding one feature, with some space left empty. |
minecraft:scan_surface | Walks over every column of a chunk's surface and tries a feature on each. |
minecraft:scatter_feature | Places another feature many times around a spot, with the same x, y, z ranges as a feature rule. |
minecraft:sculk_patch_feature | Spreads a patch of sculk. Not documented by the game yet. |
minecraft:search_feature | Searches a box of space, layer by layer, for a spot where another feature fits. |
minecraft:sequence_feature | Places features one after another, each starting where the last one ended. |
minecraft:single_block_feature | Places one block, or one picked at random from a weighted list, with rules for what it can sit on. |
minecraft:snap_to_surface_feature | Moves the spot onto the nearest floor, ceiling or wall before placing another feature. |
minecraft:structure_template_feature | Places a saved .mcstructure from the structures folder of a behavior pack. |
minecraft:surface_relative_threshold_feature | Only places another feature if the spot is far enough below the surface. |
minecraft:tree_feature | Builds a tree from a trunk, a canopy and optional roots, with lots of shape options. |
minecraft:underwater_cave_carver_feature | Digs caves below sea level. Needs pregeneration_pass. |
minecraft:vegetation_patch_feature | Covers an area of ground with a block, then grows plants on it, like moss patches. |
minecraft:weighted_random_feature | Picks one feature from a list at random. Bigger weights get picked more often. |
Next steps
- Make a home for your ore: The biome file.
- Look up biome tags to filter on: minecraft:tags.