Wiki 9Minecraft Wiki 9Minecraft

Loot Tables Reference

Define randomized item drops for mobs, blocks, chests, and gameplay events.

5Sections
3Code examples
3Known errors

Loot tables are JSON files in a behavior pack that determine what items generate or drop when a specific event happens. You use them whenever a custom mob dies, a custom block is broken, a structure chest is opened, or a vanilla drop needs to be replaced. Instead of hardcoding a single item output, a loot table lets you group items into weighted pools, apply conditions like requiring a player kill, and run functions to randomize stack counts or enchantments.

File Location and Basic Structure

All loot tables live inside the `loot_tables` folder of your behavior pack. Unlike entity or block definitions, loot tables do not have a `format_version` key or an identifier block at the top of the file. Instead, the game references them directly by their file path relative to the behavior pack root, always starting with `loot_tables/` and ending with `.json`.

To override a vanilla drop, place a file at the exact same relative path the base game uses, such as `BP/loot_tables/entities/zombie.json`. For custom content, create a subfolder named after your project inside `BP/loot_tables/` to keep your files organized and avoid collisions with other packs.

At its root, a loot table JSON contains a single `pools` array. Each object inside `pools` represents an independent group of rolls. When the game evaluates the table, it processes every pool in the list from top to bottom.

BP/loot_tables/entities/custom_goblin.json
{
  "pools": [
    {
      "rolls": 1,
      "entries": [
        {
          "type": "item",
          "name": "minecraft:gold_nugget",
          "weight": 3,
          "functions": [
            {
              "function": "set_count",
              "count": {
                "min": 1,
                "max": 4
              }
            }
          ]
        },
        {
          "type": "item",
          "name": "minecraft:emerald",
          "weight": 1
        },
        {
          "type": "empty",
          "weight": 2
        }
      ]
    }
  ]
}

Pools, Rolls, and Entries

A pool controls how many times the game picks from a specific list of items. The `rolls` property sets the number of draws; it can be a fixed integer (like `1`) or an object with `min` and `max` integers for a random range. If you want a mob to always drop bones AND have a separate chance to drop a rare weapon, you create two separate pools in the same file.

Inside a pool, the `entries` array holds the possible outcomes for each roll. Every entry needs a `type`. The most common is `"item"`, which requires a `name` field set to a valid item identifier. You can also use `"empty"` to add a chance that a roll drops nothing at all, or `"loot_table"` to point `name` at another loot table file path, allowing you to share sub-tables across multiple mobs.

When a pool has multiple entries, the `weight` integer determines how likely each entry is to be chosen on any given roll. The game adds up the weights of all eligible entries in that pool, and an entry's chance is its own weight divided by the total. In the example above, the total weight is 6 (3 + 1 + 2), giving gold nuggets a 3 in 6 chance, emeralds a 1 in 6 chance, and nothing a 2 in 6 chance.

Modifying Drops with Functions

Entries by themselves only drop a single, unmodified item. To change stack sizes, apply durability damage, add enchantments, or set custom names, you attach a `functions` array to the item entry. Functions run in order after the item entry is selected by a roll.

Function NameWhat it doesNotes
set_countSets the stack size of the dropped item.Takes a `count` field as an integer or a `{"min": x, "max": y}` object.
looting_enchantIncreases stack count based on the killer's Looting level.Uses a `count` object with `min` and `max` added per level of Looting.
set_damageSets remaining durability on tools and armor.Uses a `damage` float from 0.0 (broken) to 1.0 (full durability) in Bedrock.
enchant_with_levelsEnchants the item as if using an enchanting table.Uses `levels` (`min`/`max`) and a boolean `treasure` flag.
enchant_randomlyApplies one random compatible enchantment to the item.Accepts an optional `treasure` boolean to allow treasure enchantments.
set_nameApplies a custom display name to the item.Uses the `name` string field; supports standard formatting codes.
set_loreAdds lore text lines underneath the item name.Uses a `lore` array of strings.
set_dataSets the data value on older aux-value items.Rarely used for modern items, which use distinct identifiers instead.

Filtering with Conditions

A `conditions` array can be placed on an entire pool or on an individual entry. All conditions in the array must pass for the pool to roll or the entry to be included in the selection pool. This is how vanilla mobs restrict rare drops to player kills or adjust drop rates based on difficulty.

The `killed_by_player` condition takes no extra parameters and ensures traps or fall damage cannot farm the drop. For simple percentage chances where weights feel clumsy, `random_chance` takes a `chance` float between `0.0` and `1.0`. If you want Looting to improve that flat chance, `random_chance_with_looting` adds a `looting_multiplier` float that is added to `chance` for each level of the enchantment.

BP/loot_tables/entities/rare_boss_drop.json
{
  "pools": [
    {
      "rolls": 1,
      "conditions": [
        {
          "condition": "killed_by_player"
        },
        {
          "condition": "random_chance_with_looting",
          "chance": 0.1,
          "looting_multiplier": 0.05
        }
      ],
      "entries": [
        {
          "type": "item",
          "name": "minecraft:diamond_sword",
          "functions": [
            {
              "function": "enchant_with_levels",
              "treasure": true,
              "levels": {
                "min": 20,
                "max": 30
              }
            }
          ]
        }
      ]
    }
  ]
}

Connecting Loot Tables to Entities and Blocks

A loot table does nothing until something references it. In an entity behavior file, add the `minecraft:loot` component inside `components` or a component group, and set its `table` property to your file path. In a block behavior file, use the `minecraft:loot` component as a simple string value pointing to the table path.

You can also trigger a loot table directly during gameplay using commands or scripts. The `/loot` command allows you to spawn drops in the world or insert them directly into a player's inventory or container using `/loot spawn` or `/loot give`.

BP/blocks/cracked_crate.json
{
  "format_version": "1.20.80",
  "minecraft:block": {
    "description": {
      "identifier": "custom:cracked_crate"
    },
    "components": {
      "minecraft:destructible_by_mining": {
        "seconds_to_destroy": 1.5
      },
      "minecraft:loot": "loot_tables/blocks/cracked_crate_drops.json"
    }
  }
}

Which versions this applies to

Stable in all current Bedrock versions (1.16.0 through 1.21+). No experimental toggles are required for loot tables or the `minecraft:loot` component.

When it does not work

What you seeWhyThe fix
Mob or block drops nothing at all, and Content Log shows a JSON parse error or missing file warning for the loot table.The path inside the `minecraft:loot` component is missing the `loot_tables/` prefix, omits the `.json` extension, or uses backslashes (`\`) instead of forward slashes (`/`).Ensure the path starts from the behavior pack root and uses forward slashes, for example: `"loot_tables/entities/my_mob.json"`.
One pool drops items as expected, but another pool in the same file never drops anything.An item identifier inside `entries` is misspelled or missing its namespace, or a condition on the pool (such as `killed_by_player` when testing with `/kill`) is evaluating to false.Check the Content Log for `Failed to find item` warnings, verify all custom items use their exact `namespace:name`, and test mob drops with a sword rather than `/kill` if conditions are present.
A custom block drops a single copy of itself instead of running your custom loot table.The `minecraft:loot` component was placed inside `description` instead of `components`, or formatted as an object `{"table": "..."}` on a modern block version that expects a direct string.Move `minecraft:loot` into the `components` block of your block JSON and assign the path directly as a string value.

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.