6

I'm wondering whether it is possible to change part of the NBT or add NBT to an item that a player is holding.

My goal is to make custom enchantments. For example, my system is set up so that when a player uses an item, a scoreboard value EnchantMight would be set, which would cause the next weapon they hold to get a fictional enchantment, "Might V". This, in reality, would just be an attribute modifier within the NBT that adds +5 attack damage.

/replaceitem is able to replace items inside the player's inventory, but it is not able to modify them, as the replacement item is specified as part of the command, and cannot be used to modify only part of the item's data without completely overwriting the item.

The only option left to modify part of an item's data would be the /data command. Unfortunately, it is restricted from being used upon players, only throwing a flat error message and not performing any operation. If it did work on players, we could simply use a command like so:

data modify entity @p {SelectedItem:[{AttributeModifiers:[{AttributeName:"generic.attack_damage",Amount:5,Operation:0,UUID:[I;-120919,1237,151734,-2474],Name:"generic.attack_damage"}]}]} insert/append/merge

Does anyone have an idea on alternatives that could be used to modify part of an item's NBT? I'm open to using data packs, but I'm not very experienced in them, so detail would be appreciated in any responses.

1
  • Considering that a higher-traffic question may become duplicate of this, I have revised this question and its answers with extra detail and clarity in the hopes that it will be easier to read for everyone. Feel free to edit further as needed.
    – One 2 Many
    Commented Oct 15, 2022 at 5:37

2 Answers 2

4

Solution for versions 1.17 and newer

As of 1.17, there are two ways to modify items while they are inside of the player's inventory.

Item modifiers

1.17 introduced item modifiers, data pack files that can be invoked upon items in the inventory to modify their properties. This is the easiest way to modify item properties, whether they are within the player's inventory or not.

Here is a sample item modifier for the example in the question post:

{
  "function": "minecraft:set_attributes",
  "modifiers": [
    {
      "attribute": "minecraft:generic.attack_damage",
      "name": "",
      "amount": 5,
      "operation": "addition",
      "id": "fffe27a9-0000-04d5-0002-50b6fffff656",
      "slot": "mainhand"
    }
  ]
}

Item modifiers are placed at the folder /data/<namespace>/item_modifiers/<modifier_name>.json. It can then be invoked upon any item slot in any container block or entity's inventory, using /item like so:

item modify entity @s weapon.mainhand <modifier_reference>

where <modifier_reference> is your reference to the data pack file containing your item modifier's data. For example, if your item modifier's location is /data/special_enchants/item_modifiers/add_attributes.json, then your modifier reference would be special_enchants:add_attributes.

You can generate item modifier files using a generator such as misode.github.io, and you can read more about these changes on the relevant Minecraft Wiki page.

Commands only

With commands and command blocks only, /item still allows us to cut down on the number of commands we run. However, we cannot take advantage of the performance benefit of item modifiers, given that /data (the only other alternative) has a high impact on performance and is considered an expensive operation. This is why data packs are recommended for larger projects.

This method uses a temporary slot to store items while they are being modified. Usually, the standard location for this purpose is a yellow shulker box placed at the coordinates (-30000000, 0, 1602).

To copy an item from the player's main hand to an inventory slot of another block or entity, one of the following commands can be used:

item replace block <block> <slot> from entity <player> <slot>
item replace entity <entity> <slot> from entity <player> <slot>

The left side block or entity and slot refers to the location where the item(s) will be copied to, and the right hand side refers to where the item(s) are coming from. Therefore, the command can be reversed to copy the item(s) back to the player.

Example

The following example adds the Sharpness enchantment to the item in the player's main hand, and sets the level of this enchantment to one of the player's score values.

  1. item replace block -30000000 0 1602 container.0 from entity @s weapon.mainhand
    
  2. data modify block (x) (y) (z) Items[0] merge value {tag:{Enchantments:[{id:"minecraft:sharpness", lvl:1s}]}}
    
  3. execute store result block (x) (y) (z) Items[0].tag.Enchantments[0].lvl short 1.0 run scoreboard players get @s sharpnesslvl
    
  4. item replace entity @s weapon.mainhand from block -30000000 0 1602 container.0
    

Explanation

  1. Copies the item from the player's main hand to the shulker box.
  2. Accesses the item's data, and adds a temporary enchantment of Sharpness. Currently it has level I, but this will be changed by command #3.
  3. This command runs a /scoreboard players get to get the player's sharpnesslvl score. Whatever number is retrieved gets set as the level on the enchantment as per the /execute store part.
  4. This is the reverse of command #1, to copy the modified item and overwrite the old item in the mainhand.
3

Solution for versions 1.14–1.16

An interesting workaround to change NBT of a custom item is to copy it to a chest, modify it in the chest (where it can be modified) and then use /loot in replace mode to replace the item slot.

Outside preparation

You'll need a special loot table to make this happen. Click this link to access the loot table that you'll need.

This loot table will cause a yellow shulker box to drop its contents instead of itself when broken with a tool with the custom tag {drop_contents:1b}.

Minecraft preparation

You'll need to first place down a yellow shulker box, and place a temporary item (like a piece of dirt) in slot 0 (upper-left corner).

Important: Ensure the shulker box is otherwise empty, and always write to it with the NBT path Items[0].

The standard location for this shulker box is (-30000000, 0, 1602).

Commands

The first step is to copy the item to the shulker box:

data modify block (x) (y) (z) Items[0] merge from entity (selector) SelectedItem

(Note, if your copy source includes the Slot tag, you'll need to use three separate commands to copy ID, Count, and tag separately.)

The second step is to modify that item, use whatever commands you want here to reference the shulker box. Here are some sample commands. Try these ones out for your first try. These commands will set the Sharpness enchantment level to the scoreboard value you specify.

data modify block (x) (y) (z) Items[0] merge value {tag:{Enchantments:[{id:"minecraft:sharpness", lvl:1s}]}}
execute store result block (x) (y) (z) Items[0].tag.Enchantments[0].lvl short 1.0 run scoreboard players get FakePlayer myObjective

Once the modification is complete, here's the magic: use /loot to replace the item in the specified slot.

loot replace entity (selector) weapon.mainhand 1 mine block (x) (y) (z) minecraft:air{drop_contents:1b}
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.