Armour trim materials and patterns can be inlined in the NBT for item stacks.
Steps to reproduce:
Open any world (ideally one without any data packs to showcase the bug better)
Apply the resource pack present in this bug report:
Give yourself the following item stack and wear it (I expanded it to make it easier to read)
minecraft:leather_chestplate{ Trim: { material: { asset_name: "test", description: { text: "Test Material", color: "#66B24C" }, ingredient: "minecraft:air", item_model_index: 0.15f }, pattern: { asset_id: "bug:test", description: { text: "Test Armour Trim" }, template_item: "minecraft:air" } } }
Notice how the armour trim is applied
Code analysis
In the TrimMaterial
and TrimPattern
records the CODEC
field calls RegistryFileCodec::create(ResourceKey<? extends Registry<E>>, Codec<E>)
, which creates a new instance of RegistryFileCodec
with allowInline
set to true
. See the copied bit for TrimMaterial
.
public record TrimMaterial(String assetName, Holder<Item> ingredient, float itemModelIndex, Map<ArmorMaterials, String> overrideArmorMaterials, Component description) {
// ...
public static final Codec<Holder<TrimMaterial>> CODEC = RegistryFileCodec.create(Registries.TRIM_MATERIAL, DIRECT_CODEC);
// ...
}
This can be fixed by calling the method overload RegistryFileCodec::create(ResourceKey<? extends Registry<E>>, Codec<E>, boolean)
instead, with the boolean set to false
and thereby disallowing inline entries.
Attachments
Comments 2
The game never inlines armour trim materials and patterns by itself. It always uses a reference to an armour trim in the dynamic registry. For example, combining the Dune Smithing Template with Redstone in a smithing table yields the following:
{
material: "minecraft:redstone",
pattern: "minecraft:dune"
}
See the images as well. The command used to retrieve the result was /data get entity @s SelectedItem.tag.Trim
while holding the item.
Why do you believe this is a bug? If a trim gets disabled (via another data pack, or disabling the one that adds it), the item text would break if it were fetched from the file, while now, it stays functional.