Custom model data: giving one item many models without replacing anything
The item-model system replaced the old CustomModelData predicate. Here is the folder layout, the JSON that maps values to models, and why your texture shows as a purple cube.
Custom item models let a server hand out a "magic wand" that is really a carrot on a stick with a different model. The mechanism changed, and most tutorials still describe the old one.
What changed
Old way — a predicate block inside the base item's model file, keyed on custom_model_data as a number:
{ "predicate": { "custom_model_data": 1 }, "model": "item/wand" }
Current way — an items/ definition that selects a model:
assets/minecraft/items/carrot_on_a_stick.json
{
"model": {
"type": "minecraft:range_dispatch",
"property": "minecraft:custom_model_data",
"fallback": { "type": "minecraft:model", "model": "minecraft:item/carrot_on_a_stick" },
"entries": [
{ "threshold": 1, "model": { "type": "minecraft:model", "model": "minecraft:item/wand" } }
]
}
}
The fallback is what a plain carrot on a stick still looks like. Without it, every unmodified one in the world turns into your wand.
The folder layout
pack.mcmeta
assets/minecraft/
├── items/carrot_on_a_stick.json the dispatch
├── models/item/wand.json the model
└── textures/item/wand.png the texture
models/item/wand.json at its simplest:
{ "parent": "minecraft:item/generated", "textures": { "layer0": "minecraft:item/wand" } }
Note the texture path has no textures/ prefix and no .png — that is the single most common cause of a purple-and-black cube.
Giving the item
/give @p carrot_on_a_stick[custom_model_data={floats:[1]}]
The component takes an object with typed lists now, not a bare integer. custom_model_data=1 is the old syntax and silently does nothing.
Why it shows as a purple cube
In order of likelihood:
- Texture path wrong — includes
textures/or.png, or the file is not where the
path says.
- Filename case — the game is case-sensitive even where your OS is not.
pack_formattoo low — the pack loads but theitems/folder is ignored. Match
the format to the version you are on.
- Zipped wrong —
pack.mcmetamust be at the root of the zip, not inside a
folder inside the zip.
Other selectors
range_dispatch on a number is only one option. You can also dispatch on minecraft:display_context (different model in hand versus in a frame), minecraft:using_item, or minecraft:selected — which is how a bow shows a drawn state.
Build the dispatch JSON, the model file and the give command together in the Custom Model & Item Component Tools.