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 20 — Item Modifiers

What You’ll Build

Back in Chapter 17 you learned that a loot table can do more than just pick an item to drop. It can also change that item on the way out, using little building blocks called functions: set_count to change the stack size, set_name to rename it, set_lore to add description lines, enchant_with_levels to enchant it, and so on. Those functions were tucked inside the loot table, only running when the loot table rolled.

In this short chapter you’ll learn how to lift those exact same functions out of a loot table and into their own reusable file, called an item modifier. An item modifier is a recipe for transforming an item, and because it lives in its own file with its own name, you can point at it from anywhere and fire it at any item you like, whenever you like, using a command. No loot table, no mob death, no dropped item required.

By the end you’ll have built a modifier called mypack:upgrade_held that takes whatever item the player is holding and upgrades it on the spot (adding an enchantment and a line of golden lore), plus a one-line function that runs it. You’ll be able to hold a plain stone sword, run the function, and watch it turn into something that looks legendary.

This chapter closes Part V. It extends the mypack pack you started in Chapter 9 and uses the test world you’ve used since Chapter 1.

A function, with a new home

Here is the single most important idea in this chapter, so let’s say it plainly first.

An item modifier is a reusable loot function (or a list of loot functions) saved as its own JSON file. A single modification inside an item modifier is itself called an item function or loot function.

In other words, the things you call “functions” inside a loot table and the things that make up an item modifier are the same things. set_count, set_lore, set_name, enchant_with_levels: every function type you met in Chapter 17 is available here, with the same name and the same fields. The only difference is where the function lives and what makes it run:

  • A loot-table function lives inside a loot table file and runs when that loot table is rolled (a mob dies, a chest generates, you fish something up).
  • An item modifier lives in its own file under data/<namespace>/item_modifier/ and runs when you tell it to, with the /item command, on an item that already exists in the world.

Why bother splitting it out? Two reasons. First, reuse: if five different loot tables all want to “make this a named, enchanted hero item,” you can write that recipe once as an item modifier and have all five point at it, instead of copy-pasting the same block of functions five times. Second, on-demand transformation: a loot table only changes items as they drop. An item modifier can change an item that is already in a chest or in a player’s hand, something a loot table simply can’t do.

Where item modifiers live, and what they look like

Item modifiers are JSON files, and like every other data-pack file you’ve made, their folder is singular and they sit under your namespace:

data/<namespace>/item_modifier/

For your pack that means data/mypack/item_modifier/. The file name (minus the .json) becomes the modifier’s id, exactly like recipes and loot tables: a file at data/mypack/item_modifier/increase_count.json is referred to as mypack:increase_count.

Now the shape. An item modifier is a single loot function, or an array of loot functions, to apply to the item. The root element can be either a single compound following the structure of a loot function, or a list containing multiple loot functions.

So a modifier file comes in two shapes:

  1. A single function: the whole file is one JSON object { ... } describing one function.
  2. An array of functions: the whole file is a JSON list [ ... ] of those objects. When you use the list form, every modifier in it is applied in sequence, one after another, in order.

A single function object always has at least one field:

  • function — the resource location of the loot function type to apply, e.g. "minecraft:set_count". This is the same set of type names you saw in Chapter 17.

It may also carry:

  • conditions — an optional list of predicates (the reusable condition checks from Chapter 18); the function only runs if all of them pass. We won’t need conditions here, but it’s good to know a function can be gated this way.
  • plus whatever extra fields that particular function needs: count for set_count, lore for set_lore, and so on.

Running a modifier with /item modify

A modifier file just sits there until something runs it. The thing that runs it is the /item command. It comes in two variations: item modify invokes a modifier alone upon the target slot, while item replace replaces the item in the target slot with another and then invokes a modifier upon it.

We’ll focus on item modify. Here is its exact syntax:

item modify (block <pos>|entity <targets>) <slot> <modifier>

Reading it left to right: you say whether you’re modifying a block’s container (a chest, a furnace) at a position, or an entity’s inventory (a player or mob); then you give the slot to act on; then the modifier to apply. The <slot> is the name of one inventory slot, and its valid values depend on whether you picked a block or an entity. The slot names we’ll use include:

  • weapon.mainhand — the item in the entity’s main hand (what they’re holding).
  • weapon.offhand — the off-hand item.
  • armor.head — the helmet slot.
  • hotbar.8 — a numbered hotbar slot.
  • container.26 — a numbered slot inside a container block like a chest.

Here is a worked example, which is also the perfect first modifier to build. The file:

data/example/item_modifier/increase_count.json

{
  "function": "minecraft:set_count",
  "count": 1,
  "add": true
}

And the command that fires it at the item in your main hand:

/item modify entity @s weapon.mainhand example:increase_count

That modifier uses the set_count function with "add": true, which means the change is relative to the current count, so each time you run it, the stack in your hand grows by one. Let’s build the same thing in your pack and then make it do something far more interesting.

Make this file:

mypack/data/mypack/item_modifier/increase_count.json

{
  "function": "minecraft:set_count",
  "count": 1,
  "add": true
}

That’s a complete, valid item modifier: a single function, the simplest possible shape. After you save it and run /reload in your test world, hold any stackable item (say, a stack of cobblestone) and type this in the chat bar:

/item modify entity @s weapon.mainhand mypack:increase_count

The stack grows by one. Run it again, and it grows again. You just fired a data-pack file at the item in your hand.

Modern Minecraft — If you follow older tutorials you may see this written with /replaceitem or with raw tag/NBT edits. Those are gone. In current Java Edition the /item command is the way to put items into slots and to transform items in place, and it does it by running an item modifier, the very same loot-function language used everywhere else in the game. Learn this one tool and it pays off in loot tables, advancements, and commands all at once.

Figure (to be captured). a stack of cobblestone in hand growing by one after running mypack:increase_count

Walkthrough: an upgrade-the-held-item modifier

Now for the real goal: a modifier that adds an enchantment and a line of lore to whatever item the player is holding. Because we want to do two things (enchant and add lore), we’ll use the array form of an item modifier: a JSON list of functions, applied in order.

We need two function types from the same loot-function family you met in Chapter 17:

  • set_enchantments — a new enchantment function for us here, and a sibling of the enchant_with_levels you used in Chapter 17. Where enchant_with_levels rolls random enchantments for a given enchanting level, set_enchantments lets you set specific enchantments by name. It modifies the item’s enchantments, and takes an enchantments compound, where each key is an enchantment ID and each value is the enchantment power (level). (The level is technically a number provider, the same little value-or-range objects you met with loot tables, but a plain whole number is a perfectly valid number provider, so we’ll just write 3.)
  • set_lore — the loot function from Chapter 17, used here on its own. It adds or changes the item’s lore, taking a lore list of lines, where each line is a text component (the rich-text format from Chapter 5), plus a required mode field. The allowed modes are "append", "insert", "replace_all", and "replace_section". We’ll use "append" to add our line without erasing any existing lore.

Here is the complete modifier file. It’s a list, so the whole file is wrapped in [ ... ]:

mypack/data/mypack/item_modifier/upgrade_held.json

[
  {
    "function": "minecraft:set_enchantments",
    "enchantments": {
      "minecraft:unbreaking": 3
    }
  },
  {
    "function": "minecraft:set_lore",
    "mode": "append",
    "lore": [
      {
        "text": "Upgraded by mypack",
        "color": "gold",
        "italic": false
      }
    ]
  }
]

Read it as a two-step recipe. Step one (set_enchantments) adds Unbreaking III to the held item: the key minecraft:unbreaking is the enchantment, the value 3 is the level. Step two (set_lore) appends one golden line of lore that reads Upgraded by mypack. The lore line is a plain text component exactly like the ones you wrote in Chapter 5: a text field with color and a styling flag. We set "italic": false because, as you saw with custom text in Chapter 5, Minecraft typically italicizes custom lore, so turning it off keeps the line sitting upright.

Under the Hood (skippable) — Why is the file a list this time, but increase_count.json was a single object? Both are legal. A single object is a one-function modifier; a list lets you chain several. A list behaves much like the sequence modifier type: there’s even an explicit sequence function type that does the same thing. For two functions, the bare list is the simplest form, so that’s what we use.

Now the function that runs it. We point item modify at the player’s main hand:

mypack/data/mypack/function/upgrade_item.mcfunction

item modify entity @s weapon.mainhand mypack:upgrade_held
say Your held item has been upgraded!

Notice there’s no leading / inside the function file. That’s our rule from Chapter 9. The @s selector means “the entity running this function,” so when a player runs it, it acts on their main hand. Save everything, run /reload, then hold a sword (or any item) and run:

/function mypack:upgrade_item

Your held item gains Unbreaking III and a golden Upgraded by mypack line under its name. Hold a different item and run it again, and the same modifier works on whatever you’re holding, because the modifier describes a transformation, not a specific item.

Figure (to be captured). a stone sword tooltip showing “Unbreaking III” and a gold “Upgraded by mypack” lore line after running mypack:upgrade_item

What item modifiers are good for

Now that you can write and fire a modifier, here are the three big uses, the same three the rest of this book leans on.

Applying a set of components. There’s a function type called set_components whose whole job is to set an item’s data components at once. It sets the components of an item, and it can even remove a component by prefixing its name with !. Components are the heart of how modern Minecraft describes items, and they’re the entire subject of the next chapter (Chapter 21), so we’re only previewing here. The point for now: when you want to stamp a whole bundle of properties onto an item in one shot, an item modifier with set_components is the tool, and you’ll meet it properly next.

Transforming loot. Because an item modifier is built from the very same functions a loot table uses, you can write a transformation once and reference it from a loot table with the reference function (which calls sub-functions), instead of repeating the functions inline. Your loot keeps one shared definition of “what a hero item looks like.”

Dynamic item creation. With /item modify (and its sibling /item replace, which can put a fresh item into a slot and then modify it), a data pack can build and alter items while the game is running: upgrade a player’s gear when they hit a milestone, restyle the contents of a chest, swap a tool’s enchantments mid-quest. None of that can a static loot table do on its own.

Practice

  1. A renaming modifier. Write mypack/data/mypack/item_modifier/rename_blade.json as a single function using set_name. set_name adds or changes the item’s custom name and takes a name text component. Give the name a color of your choice. Then make a function that runs item modify entity @s weapon.mainhand mypack:rename_blade and try it on a sword.

  2. Stack the steps. Turn rename_blade.json into the array form and add a second function after the rename: a set_lore with "mode": "append" that adds a flavor line. Run it and confirm both the name and the lore change in one command: proof that a list of functions applies in order.

  3. Fire it at a chest. Place a chest, put an item in its first slot, and from a function run item modify block ~ ~ ~ container.0 mypack:upgrade_held while standing on the chest. (Adjust the ~ ~ ~ coordinates to point at the chest; those relative coordinates are from Chapter 2.) Watch the item inside the chest get upgraded. This is the “transform an item that already exists” power that loot tables don’t have.

What Can Go Wrong

“Unknown item modifier” or the command fails outright. The <modifier> you name must be the resource location of an existing item modifier. Almost always a failure here means a typo in the id or a misplaced file: the path must be exactly data/mypack/item_modifier/upgrade_held.json (folder singular, namespace folder spelled mypack), and you must /reload after creating it. If the id is right but the file won’t load, your JSON is malformed: a missing comma between the two functions in the array is the classic culprit.

Nothing happens, but no error appears. Check the slot. The command fails or does nothing when the target doesn’t have the specified slot. For example, you ran it against an empty weapon.mainhand (you weren’t holding anything), or you aimed at a block that isn’t a container. Hold an item first, and make sure a chest is actually at the coordinates you gave.

The lore line is missing or replaces everything. set_lore requires its mode field. Leave it out and the function is invalid; set it to "replace_all" by accident and you’ll wipe any lore that was already there. Use "append" when you mean “add a line.”

What You Know Now — Part V Recap

This chapter closes Part V, the part where you learned to make Minecraft do things by writing data files rather than by typing commands. You can now:

  • Write recipes, loot tables, predicates, and advancements, and, as of this chapter, item modifiers, which are reusable loot functions in their own files under data/<namespace>/item_modifier/.
  • Choose between the two modifier shapes: a single function object, or an array of functions applied in sequence.
  • Fire a modifier at any item in the world with /item modify, naming the slot (weapon.mainhand, armor.head, container.0, …) to act on.
  • See why an item modifier reaches places a loot table can’t: it transforms items that already exist, on demand.

The single thread running through all of Part V is that the same small building blocks reappear everywhere: a loot function is a loot function whether it’s inside a loot table, referenced from an advancement reward, or standing alone as an item modifier. In Part VI, starting with Chapter 21, we go one level deeper into the items themselves: data components, the named properties that define every item stack, the thing set_components was quietly setting all along.