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/itemcommand, 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:
- A single function: the whole file is one JSON object
{ ... }describing one function. - 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:
countforset_count,loreforset_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
/replaceitemor with rawtag/NBT edits. Those are gone. In current Java Edition the/itemcommand 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 theenchant_with_levelsyou used in Chapter 17. Whereenchant_with_levelsrolls random enchantments for a given enchanting level,set_enchantmentslets you set specific enchantments by name. It modifies the item’s enchantments, and takes anenchantmentscompound, 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 write3.)set_lore— the loot function from Chapter 17, used here on its own. It adds or changes the item’s lore, taking alorelist of lines, where each line is a text component (the rich-text format from Chapter 5), plus a requiredmodefield. 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.jsonwas 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 thesequencemodifier type: there’s even an explicitsequencefunction 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
-
A renaming modifier. Write
mypack/data/mypack/item_modifier/rename_blade.jsonas a single function usingset_name.set_nameadds or changes the item’s custom name and takes anametext component. Give the name a color of your choice. Then make a function that runsitem modify entity @s weapon.mainhand mypack:rename_bladeand try it on a sword. -
Stack the steps. Turn
rename_blade.jsoninto the array form and add a second function after the rename: aset_lorewith"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. -
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_heldwhile 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.