Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 34 — Project: A Complete Content Pack

What You’ll Build

This is the chapter where everything comes together. Across the last thirty-two chapters you learned the pieces one at a time: components, recipes, loot tables, advancements, models, sounds. Now you’ll put them in one box.

By the end you’ll have a complete content pack of your own: a data pack and a resource pack, shipped as a pair, under one shared name. The theme is Emberforge, a fire-and-forge treasure set. You’ll plan it on paper first, then build three custom items (a glowing Ember Blade, a fast Forgemaster’s Hammer, and an edible Molten Bun), write the recipes that craft them, make a cache loot table that drops them in a chest, build a small advancement tree that guides the player from “you made your first Emberforge item” to “you opened the cache,” and finish with a custom sound that plays at the big moment. Then you’ll test the whole thing, end to end.

Two new ideas only: a content pack (data pack + resource pack as one project) and a design document (a short written plan you make before you build). Everything else is something you already know, used together for the first time.

Content pack. A content pack is a data pack and a resource pack shipped together as one project, so the behavior (the data files) and the look-and-sound (the asset files) arrive as a unit. The two halves are separate things (a data pack is “a collection of data used to configure a number of features,” and a resource pack carries the textures, models and sounds), but a player downloading your work just wants both at once. This chapter builds both.

Figure (to be captured). the finished pack in action — a chest spilling glowing Ember Blades, the advancement toast popping, a forge-themed background

Plan First: The Design Document

Every chapter so far handed you the plan. This time you make it. Before you create a single folder, write a design document: a short, plain plan of what you’re building. It’s a few lines in a text file (or on paper) that answer five questions, no JSON and no code. Doing this first is the single biggest favor you can do yourself, because it turns “I’ll add some cool items” into a finite, finishable list.

Design document. A short written plan made before building: the theme, the list of items, what each item does, where the player finds them, and how they’re obtained. No code, just decisions, so you know when you’re done.

Here is the design document for this project. Yours, for your own pack, will look different. That’s the point.

EMBERFORGE — design document

Theme:     A fire/forge treasure set left behind by a master smith.
Namespace: emberforge   (both packs share this name)

Items:
  1. Ember Blade        — a sword that glows; sharp; "rare" coloring.
  2. Forgemaster's Hammer — a pickaxe that mines fast; bonus attack damage.
  3. Molten Bun         — a food item; restores hunger; quick to eat.

Where found: a forge "cache" chest (a structure — Part XI). For now we ship the
             chest's LOOT TABLE and test it directly.

How obtained: each item is craftable (a recipe), AND drops from the cache chest.

Guiding path (advancements):
  root   "Apprentice"  — get any Emberforge item
  child  "Swordsmith"  — hold the Ember Blade
  hidden "Cache Opener" — get the cache marker; plays a forge sound

Polish: one custom sound, emberforge:cache_open, at the final advancement.

That fits on a screen, and it tells you exactly when the pack is finished: three items, three recipes, one loot table, three advancements, one sound. We’ll build it in that order.

The Project Skeleton

A content pack is two folders sitting next to each other. Each is its own pack with its own marker file: a data pack “is either a folder or a .zip file containing a pack.mcmeta file,” and a resource pack has its own pack.mcmeta and an assets/ folder instead of data/. So your project root holds two folders:

emberforge/                 <- the DATA pack  (behavior; has data/)
emberforge_resources/       <- the RESOURCE pack (look & sound; has assets/)

Both use the same namespace, emberforge, so every path in either pack reads .../emberforge/.... That’s a project namespace: one name shared by both halves, which keeps your items, models and data files lined up. (The reader’s earlier mypack/myassets project did the same thing: same namespace inside, different folder names outside. Here we start a clean project of its own so you practice building one from nothing.)

Project namespace. The single namespace shared by both packs (emberforge). A namespace exists “to avoid files from different packs unintentionally interfering with each other”; sharing one name within your own project is what keeps a data file and its matching asset pointing at each other.

The two marker files

Both packs need a pack.mcmeta. You built one of each back in Chapters 9 and 28, and they use the same min_format/max_format version mechanism. Here they are for this project.

emberforge/pack.mcmeta

{
  "pack": {
    "description": "Emberforge — a forge-master's treasure set (data)",
    "min_format": 107,
    "max_format": 107
  }
}

emberforge_resources/pack.mcmeta

{
  "pack": {
    "description": "Emberforge — a forge-master's treasure set (assets)",
    "min_format": 88,
    "max_format": 88
  }
}

Modern Minecraft. Older tutorials write a single pack_format number. As you learned in Chapter 9, current Minecraft uses min_format/max_format — here 107 for the data pack and 88 for the resource pack, because the two registries keep separate format numbers (Chapters 9 and 28, both values for Minecraft 26.2). Leave the legacy pack_format field out of a new-only pack.

The load announcer

Give the pack a heartbeat: a load function that announces itself, wired through the minecraft:load function tag exactly as in Chapter 9, just in the new namespace.

emberforge/data/emberforge/function/load.mcfunction

# Emberforge content pack — runs on load/reload
say [Emberforge] forge fires lit. Pack loaded.

emberforge/data/minecraft/tags/function/load.json

{
  "values": [
    "emberforge:load"
  ]
}

Reload, and you should see the announcement. That’s your skeleton breathing.

Figure (to be captured). chat showing “[Emberforge] forge fires lit. Pack loaded.” after /reload

The Themed Items

The heart of the pack is three custom items. You already know how to build a custom item: it’s an item ID plus a bag of data components (Chapter 21), written in the bracket form item_id[component=value, ...]. We’ll define each item once, as a /give, inside a make_items function so you can summon all three for testing with one call. Then we’ll point each one at a custom model.

Item 1 — the Ember Blade

A golden sword that glows, named and colored to feel special, pre-sharpened, and aimed at a custom model. The components are all ones you met in Chapters 22–24:

  • custom_name — the hover name (a text component, Chapter 5/21).
  • lore — description lines (Chapter 22).
  • rarity"rare", which tints the name (Chapter 22).
  • enchantments — applied enchantments (Chapter 24).
  • item_model — points at the model definition in the resource pack (Chapter 22/28).

Item 2 — the Forgemaster’s Hammer

A pickaxe that mines quickly and hits a little harder. It uses functional components from Chapter 23:

  • tool — the mining-rule component (here we keep the default behavior and lean on attributes for the “fast” feel; full tool rules were covered in Chapter 23).
  • attribute_modifiers — a stat bonus (Chapter 23).
  • item_model — its custom look.

Item 3 — the Molten Bun

A quick snack, using the food components from Chapter 23:

  • food — nutrition and saturation.
  • consumable — how it’s eaten.
  • item_model — its look.

Here’s the function that gives all three to yourself:

emberforge/data/emberforge/function/make_items.mcfunction

# Emberforge — give the three themed items to the nearest player (for testing)

# 1. Ember Blade — glowing, sharp, "rare" sword
give @p minecraft:golden_sword[custom_name={text:"Ember Blade",color:"gold"},lore=[{text:"Forged in the first fire.",color:"dark_red"}],rarity="rare",enchantments={"minecraft:sharpness":3},item_model="emberforge:ember_blade"]

# 2. Forgemaster's Hammer — fast pickaxe, harder hits
give @p minecraft:golden_pickaxe[custom_name={text:"Forgemaster's Hammer",color:"gold"},lore=[{text:"Heavy as a falling anvil.",color:"gray"}],rarity="rare",attribute_modifiers=[{type:"minecraft:attack_damage",amount:3,operation:"add_value",slot:"mainhand",id:"emberforge:hammer_damage"}],item_model="emberforge:forgemasters_hammer"]

# 3. Molten Bun — quick food
give @p minecraft:bread[custom_name={text:"Molten Bun",color:"gold"},lore=[{text:"Still warm.",color:"red"}],food={nutrition:6,saturation:7.2},consumable={consume_seconds:0.8},item_model="emberforge:molten_bun"]

Run function emberforge:make_items and the three items appear in your inventory. They have their names, colors and behavior already, but they’ll show their base item picture (a golden sword, a golden pickaxe, bread) until we give them models. That’s the next step.

Under the Hood. Notice each give line is one long item argument. Components are separated by commas, each is component=value (an =, not a :, between the name and its value, Chapter 21), and the values are SNBT — including the names and lore, which are plain SNBT text components ({text:...,color:...}), the same shape you learned in Chapter 22. If a line errors, the game points at the spot. Read it the way you practiced in Chapter 10.

Giving the items a custom look

The item_model component on each item is a pointer (Chapter 22): item_model="emberforge:ember_blade" tells the game to read the item model definition at assets/emberforge/items/ember_blade.json. You built exactly these definition files in Chapter 29. Here we keep them at their simplest (one model, one texture) because the assembly, not the modeling, is the lesson. Each definition is the minimal type: minecraft:model form from Chapter 29:

emberforge_resources/assets/emberforge/items/ember_blade.json

{
  "model": {
    "type": "minecraft:model",
    "model": "emberforge:item/ember_blade"
  }
}

emberforge_resources/assets/emberforge/items/forgemasters_hammer.json

{
  "model": {
    "type": "minecraft:model",
    "model": "emberforge:item/forgemasters_hammer"
  }
}

emberforge_resources/assets/emberforge/items/molten_bun.json

{
  "model": {
    "type": "minecraft:model",
    "model": "emberforge:item/molten_bun"
  }
}

Each model field names a shape file in assets/emberforge/models/item/ that wears a texture in assets/emberforge/textures/item/: the three-folder chain you built in Chapter 29. We won’t reprint the shape and texture files here (that’s Chapter 29’s job); make a small PNG and a one-line model file for each, exactly as you did for the flame sword, and your items will wear their own art.

Try It! Want the Ember Blade to glow only when it carries an enchantment, like the flame sword in Chapter 29? Swap its items/ember_blade.json for a minecraft:condition definition on the enchantment glint. The recipe in this chapter already adds Sharpness, so it’ll glow by default, but the conditional version is a nice touch if you make an unenchanted variant.

Recipes to Craft Them

Right now the only way to get an Emberforge item is the make_items cheat. Let’s make them craftable. You wrote recipes in Chapter 15; the key idea here is that a recipe’s result can carry its own components, so the crafted item comes out already customized: the same component bag as the give above, just attached to the recipe’s result.

The result field is id (not the legacy item), and components is optional extra data on the result. Here are the three recipes.

The Ember Blade is a shaped recipe, two ember-ish ingredients over a stick, like a sword:

emberforge/data/emberforge/recipe/ember_blade.json

{
  "type": "minecraft:crafting_shaped",
  "category": "equipment",
  "group": "emberforge",
  "pattern": [
    "B",
    "B",
    "S"
  ],
  "key": {
    "B": "minecraft:blaze_powder",
    "S": "minecraft:stick"
  },
  "result": {
    "id": "minecraft:golden_sword",
    "components": {
      "minecraft:custom_name": "{\"text\":\"Ember Blade\",\"color\":\"gold\"}",
      "minecraft:lore": [
        "{\"text\":\"Forged in the first fire.\",\"color\":\"dark_red\"}"
      ],
      "minecraft:rarity": "rare",
      "minecraft:enchantments": {
        "minecraft:sharpness": 3
      },
      "minecraft:item_model": "emberforge:ember_blade"
    }
  }
}

The Forgemaster’s Hammer, a pickaxe shape in blaze powder and gold:

emberforge/data/emberforge/recipe/forgemasters_hammer.json

{
  "type": "minecraft:crafting_shaped",
  "category": "equipment",
  "group": "emberforge",
  "pattern": [
    "BBB",
    " S ",
    " S "
  ],
  "key": {
    "B": "minecraft:blaze_powder",
    "S": "minecraft:stick"
  },
  "result": {
    "id": "minecraft:golden_pickaxe",
    "components": {
      "minecraft:custom_name": "{\"text\":\"Forgemaster's Hammer\",\"color\":\"gold\"}",
      "minecraft:lore": [
        "{\"text\":\"Heavy as a falling anvil.\",\"color\":\"gray\"}"
      ],
      "minecraft:rarity": "rare",
      "minecraft:attribute_modifiers": [
        {
          "type": "minecraft:attack_damage",
          "amount": 3,
          "operation": "add_value",
          "slot": "mainhand",
          "id": "emberforge:hammer_damage"
        }
      ],
      "minecraft:item_model": "emberforge:forgemasters_hammer"
    }
  }
}

The Molten Bun, a shapeless recipe (toss the ingredients in any order):

emberforge/data/emberforge/recipe/molten_bun.json

{
  "type": "minecraft:crafting_shapeless",
  "category": "misc",
  "group": "emberforge",
  "ingredients": [
    "minecraft:bread",
    "minecraft:blaze_powder"
  ],
  "result": {
    "id": "minecraft:bread",
    "components": {
      "minecraft:custom_name": "{\"text\":\"Molten Bun\",\"color\":\"gold\"}",
      "minecraft:lore": [
        "{\"text\":\"Still warm.\",\"color\":\"red\"}"
      ],
      "minecraft:food": {
        "nutrition": 6,
        "saturation": 7.2
      },
      "minecraft:consumable": {
        "consume_seconds": 0.8
      },
      "minecraft:item_model": "emberforge:molten_bun"
    }
  }
}

Reload, open a crafting table, and the three recipes are yours. Because the components live on the result, the crafted items come out fully themed: names, colors, behavior and model all attached.

What Went Wrong? If a crafted item appears with the right name but the wrong picture, the recipe’s item_model is fine but the resource pack isn’t loaded. Remember a resource pack is enabled in its own menu (Chapter 28), not with /datapack. If the item comes out as plain gold with no name at all, check that you wrote id in the result, not item.

The Cache Chest Loot Table

In the story, these items are found in a forge cache, a chest hidden in a structure. We’ll build the structure itself in Part XI (it’s a world-generation topic). What we can build now, and what the structure would point at, is the loot table that fills the chest. You wrote loot tables in Chapters 16 and 17; this one drops the themed items using set_components so each rolled item carries its full component bag.

A chest table declares a chest loot context: the loot situation of a container being opened.

Chest loot context. Minecraft lists “opening of a container with loot table” (barrel, chest, trapped chest, and so on) as one of the loot-context types, with the chest’s center as the Origin and the opener as the this entity. A loot table sets its context with the type field (Chapter 17). For a chest we use type: minecraft:chest.

Here’s the cache table. Two pools: one guaranteed roll that always gives the Ember Blade (the prize), and one pool that rolls 1–2 times for a hammer or some buns.

emberforge/data/emberforge/loot_table/cache.json

{
  "type": "minecraft:chest",
  "pools": [
    {
      "rolls": 1,
      "entries": [
        {
          "type": "minecraft:item",
          "name": "minecraft:golden_sword",
          "functions": [
            {
              "function": "minecraft:set_components",
              "components": {
                "minecraft:rarity": "rare",
                "minecraft:enchantments": {
                  "minecraft:sharpness": 3
                },
                "minecraft:item_model": "emberforge:ember_blade"
              }
            },
            {
              "function": "minecraft:set_name",
              "name": "{\"text\":\"Ember Blade\",\"color\":\"gold\"}",
              "target": "custom_name"
            },
            {
              "function": "minecraft:set_lore",
              "lore": [
                "{\"text\":\"Forged in the first fire.\",\"color\":\"dark_red\"}"
              ],
              "mode": "replace_all"
            }
          ]
        }
      ]
    },
    {
      "rolls": {
        "min": 1,
        "max": 2
      },
      "entries": [
        {
          "type": "minecraft:item",
          "name": "minecraft:golden_pickaxe",
          "weight": 2,
          "functions": [
            {
              "function": "minecraft:set_components",
              "components": {
                "minecraft:rarity": "rare",
                "minecraft:item_model": "emberforge:forgemasters_hammer"
              }
            },
            {
              "function": "minecraft:set_name",
              "name": "{\"text\":\"Forgemaster's Hammer\",\"color\":\"gold\"}",
              "target": "custom_name"
            }
          ]
        },
        {
          "type": "minecraft:item",
          "name": "minecraft:bread",
          "weight": 5,
          "functions": [
            {
              "function": "minecraft:set_count",
              "count": {
                "min": 1,
                "max": 3
              }
            },
            {
              "function": "minecraft:set_components",
              "components": {
                "minecraft:food": {
                  "nutrition": 6,
                  "saturation": 7.2
                },
                "minecraft:item_model": "emberforge:molten_bun"
              }
            },
            {
              "function": "minecraft:set_name",
              "name": "{\"text\":\"Molten Bun\",\"color\":\"gold\"}",
              "target": "custom_name"
            }
          ]
        }
      ]
    }
  ]
}

Testing the table without a structure

You don’t need the structure to test the loot: the /loot command runs any table on demand. There are two forms you’ll use. To drop the cache’s contents straight into your own inventory:

/loot give @s loot emberforge:cache

To fill a real chest you’ve placed, aim at it and insert:

/loot insert ~ ~ ~-1 loot emberforge:cache

(/loot give <players> loot <table> gives the items to a player; /loot insert <pos> loot <table> puts them into the container at that position, both from the /loot command’s source list.) Run it a few times: you should always get an Ember Blade, plus one or two hammers or stacks of buns.

Figure (to be captured). a chest opened to show an Ember Blade plus Molten Buns, all custom-named and gold

A Custom Structure (Preview Only)

So where does this cache live? In a structure, a built piece that generates in the world. A structure is “a large decoration… configured using JSON files within a data pack in the path data/<namespace>/worldgen/structure,” which only generates once it’s “part of at least one structure set.” A structure set then decides where in the world the piece appears.

Building a real structure (the .nbt building file, the worldgen/structure definition, the structure_set placement, jigsaw blocks, template pools) is the subject of Part XI (Chapters 40–41). It’s genuinely more involved than anything in this part, which is why it lives there. For this capstone, the takeaway is the connection: a structure’s chest would simply point its loot at the table you just wrote (emberforge:cache). You’ve already built the part that matters for the items (the loot) and you’ve tested it. When you reach Chapter 40, you’ll save a forge building, and in Chapter 41 you’ll place it in the world with its chest aimed at this exact table.

Note. We’re deliberately not writing worldgen/structure or structure_set JSON here. Those formats belong to Part XI. Treating the cache as “a loot table now, a structure later” keeps this chapter focused on assembly and lets the structure chapters teach world generation properly.

The Advancement Tree

A content pack feels finished when it guides the player. You’ll build a small advancement tree (Chapter 19) with three steps that detect the player’s progress and, at the end, fire a function.

All three use the inventory_changed trigger, which fires whenever the player’s inventory changes, with an items condition that checks what they’re now holding. The item condition gives us the fields we need: an items list (which item types match) and a components object that “matches exact item component values.” We detect an Emberforge item by checking its item_model component.

Step 1, the root, “Apprentice.” Fires when the player obtains any item carrying an Emberforge model. (We check the Ember Blade’s model as the representative; you could widen this to a list.)

emberforge/data/emberforge/advancement/root.json

{
  "display": {
    "icon": {
      "id": "minecraft:blaze_powder"
    },
    "title": {
      "text": "Apprentice",
      "color": "gold"
    },
    "description": {
      "text": "Obtain your first Emberforge item.",
      "color": "gray"
    },
    "frame": "task",
    "background": "minecraft:textures/block/netherrack.png",
    "show_toast": true,
    "announce_to_chat": true
  },
  "criteria": {
    "got_item": {
      "trigger": "minecraft:inventory_changed",
      "conditions": {
        "items": [
          {
            "components": {
              "minecraft:item_model": "emberforge:ember_blade"
            }
          }
        ]
      }
    }
  }
}

Step 2, the child, “Swordsmith.” A child advancement (it names the root as its parent), granted when the player holds the Ember Blade specifically.

emberforge/data/emberforge/advancement/ember_blade.json

{
  "parent": "emberforge:root",
  "display": {
    "icon": {
      "id": "minecraft:golden_sword"
    },
    "title": {
      "text": "Swordsmith",
      "color": "gold"
    },
    "description": {
      "text": "Hold the Ember Blade.",
      "color": "gray"
    },
    "frame": "goal",
    "show_toast": true,
    "announce_to_chat": true
  },
  "criteria": {
    "has_blade": {
      "trigger": "minecraft:inventory_changed",
      "conditions": {
        "items": [
          {
            "items": [
              "minecraft:golden_sword"
            ],
            "components": {
              "minecraft:item_model": "emberforge:ember_blade"
            }
          }
        ]
      }
    }
  }
}

Step 3, the hidden detector, “Cache Opener.” This one has no toast meant to be seen as a normal goal. Instead it’s the hidden-advancement-as-detector pattern from Chapter 19: it watches for the player obtaining a special cache marker item, then runs a reward function and immediately revokes itself so it can fire again. The marker is just bread carrying a custom_data flag (Chapter 24) that the cache chest’s structure would hand out; for testing you can give it yourself.

emberforge/data/emberforge/advancement/open_cache.json

{
  "criteria": {
    "got_marker": {
      "trigger": "minecraft:inventory_changed",
      "conditions": {
        "items": [
          {
            "components": {
              "minecraft:custom_data": {
                "emberforge_cache": true
              }
            }
          }
        ]
      }
    }
  },
  "rewards": {
    "function": "emberforge:cache_reward"
  }
}

Notice this one has no display block at all. Advancements may “lack a display so that they can utilize triggers and rewards instead of excessive commands”: exactly the silent-event- listener role from Chapter 19. Its reward fires the function below.

emberforge/data/emberforge/function/cache_reward.mcfunction

# Emberforge — fired when the player opens the cache (hidden advancement reward)
playsound emberforge:cache_open master @s
tellraw @s {"text":"The forge remembers you.","color":"gold"}

# re-arm: revoke this advancement so it can fire again next time
advancement revoke @s only emberforge:open_cache

That last line is the re-arming trick from Chapter 19: revoking the hidden advancement on the player means the next time they pick up a cache marker, it triggers all over again.

Figure (to be captured). the “Apprentice” and “Swordsmith” advancements in a custom tab with a netherrack background

Custom Sound for Polish

The reward function plays emberforge:cache_open, a sound that doesn’t exist yet. Register it the way you learned in Chapter 30: a sounds.json in the resource pack that maps the event name to one or more .ogg files.

emberforge_resources/assets/emberforge/sounds.json

{
  "cache_open": {
    "subtitle": "Emberforge cache opens",
    "sounds": [
      "emberforge:cache_open"
    ]
  }
}

Then place your OGG file at assets/emberforge/sounds/cache_open.ogg. Remember that /playsound takes an event name, not a file name. The event here is emberforge:cache_open (the emberforge namespace plus the cache_open key from sounds.json), and the sounds list points at the file. That’s why the reward function says playsound emberforge:cache_open master @s. The subtitle line shows in closed captions if the player has them on.

Modern Minecraft. The event’s namespace comes from where the sounds.json lives, not from a field inside it. The file is under assets/emberforge/, so its events are emberforge:<key>. This is why the same cache_open key inside an assets/minecraft/sounds.json would instead be a vanilla event. Keep your sounds under your own namespace and they won’t collide with anyone else’s pack.

The Full Project Tree

Here is everything you built, both packs side by side. (Model and texture files from Chapter 29, and the .ogg, are marked but not reprinted; they’re the same art-pipeline files from earlier chapters.)

emberforge/                                              <- DATA pack
  pack.mcmeta
  data/
    minecraft/
      tags/function/load.json
    emberforge/
      function/
        load.mcfunction
        make_items.mcfunction
        cache_reward.mcfunction
      recipe/
        ember_blade.json
        forgemasters_hammer.json
        molten_bun.json
      loot_table/
        cache.json
      advancement/
        root.json
        ember_blade.json
        open_cache.json

emberforge_resources/                                    <- RESOURCE pack
  pack.mcmeta
  assets/
    emberforge/
      sounds.json
      items/
        ember_blade.json
        forgemasters_hammer.json
        molten_bun.json
      models/item/    (ember_blade.json, forgemasters_hammer.json, molten_bun.json — Chapter 29)
      textures/item/  (ember_blade.png, forgemasters_hammer.png, molten_bun.png — Chapter 29)
      sounds/         (cache_open.ogg — Chapter 30)

Testing Everything Together

A content pack has many moving parts, so test it as a routine, top to bottom, every time you change something. Here’s the checklist for Emberforge:

  1. Install both packs. Put emberforge/ in the world’s datapacks/ folder; bundle emberforge_resources/ as a resources.zip (Chapter 28) and enable it in Options → Resource Packs. Two packs, two different menus.
  2. Reload. Run /reload. You should see the [Emberforge] forge fires lit announcement.
  3. Items. Run function emberforge:make_items. All three items appear, named and colored, wearing their custom models.
  4. Recipes. Open a crafting table and craft each of the three. The crafted items should match the given ones exactly.
  5. Loot. Place a chest, aim at it, run /loot insert ~ ~ ~-1 loot emberforge:cache a few times. You should always get an Ember Blade plus a hammer or buns. Try /loot give @s loot emberforge:cache too.
  6. Advancements. Obtain an Emberforge item → “Apprentice” pops. Hold the Ember Blade → “Swordsmith” pops. Give yourself the cache marker (give @s minecraft:bread[custom_data={emberforge_cache:true}]) → the hidden detector fires the reward.
  7. Sound. When the hidden detector fires, you should hear emberforge:cache_open and see “The forge remembers you.” If you hear nothing, the sound event or the .ogg path is wrong. Check sounds.json and that the resource pack is actually enabled.

When every line passes, your content pack is complete and shippable. (Chapters 46–47 cover versioning and publishing it for other players.)

Practice

  1. A fourth item. Add an Ember Charm (use any item ID, e.g. minecraft:gold_nugget) with a custom_name, rarity, and item_model. Give it a shapeless recipe, add it as a low-weight entry in cache.json, and add an item_model definition for it. Run your test checklist again. The new item should flow through every system.
  2. A second advancement branch. Add a child advancement under the root, “Baker,” that fires on holding a Molten Bun (inventory_changed with the bun’s item_model in components). Give it a goal frame. Now your tree branches: Apprentice → Swordsmith and Apprentice → Baker.
  3. Widen the root. Change the root’s items condition into a list of all three Emberforge models so any of them triggers “Apprentice,” not just the blade. (Hint: the items field is already a list, so add more entries, each with a different item_model.)

What Can Go Wrong

  • Namespace mismatch between the two packs. If your data pack uses emberforge but you put the models under assets/ember_forge/, every item_model pointer misses and items show the error model. One project, one namespace: check both packs spell it the same way.
  • Forgetting the resource pack. Data packs and resource packs enable in different menus (Chapter 28). If items have the right names and behavior but wrong pictures, or the custom sound is silent, the resource pack almost certainly isn’t loaded.
  • Wrong loot type. A chest table needs "type": "minecraft:chest". If you copy a mob table’s context by accident, conditions that expect a chest context won’t behave. (For this simple table it’ll still drop items, but get into the habit of matching the context to where the table is used.)

What You Know Now

You can plan a content pack on paper, then build it: a paired data pack and resource pack under one project namespace, with custom items (components + models), recipes that craft them, a loot table that drops them, an advancement tree that guides the player, and a custom sound for polish, and you can test the whole thing end to end. This is the capstone of Parts I–VIII: it ties together components (21–24), recipes (15), loot tables (16–17), advancements (19), resource-pack models (29) and sounds (30) into one shippable project. The one piece you’ve previewed but not yet built is the structure that houses the cache. That’s where Part XI begins.