Developers

Data-only packs

The simplest way to add advancements to your add-on or map: item JSON files in a behaviour pack. No scripts.

Three ways to add advancements

Data-only packExternal packScript plugin
Lives inYour behaviour packYour behaviour packA folder inside BedrockAdvancements
Needs scriptingNoYesYes
DefinitionsJSON in item filesJSON, sent over script eventsJavaScript, with test functions and custom triggers
Progress fromBuilt-in triggers, tags, scoreboards, commandsBuilt-in triggers, plus events your scripts reportAnything
GuideThis pageExternal packsScript plugins

The creator makes data-only packs, so everything here is what it writes for you. Write them by hand when you want them inside your own add-on.

The JSON the creator writes for one advancement
The creator's Advanced mode shows the JSON it writes for each advancement: a good starting point.

How it works

Each definition is a hidden item in your behaviour pack with one of three custom components. When the world loads, BedrockAdvancements reads every item with these components and registers what they describe. Without BedrockAdvancements, the items load and do nothing, so your pack doesn't depend on it.

ComponentHolds
ba:tabOne tab. Fields: Tabs.
ba:advancementOne advancement and its first goal, in criterion. Fields: Advancements.
ba:criterionOne more goal for an advancement (advancement, name). Fields: Criteria.

A tab

items/tab_map.json:

{
  "format_version": "1.21.90",
  "minecraft:item": {
    "description": {
      "identifier": "treasure_hunt:tab_map",
      "menu_category": { "category": "none", "is_hidden_in_commands": true }
    },
    "components": {
      "ba:tab": {
        "format": 1,
        "id": "map",
        "title": "Treasure Hunt",
        "icon": "textures/items/map_filled",
        "background": "textures/blocks/sand"
      }
    }
  }
}

An advancement

items/adv_found_map.json, with the same wrapper and its own identifier:

"ba:advancement": {
  "format": 1,
  "id": "found_map",
  "tab": "map",
  "title": "X Marks the Spot",
  "description": "Pick up an explorer map",
  "icon": "textures/items/map_filled",
  "criterion": { "trigger": "inventory_changed", "item": "filled_map" }
}

The next one in the tree names it as its parent:

"ba:advancement": {
  "format": 1,
  "id": "dug_up", "tab": "map", "parent": "found_map",
  "title": "Dig Site", "icon": "textures/items/heartofthesea_closed", "frame": "goal",
  "criterion": { "trigger": "inventory_changed", "item": "heart_of_the_sea" },
  "rewards": { "xp": 50, "commands": ["give @s gold_ingot 3"] }
}

Several goals

Name the first goal inline, and add each of the others as its own ba:criterion item:

"ba:advancement": {
  "format": 1,
  "id": "pirate", "tab": "map", "parent": "dug_up", "title": "Pirate's Haul",
  "icon": "textures/items/emerald", "requirements": "any",
  "criterion": { "name": "diamond", "trigger": "inventory_changed", "item": "diamond" }
}
"ba:criterion": { "format": 1, "advancement": "pirate", "name": "emerald", "trigger": "inventory_changed", "item": "emerald" }

Rules to know

  • Namespace. Ids without one get the item's namespace (treasure_hunt: above). Use a namespace that's yours: two packs that define the same id replace each other's tab or advancement, and the content log warns about it.
  • Nesting limit. Bedrock refuses item components nested more than one object deep. That's why goals come one per component: write "criterion": { … }, never "criteria": { "a": { … } }. A list inside a criterion ("item": ["diamond", "emerald"]) is fine. Break the limit and the content log says Exceeded the object and array depth limit.
  • Order. Items are read in identifier order, tabs before advancements. Siblings in a tree follow that order. The creator prefixes identifiers with a number for this.
  • Hide the items with "menu_category": { "category": "none", "is_hidden_in_commands": true } so they stay out of the creative inventory and /give.
  • Format. Add "format": 1 to each component. Newer BedrockAdvancements versions keep reading older formats; an older one warns that the pack needs an update.
  • Problems (an unknown parent or tab, a criterion for a missing advancement) are logged with the item's identifier when the world loads.

Textures

Icons and backgrounds are texture paths, without .png: any vanilla texture, or your resource pack's. Ship your own textures in your resource pack and refer to them by path, like textures/my_pack/ruby_trophy.

English text for Discord

If you use lang keys for titles and descriptions, add "english": { "my.key": "My Text" } to any ba:tab or ba:advancement so Discord posts read well.

A complete example

The example data-only pack has two tabs, a tree, several goals, a locked tab and rewards. The trigger reference lists every goal type and its fields, and Map making covers driving advancements from commands.