Advancements
The complete advancement JSON format — display, criteria, all 58 triggers, requirements logic and rewards — plus the single most important datapack pattern: using an invisible advancement as a silent, self-rearming event listener.
Overview & folder
An advancement is a single JSON file at data/<namespace>/advancement/<path>.json. Its resource id is <namespace>:<path>, with subfolders folding into the path — data/foo/advancement/story/root.json becomes foo:story/root. Advancements do three jobs:
- Track player progress toward a goal (the visible Advancements GUI screen).
- Fire rewards (XP, loot, recipes, and — critically for datapacks — a function) the instant all requirements are met.
- Serve as a silent event listener for datapack logic (see Event-listener detection — the single most important trick in this document).
Only criteria is strictly required for a functional advancement; everything else is optional. A root advancement (no parent) with a valid display creates a tab.
- since 1.21 (
pack_format48, snapshot 24w21a): the folder is singularadvancement/. - before 1.21 (1.20.6 and earlier): the folder was plural
advancements/. - since 1.20.5: the icon and item predicates use
id+components— the olditem+nbtstring will fail to parse on 1.20.5+.
Root JSON schema
The top-level fields of an advancement file:
| Field | Type | Req? | Default | Notes |
|---|---|---|---|---|
parent | string (resource id) | No | — | Parent advancement. Omit → this is a root (its own tab). Circular parents fail to load. |
display | object | No | — | Visual presentation. Omit → invisible in the GUI but still functions (ideal for hidden detectors). |
criteria | object | Yes | — | Map of criterion name → trigger object. At least one required. |
requirements | array of arrays | No | one sublist per criterion (AND) | Boolean completion logic — see requirements semantics. |
rewards | object | No | — | Rewards on completion. |
sends_telemetry_event | boolean | No | false | If true, completion sends an official Mojang telemetry event. Only honored for advancements in the minecraft namespace; custom-namespace advancements ignore it. Leave false/omit for datapacks. |
A criterion is "<name>": { "trigger": "<id>", "conditions": { ... } }. The <name> is arbitrary and is what you reference in requirements[] and in advancement grant @s only <adv> <name>. conditions is trigger-specific and always optional — omit it and the trigger fires on any occurrence of that event.
data/example/advancement/detect/eat_apple.json — silent event-listener skeleton
{
"criteria": {
"ate": {
"trigger": "minecraft:consume_item",
"conditions": {
"item": { "items": ["minecraft:apple"] }
}
}
},
"rewards": {
"function": "example:on_eat_apple"
}
}
No display → invisible in the GUI, no toast, no chat spam. A pure logic hook.
The display object
Present to make the advancement visible in the GUI. Omit it entirely for silent detectors.
| Field | Type | Req? (if display) | Default | Notes |
|---|---|---|---|---|
icon | object | Yes | — | See the icon table below. |
title | text component (string/object/array) | Yes | — | Shown in the toast + GUI. |
description | text component | Yes | — | Shown in the GUI tooltip. |
frame | string enum | No | "task" | task (square), goal (rounded), challenge (spiky — plays a sound + purple toast). |
background | string (texture path) | No | — | Root-only. Tab background texture — see Tabs & backgrounds. |
show_toast | boolean | No | true | Pop-up toast on completion. Set false for silent detectors. |
announce_to_chat | boolean | No | true | Broadcasts "PlayerName has made the advancement [Title]" to chat. Set false for silent detectors. Also globally gated by the announceAdvancements gamerule. |
hidden | boolean | No | false | Hides this advancement and its children in the GUI until earned. Does not stop the toast/chat. |
The icon object
| Field | Type | Req? | Default | Notes |
|---|---|---|---|---|
id | string (item id) | Yes | — | e.g. "minecraft:diamond". |
count | integer | No | 1 | Stack size (cosmetic). |
components | object | No | — | 1.20.5+ item components (e.g. minecraft:custom_model_data, minecraft:enchantments). Replaces the old nbt string. |
- before 1.20.5: the icon used
"item"+ an"nbt"SNBT string. - since 1.20.5: the field is
"id"and extra data goes in a structured"components"object. Usingnbton 1.20.5+ will fail to parse.
data/example/advancement/root.json — full displayed root advancement
{
"display": {
"icon": { "id": "minecraft:grass_block" },
"title": { "text": "Example Pack", "color": "gold" },
"description": "The start of a custom tree",
"background": "minecraft:textures/gui/advancements/backgrounds/stone.png",
"frame": "task",
"show_toast": true,
"announce_to_chat": false,
"hidden": false
},
"criteria": {
"tick": { "trigger": "minecraft:tick" }
}
}
data/example/advancement/challenges/beat_ender_dragon.json — challenge with multiple rewards
{
"parent": "example:root",
"display": {
"icon": { "id": "minecraft:dragon_egg" },
"title": "Dragonslayer",
"description": "Defeat the Ender Dragon",
"frame": "challenge",
"show_toast": true,
"announce_to_chat": true
},
"criteria": {
"killed_dragon": {
"trigger": "minecraft:player_killed_entity",
"conditions": { "entity": { "type": "minecraft:ender_dragon" } }
}
},
"rewards": {
"experience": 500,
"loot": ["example:rewards/dragon_loot"],
"function": "example:grant_dragon_title"
}
}
The rewards object
All four fields are independent and optional; a completed advancement fires every one present, simultaneously.
| Field | Type | Notes |
|---|---|---|
experience | integer | Raw XP points (not levels). Default 0. |
recipes | array of recipe ids | Unlocks these recipes in the recipe book — see recipe-unlock advancements. |
loot | array of loot-table ids | Generates loot from each table directly into the player's inventory. |
function | string (function id) | Runs a single function as @s = the player who completed it. Function tags are NOT allowed — must be a concrete function. This is the datapack workhorse. |
Complete trigger list (58)
All 58 vanilla trigger ids, pulled verbatim from the machine-readable registry (misode/mcmeta, trigger_type/data.json, tracking snapshot 26.3-snapshot-3). Prefix each with minecraft:. Because that branch is newer than the 1.21 baseline, triggers that did not exist in 1.21.0 are flagged below the table.
| Trigger | Fires when… |
|---|---|
allay_drop_item_on_block 1.19+ | an allay drops an item onto a block near the player |
any_block_use | player uses a block (any use path — default or item-specific) |
avoid_vibration 1.19+ | player sneaks to avoid producing a vibration |
bee_nest_destroyed | player breaks a bee nest / beehive |
bred_animals | player breeds two animals |
brewed_potion | player takes a potion out of a brewing stand |
changed_dimension | player crosses between dimensions |
channeled_lightning | player triggers Channeling on a trident hit |
construct_beacon | player is near a beacon whose pyramid level changes |
consume_item | player finishes eating/drinking (or otherwise consuming) an item |
crafter_recipe_crafted 1.21+ | a Crafter block crafts a recipe near the player |
cured_zombie_villager | player cures a zombie villager |
default_block_use | player triggers a block's default interaction |
effects_changed | a status effect is added/removed on the player |
enchanted_item | player enchants an item at an enchanting table |
enter_block | player's hitbox is inside a given block/state |
entity_hurt_player | player takes damage from an entity |
entity_killed_player | an entity kills the player |
fall_after_explosion | player lands after being launched by an explosion/wind |
fall_from_height | player lands having fallen a distance / between elevations |
filled_bucket | player fills a bucket |
fishing_rod_hooked | player reels in a fishing rod with something hooked |
hero_of_the_village | a raid the player helped win ends |
impossible | never — command/reward-only marker |
inventory_changed | player's inventory contents change |
item_durability_changed | an item's durability changes |
item_used_on_block | player right-clicks a block with an item (item action) |
kill_mob_near_sculk_catalyst 1.19+ | player kills a mob near a sculk catalyst |
killed_by_arrow | player kills entities with an arrow/projectile |
levitation | player has levitation for some ticks/distance |
lightning_strike | lightning strikes near the player |
location | polled — player is at a matching location |
nether_travel | player travels then exits the Nether (measures overworld distance) |
placed_block | player places a block |
player_generates_container_loot | a loot table generates for a container the player opens |
player_hurt_entity | player deals damage to an entity |
player_interacted_with_entity | player right-clicks/interacts with an entity (with an item) |
player_killed_entity | player kills an entity |
player_sheared_equipment 1.21.x | player shears equipment off a mob |
recipe_crafted 1.20+ | player crafts a specific recipe (crafting-table result) |
recipe_unlocked | player unlocks a recipe |
ride_entity_in_lava 1.21+ | player rides an entity across lava |
shot_crossbow | player fires a crossbow |
slept_in_bed | player enters/sleeps in a bed |
slide_down_block | player slides down a block (honey/etc.) |
spear_mobs post-1.21 | player hits multiple mobs with a charged spear |
started_riding | player starts riding an entity |
summoned_entity | player summons an entity (golem, wither, etc.) |
tame_animal | player tames an animal |
target_hit | player hits a target block with a projectile |
thrown_item_picked_up_by_entity | an entity picks up an item the player threw |
thrown_item_picked_up_by_player | player picks up a thrown item |
tick | every tick, per online player |
used_ender_eye | player uses an eye of ender |
used_totem | a totem of undying saves the player |
using_item | polled while the player is holding-use on an item |
villager_trade | player completes a trade with a villager |
voluntary_exile | player causes a raid by getting Bad Omen at a village |
The table is the 26.3-snapshot registry (58 triggers); not all existed in 1.21.0. spear_mobs is a post-1.21 (26.x era) addition tied to the spear item — do not use it in a 1.21 pack. crafter_recipe_crafted arrived with the Crafter block in 1.21. ride_entity_in_lava and fall_after_explosion are Tricky-Trials-era, present by 1.21. any_block_use/default_block_use are part of the interaction-trigger refactor — if targeting exactly 1.21.0/48, verify against the wiki before relying on them; item_used_on_block is the long-stable equivalent for item-on-block.
Before shipping a version-sensitive trigger, confirm it exists in your exact pack_format by checking the registry for that version (an mcmeta version branch) or the wiki trigger's own History section. Do not assume the 26.3 list applies to 1.21.
Condition schemas
Every trigger's conditions also accepts "player": [ <predicate conditions...> ] — a list of predicate objects tested against the triggering player — except minecraft:impossible. It is omitted from the schemas below for brevity.
Most-used trigger conditions
minecraft:impossible — no conditions. Never fires on its own. Used purely as a reward/flag holder.
minecraft:tick — no conditions (beyond player). Fires every tick. Combine with a player predicate to test state continuously.
minecraft:inventory_changed
{
"items": [ { /* item predicate: matches an added item */ } ],
"slots": {
"empty": <int or {"min":_,"max":_}>,
"full": <int or range>,
"occupied": <int or range>
}
}
Each entry in items[] must match at least one item currently in the inventory.
minecraft:consume_item
{ "item": { /* item predicate for the consumed item */ } }
minecraft:location
{ "location": [ { /* location predicate: position/biome/structure/dimension/block/fluid/light/smokey */ } ] }
Polled roughly every 20 ticks. Use for "player is in biome / structure / dimension".
minecraft:player_killed_entity (also entity_killed_player, kill_mob_near_sculk_catalyst)
{
"entity": { /* entity predicate for the victim, or a list of predicate conditions */ },
"killing_blow": { /* damage-type predicate: how it died */ }
}
minecraft:item_used_on_block (right-click an item onto a block)
{
"location": [
{
"condition": "minecraft:location_check",
"predicate": { "block": { "blocks": ["minecraft:..."], "state": { } } }
}
/* plus a location predicate whose `tool` sub-field matches the item used */
],
"item": { /* item predicate for the used item (version-dependent placement) */ }
}
The block is tested via a location predicate; the held item is tested via that predicate's tool item sub-predicate (or the item field, depending on version). minecraft:placed_block uses the same location array shape, describing the placed block's state, position and the tool/item used.
minecraft:recipe_crafted
{
"recipe_id": "minecraft:...", /* required: which recipe */
"ingredients": [ { /* item predicate */ } ] /* optional: which items went in */
}
This is what powers "craft with a specific item" detection — it exposes recipe_id and per-slot ingredients.
minecraft:using_item (polled while holding right-click on an item)
{ "item": { /* item predicate; use predicates:{minecraft:custom_data:...} for custom items */ } }
minecraft:slide_down_block
{ "block": "minecraft:honey_block", "state": { "<property>": "<value>" } }
minecraft:allay_drop_item_on_block
{
"location": [ { /* location/block predicate for the drop target */ } ],
"item": { /* item predicate for the dropped item */ }
}
Sub-predicate quick reference
| Predicate | Top-level keys |
|---|---|
| Entity | entity_type (type in older names), nbt, team, location, stepping_on, movement_affected_by, distance, flags (is_baby/is_on_fire/is_sneaking/is_sprinting/is_swimming/is_flying/is_on_ground), equipment (mainhand/offhand/head/chest/legs/feet/body), slots, effects, vehicle, passenger, targeted_entity, movement, periodic_tick, predicates (data-component predicates), type_specific (variants: player, fishing_hook, lightning, raider, sheep, …). |
| Item | items (id list or #tag), count (range), components (exact component match), predicates (partial/sub-predicate match — e.g. minecraft:custom_data, minecraft:enchantments, minecraft:damage). custom_data is the standard way to tag a custom item for detection. |
| Location | position (x/y/z ranges), biomes, structures, dimension, block (blocks + state + nbt), fluid, light, can_see_sky, smokey, tool (item predicate for the held item — used by block-interaction triggers). |
- since 1.20.5: item predicates match with
id-style component data — usecomponentsfor exact matches andpredicates(e.g.minecraft:custom_data) for partial matches. - before 1.20.5: item predicates used
item+ annbtSNBT string. - in 1.15 and earlier: the field names for
entity/itempredicates and the criteria/requirements format differed; everything here assumes the modern (1.16+) predicate format.
requirements AND/OR logic
requirements is an array of arrays of criterion names. The completion rule:
The advancement is granted when every sublist has at least one completed criterion. The outer array is joined by AND (all sublists must be satisfied); each inner array is joined by OR (any one criterion in it satisfies that sublist).
If requirements is omitted, the default is one sublist per criterion → all criteria must be met (pure AND).
Pure AND (default, written explicitly)
"criteria": { "a": {...}, "b": {...}, "c": {...} },
"requirements": [ ["a"], ["b"], ["c"] ]
Pure OR — "any one of N"
"criteria": { "a": {...}, "b": {...}, "c": {...} },
"requirements": [ ["a", "b", "c"] ]
Completing a or b or c grants it — the canonical "detect one of several items/events" form.
Mixed — (a OR b) AND c
"requirements": [ ["a", "b"], ["c"] ]
- Every criterion listed in
criteriashould appear somewhere inrequirements; a criterion omitted fromrequirementscan never contribute to completion. - An empty inner list
[]can never be satisfied → the advancement becomes command-only. - Criterion names in
requirementsmust exactly match keys incriteria, or the pack fails validation.
Event-listener detection pattern
Advancements are the cleanest event listeners in vanilla datapacks. The loop:
- Write an advancement whose criterion is the event you want (
consume_item,player_killed_entity,using_item,item_used_on_block, …), with nodisplayso it is invisible/silent. - Give it a
rewards.functionthat runs your logic as@s(the player). - Inside that function, revoke the advancement from that player so it can fire again:
advancement revoke @s only <namespace>:<path>.
Because the reward function runs with @s = the completing player and revocation re-arms the listener, this yields reliable, per-player, single-execution event handling with no per-tick scanning — far cheaper and more precise than polling scoreboards for most discrete events.
- since 1.20.5: making a custom item "consumable"/"usable" so
consume_itemorusing_itemfires is done via item components (minecraft:consumable,minecraft:food). - before 1.20.5: the same was done through NBT.
Detect eating a custom golden apple
data/mypack/advancement/detect/ate_special.json
{
"criteria": {
"ate": {
"trigger": "minecraft:consume_item",
"conditions": {
"item": {
"items": ["minecraft:golden_apple"],
"predicates": { "minecraft:custom_data": "{special:true}" }
}
}
}
},
"rewards": { "function": "mypack:on_ate_special" }
}
data/mypack/function/on_ate_special.mcfunction
# @s is the player who just ate the item
effect give @s minecraft:regeneration 10 2
playsound minecraft:entity.player.levelup player @s
# re-arm the listener so it can fire again next time
advancement revoke @s only mypack:detect/ate_special
Right-click detection via item_used_on_block
Detect right-clicking a custom wand on any block:
data/mypack/advancement/detect/wand_use.json
{
"criteria": {
"used": {
"trigger": "minecraft:item_used_on_block",
"conditions": {
"item": { "predicates": { "minecraft:custom_data": "{wand:true}" } }
}
}
},
"rewards": { "function": "mypack:on_wand_use" }
}
data/mypack/function/on_wand_use.mcfunction
execute at @s anchored eyes run particle minecraft:end_rod ^ ^ ^2 0 0 0 0 1
advancement revoke @s only mypack:detect/wand_use
item_used_on_block only fires when clicking a block. To detect a right-click in air or on entities, use using_item (needs a consumable/usable component) or the classic carrot-on-a-stick statistic method below.
Mob-kill counter
data/mypack/advancement/detect/killed_zombie.json
{
"criteria": {
"kill": {
"trigger": "minecraft:player_killed_entity",
"conditions": { "entity": { "type": "minecraft:zombie" } }
}
},
"rewards": { "function": "mypack:count_zombie_kill" }
}
data/mypack/function/count_zombie_kill.mcfunction
scoreboard players add @s zombie_kills 1
advancement revoke @s only mypack:detect/killed_zombie
execute if score @s zombie_kills matches 100.. run function mypack:reward_100_kills
Detection cookbook
| Goal | Approach |
|---|---|
| Consume detection (food/potions) | consume_item + custom_data item predicate + revoke. Best for anything with a use-consume animation. |
| Right-click a block | item_used_on_block. |
| Right-click anywhere (air/entity) | (a) give the item a minecraft:consumable component and use using_item; or (b) the carrot-on-a-stick / warped-fungus-on-a-stick trick — a scoreboard with criterion minecraft.used:minecraft.carrot_on_a_stick, a per-tick check, then reset the score. COAS registers a use every ~4 ticks while held; use custom_data to distinguish your item. |
| Kill counters / boss logic | player_killed_entity + revoke. |
| Continuous state | a displayless tick advancement with a player predicate fires every tick while the condition holds; pair its function with revoke for edge-detection, or gate inside the function. |
An advancement whose only criterion is minecraft:impossible can only be granted by command (advancement grant), making it a clean, persistent per-player boolean flag readable via advancement / execute if against entity data.
Silence is mandatory for detectors: omit display entirely (no toast, no chat, no GUI clutter). If you do need a display on a detector, set show_toast: false and announce_to_chat: false.
Recipe-unlock advancements
Recipes appear in the player's recipe book only once unlocked. Two mechanisms:
- Automatic discovery — obtaining any item that is an ingredient (or the result) of a recipe auto-unlocks it. This is driven by auto-generated advancements under the
minecraft:recipes/...id space. rewards.recipeson an advancement — completing an advancement unlocks the listed recipes. This is exactly how vanilla'sminecraft:recipes/<category>/<name>advancements work: each is a hidden advancement whose criteria (inventory_changed,recipe_unlocked, …) detect "player has an ingredient", and whose reward is"recipes": ["minecraft:<recipe>"].
data/minecraft/advancement/recipes/misc/example.json — auto-generated recipe advancement shape
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_ingredient": {
"trigger": "minecraft:inventory_changed",
"conditions": { "items": [ { "items": ["minecraft:paper"] } ] }
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": { "recipe": "minecraft:example" }
}
},
"requirements": [ ["has_ingredient", "has_the_recipe"] ],
"rewards": { "recipes": ["minecraft:example"] }
}
Note the no display (recipe advancements are invisible) and the OR requirement — it grants the moment either the ingredient is obtained or the recipe is otherwise unlocked.
To unlock recipes from any advancement, add to its rewards:
"rewards": { "recipes": ["mypack:secret_sword", "mypack:secret_shield"] }
Suppressing the recipe-unlock toast
The "recipe unlocked!" pop-up is controlled on the recipe side, not the advancement side: set "show_notification": false in the recipe JSON.
data/mypack/recipe/secret_sword.json
{
"type": "minecraft:crafting_shaped",
"group": "swords",
"show_notification": false,
"pattern": ["#", "#", "/"],
"key": { "#": "minecraft:netherite_ingot", "/": "minecraft:stick" },
"result": { "id": "minecraft:netherite_sword" }
}
- since 1.20 (snapshot 23w07a):
show_notificationexists and defaults totrue. Setting itfalseunlocks the recipe silently — the standard way to add recipes to the book without a toast. - the
groupfield merges related recipes in the book display.
- To grant a recipe immediately at world join with no toast, pair
"show_notification": falseon the recipe with a hidden advancement that has aninventory_changed/tickcriterion andrewards.recipes. - Give recipes with related outputs the same
groupto collapse them in the recipe book. - Recipe advancements are the one legitimate large-volume use of
rewards.recipes; don't hand-roll discovery logic with functions unless you need conditional gating.
Tabs, roots & backgrounds
Any advancement without a parent and with a valid display becomes a tab in the Advancements GUI. Child advancements (those with parent) render inside their root's tab. The game auto-arranges children into columns, drawing connector arrows to the nearest visible ancestor. A custom tree therefore needs exactly one root per tab.
data/mypack/advancement/root.json — the tab
{
"display": {
"icon": { "id": "minecraft:nether_star" },
"title": "My Pack",
"description": "Custom challenges",
"background": "minecraft:textures/gui/advancements/backgrounds/adventure.png",
"show_toast": false,
"announce_to_chat": false
},
"criteria": { "auto": { "trigger": "minecraft:tick" } }
}
data/mypack/advancement/step_one.json — a child
{
"parent": "mypack:root",
"display": {
"icon": { "id": "minecraft:iron_pickaxe" },
"title": "Getting Started",
"description": "Mine some iron",
"frame": "task"
},
"criteria": {
"iron": {
"trigger": "minecraft:inventory_changed",
"conditions": { "items": [ { "items": ["minecraft:iron_ingot"] } ] }
}
}
}
Background textures
background is a texture resource path (relative to assets, including the .png). Vanilla tab backgrounds live at minecraft:textures/gui/advancements/backgrounds/:
| Value | Look |
|---|---|
minecraft:textures/gui/advancements/backgrounds/stone.png | Stone |
minecraft:textures/gui/advancements/backgrounds/gravel.png | Gravel |
.../backgrounds/dirt.png | Dirt |
.../backgrounds/end.png | End stone |
.../backgrounds/nether.png | Netherrack |
.../backgrounds/adventure.png | Stone bricks |
.../backgrounds/husbandry.png | Hay/farmland |
To use a custom background, ship it in a resource pack at assets/mypack/textures/gui/advancements/backgrounds/mytab.png and reference "background": "mypack:textures/gui/advancements/backgrounds/mytab.png". The texture tiles across the tab; use a seamless 16×16 (or larger) tileable image.
background is honored on root advancements only; setting it on a child is ignored. The path format (namespaced, full textures/...png) has been stable across 1.16 → 1.21 — only the folder rename to singular advancement/ affects path layout.
- since 1.21 (
pack_format48, snapshot 24w21a): datapack directories were renamed to singular —advancements→advancement,recipes→recipe,loot_tables→loot_table,predicates→predicate,functions→function,item_modifiers→item_modifier,structures→structure,tags/functions→tags/function. - before 1.21 (1.20.6 and earlier): use the plural
advancements/. A pack targeting both must ship overlays or duplicate trees perpack_format.
- One root per logical tab; keep tab count small — many roots make a cluttered tab bar.
- For pure-logic packs, never give detectors a
display— keep the GUI clean and reserve visible advancements for actual player-facing goals. - Titles/descriptions are full text components — use
translatekeys for localization. - Test the tree with
/advancement grant @s everythingand/advancement revoke @s everythingduring development.
Sources
- Advancement JSON format (schema) — minecraft.wiki
- Advancement definition (schema, triggers, requirements semantics) — minecraft.wiki
- Advancement (GUI concepts, tabs) — minecraft.wiki
- Trigger registry (verbatim, 26.3-snapshot-3) — misode/mcmeta
- mcmeta version pin (version.json, data_pack_version 110)
- Entity predicate — minecraft.wiki
- Data pack (folder rename to singular, 24w21a / pack_format 48) — minecraft.wiki
- Recipe (Java Edition) — show_notification, group, recipe unlocking — minecraft.wiki
- Advancement-based item / right-click detection pattern — MCC wiki
- Carrot-on-a-stick right-click detection — datapack.wiki
- Misode advancement generator (field/UI reference)