An empty entry is a chance to roll nothing.
{
"type": "minecraft:chest",
"pools": [
{
"rolls": {
"type": "minecraft:uniform",
"min": 2,
"max": 4
},
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:gold_ingot",
"weight": 20,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1,
"max": 5
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 5,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1,
"max": 2
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:enchanted_book",
"weight": 8,
"functions": [
{
"function": "minecraft:enchant_with_levels",
"levels": {
"type": "minecraft:uniform",
"min": 0,
"max": 1
}
}
]
},
{
"type": "minecraft:empty",
"weight": 12
}
]
}
]
}Save it as data/<namespace>/loot_table/custom_table.json in your datapack.
No problems found. This table is ready to drop into a datapack.
Averages from rolls times weight share times set_count and chance conditions. Match-tool and weather conditions are treated as always met since they depend on how the table is triggered.
A loot table is the JSON that decides what a chest, mob, block, or the /loot command drops. This builder lets you assemble one visually: stack pools, give each entry a weight, attach functions like set_count and enchant, gate drops with conditions, and copy or download valid JSON straight into your datapack. The drop odds update as you type.
Writing a Minecraft loot table by hand means juggling nested pools, number providers, function lists, and condition arrays, with field names that have changed across versions. The editor above keeps the structure correct for you and emits the modern schema. You can also load any vanilla table as a starting point, tweak it, and export your own copy.
Every part of the loot table format is here: pool rolls (constant, uniform, or binomial), entries (item, item tag, loot table reference, alternatives, or empty), functions (set count, enchant randomly, enchant with levels, set damage, and Looting bonus), and conditions (killed by player, random chance, Looting-scaled chance, match tool, and weather).
1. Pick a table type. Chest, entity, block, fishing, gift, and so on. The type tells the game what the table is for and how it is rolled. Choose generic to leave the type out entirely.
2. Set the rolls on each pool. A pool with rolls 1 drops one entry. Uniform 2 to 4 drops two to four. Add a second pool when you want guaranteed plus random loot, the way vanilla chests mix a key item pool with a filler pool.
3. Add entries and weights. Each entry is an item, a tag, another loot table, an alternatives group, or empty. Heavier weights are picked more often. Add an empty entry to build in a chance of nothing.
4. Attach functions and conditions. Use set_count for stack sizes, enchant for gear, and the Looting bonus for mob drops. Conditions decide whether an entry or whole pool is eligible, for example only when killed by a player.
5. Copy or download the JSON. The output updates live and the validation panel flags anything broken. Save the file under data/<namespace>/loot_table/ in your datapack.
Here is what each piece of the format does and where it sits in the structure:
| Part | What it does |
|---|---|
| pool | A group of entries that is rolled together. A table can have several pools, and each one drops independently. |
| rolls | How many entries the pool picks. A number provider: constant, uniform (a min and max range), or binomial (n trials at probability p). |
| entry | One candidate drop. Type item, tag, loot_table, alternatives, or empty. Carries a weight, optional functions, and optional conditions. |
| weight | Relative chance of being picked within the pool. An entry is picked weight divided by total weight of the time. |
| functions | Modify the chosen item: set_count, enchant_with_levels, enchant_randomly, set_damage, and enchanted_count_increase (the Looting bonus). |
| conditions | Gate an entry or pool: killed_by_player, random_chance, random_chance_with_enchanted_bonus, match_tool, and weather_check. All conditions in a list must pass. |
The alternatives entry is how vanilla handles Silk Touch on ores: the first child whose conditions pass is the one that drops, so a Silk Touch branch comes before the normal drop branch. Load blocks/diamond_ore in the importer above to see that pattern.
Two pools for chests. Vanilla chest tables usually split into one pool for the headline loot (with a high uniform roll) and another for common filler. Copy that shape: put rare items at low weight in a pool with rolls of one, and bulk resources in a second pool.
Mob drops and Looting. For an entity table, add the killed_by_player condition to gear or rare drops so they only appear on player kills, and add the Looting bonus function so the amount scales with the Looting enchantment, exactly how zombies drop iron and carrots.
Reading the odds panel. The expected-drops panel multiplies rolls by weight share by the average set_count and any chance conditions. It is the average over many drops, so a 5 percent entry that drops a stack still reads as a small fraction per drop. Match-tool and weather conditions are counted as always met because they depend on how the table is triggered, not on chance.
Build the table in the editor above by adding pools, then entries (items, tags, or table references) with weights, then download the JSON. Place the file at data/<namespace>/loot_table/<name>.json inside a datapack, and reference it from a chest, /loot, or a block or mob you have overridden.
They live in data/<namespace>/loot_table/ in your datapack. In 1.20 and earlier the folder is loot_tables (plural). The path under loot_table becomes the table id, so data/mypack/loot_table/treasure.json is mypack:treasure, and you can nest folders like chests/dungeon.json.
Rolls is how many times the pool picks an entry. A constant of 1 picks once. A uniform of 2 to 4 picks 2, 3, or 4 times at random. A binomial uses n trials at probability p. Each roll independently picks one entry by weight, so higher rolls means more total drops.
Each entry has a weight (default 1). The chance an entry is picked on a roll is its weight divided by the total weight of all entries in the pool. An empty entry with weight gives a chance of rolling nothing. The odds panel above shows the exact percentage for every entry as you edit.
Add the Looting bonus function (enchanted_count_increase) to an item entry and set the enchantment to minecraft:looting. It adds extra items per Looting level. For drops that only appear with Looting, use the random chance with Looting bonus condition instead.
Run /reload after editing the datapack, then use /loot give @s loot <namespace>:<table> to drop it to yourself, or /loot spawn ~ ~ ~ loot <table> to spawn it at a position. The /loot command is the fastest way to confirm a table works before attaching it to a chest or mob.
Browse more Minecraft tools: