Chapter 29 — Custom Item Models and Textures
What You’ll Build
Back in Chapter 22 you wrote a sword that pointed at a custom look with the item_model
component, and you packed data into a custom_model_data compound, but the artwork the pointer
aimed at didn’t exist yet. This is the chapter where you build it.
By the end you’ll have a flame sword in your resource pack: an item that shows a plain blade most of the time, but swaps to a glowing, flaming blade the moment it carries an enchantment shimmer. You’ll make the picture (a small PNG texture), wrap it in a model, and write the item model definition: the little JSON file that decides, frame by frame, which model the game should draw. You’ll learn the five kinds of model definition and finish by making your sword change its own look based on its components, all without a single command running at play time.
Figure (to be captured). two tooltips side by side — a plain custom sword, and the same sword glowing/flaming once it has an enchantment glint
Concepts
Three folders, three jobs
In Chapter 28 you built a resource pack and learned its assets/<namespace>/ layout. Three of the
folders inside it work together to draw a custom item, and keeping them straight is most of the
battle:
assets/<namespace>/textures/holds the flat images —.pngfiles in PNG format, which provide the images used as textures for models such as items, blocks and mobs. Item images live intextures/item/.assets/<namespace>/models/holds the shapes —.jsonfiles defining the three-dimensional shapes used to render blocks and items. A model says what form the item takes and which texture it wears.assets/<namespace>/items/holds the item model definitions —.jsonfiles controlling the rendering of items. This is the new system this chapter is about: the file that chooses a model.
So the chain runs: a definition in items/ points at a shape in models/, and that shape wears an
image from textures/. One picture, one shape, one chooser.
Modern Minecraft. If you follow an older tutorial, you may see it put everything in the
models/file and use a longoverrideslist to switch models bycustom_model_data. Modern Minecraft splits that job out into theitems/folder you’re learning here. Theoverrideslist is gone: theitems/definition with its model types (below) replaces it. If a video edits an item’s model directly withoverrides, it’s describing the old way.
The pointer, from Chapter 22
An item knows which definition to use through the minecraft:item_model component you met in
Chapter 22. It is the resource location of the item, which references the item model definition
/assets/<namespace>/items/<id> without the .json suffix. So if your sword carries
item_model="mypack:flame_sword", the game reads the file assets/mypack/items/flame_sword.json.
There’s an important warning here: referencing nonexistent models will cause the missing model to be
used, rather than falling back to the item ID’s default model. Spell the path wrong and you get the
error model, not your diamond sword back.
The shape of an item model definition
Every file in items/ has the same outer shape. The root object holds:
- a few optional animation switches (
hand_animation_on_swap,oversized_in_gui,swap_animation_scale) we’ll leave at their defaults, and - a
modelfield holding one items model object — the actual chooser.
That inner model object always has a type. The possible values for type are:
minecraft:model, minecraft:composite, minecraft:condition, minecraft:select,
minecraft:range_dispatch, minecraft:empty, minecraft:bundle/selected_item, and
minecraft:special. This chapter teaches the first five; they’re the ones you’ll reach for. The
last three (an item that draws nothing, the selected stack of a bundle, and “special” hard-coded
renders like banners and heads) exist, but we leave them named and move on.
Here’s the simplest possible definition, type: minecraft:model, which renders a plain model from
the models directory:
assets/mypack/items/flame_sword.json
{
"model": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword"
}
}
Read it inside-out. The model field (inner) is the namespaced id of a shape in the models/
folder: it specifies the path to the model file of the item, in the form of a namespaced ID. So
mypack:item/flame_sword means assets/mypack/models/item/flame_sword.json.
The model object (outer) wraps that and gives it a type. Yes, “model” shows up twice: the
outer one is the chooser, the inner one is the shape it chose.
The five model types, at a glance
In plain terms:
minecraft:model— draw one fixed model. (You just saw it.)minecraft:composite— “render multiple sub-models in the same space.” Stack several models on top of each other.minecraft:condition— pick between two models based on a yes/no test, like “is this item damaged?”minecraft:select— pick a model from a list of named cases, like “which string is in the item’s data?”minecraft:range_dispatch— pick a model based on a number, like “how damaged, on a scale from 0 to 1?”
The Chapter 22 payoff: custom_model_data ↔ model type
Here’s the connection the last few chapters have been building toward. In Chapter 22 you learned
that minecraft:custom_model_data is a compound carrying four lists. It holds a list of values
used by items model definitions for model selection and coloring. Each of its four lists feeds
one of the model mechanisms you just met:
| custom_model_data list | feeds this model type | what it is |
|---|---|---|
flags (booleans) | condition | A list of booleans for the condition model type. |
strings | select | A list of strings for the select model type. |
floats | range_dispatch | A list of floats for the range_dispatch model type. |
colors | model (its tints) | A list of RGB values for the model model type’s tints. |
So the data you stamped onto the item in Chapter 22 and the JSON you’re writing now are two halves of the same machine. The item carries the data; the definition reads it. We’ll wire up one of these linkages in the Practice.
Walkthrough
Step 1 — prove the pipeline with a vanilla model
Before making any art, let’s prove the plumbing works by pointing at a model that already exists. Give yourself a stick that renders as a diamond sword. First the definition:
assets/mypack/items/proof.json
{
"model": {
"type": "minecraft:model",
"model": "minecraft:item/diamond_sword"
}
}
The inner model is minecraft:item/diamond_sword, a model that ships with the game, so we don’t
have to build it. Now hand yourself a stick that uses this definition. Put this in a function in your
mypack data pack (commands live in .mcfunction files, no leading /):
data/mypack/function/give_proof.mcfunction
give @s stick[item_model="mypack:proof"]
Reload, run the function, and the stick in your hand looks like a diamond sword. The data pack hands
out the item; the resource pack draws it. If you instead see a black-and-purple error cube, the game
couldn’t find assets/mypack/items/proof.json, so check the filename and the namespace.
Step 2 — a brand-new texture
Now your own art. A standard item image is 16×16 pixels. You need an image editor that can save a PNG with transparency and edit one pixel at a time. Free options that work well:
- GIMP or Krita (desktop, full-featured),
- Aseprite (paid, made for pixel art),
- any web-based pixel editor (search “online pixel art editor”).
Set the canvas to 16×16, turn the background transparent (so the area around your sword shows the world behind it, not a white box), zoom way in, and draw. Keep colors bold and outlines dark. At 16 pixels there’s no room for subtlety. Save it here:
assets/mypack/textures/item/flame_sword.png
Try It! Make two versions in the same style:
flame_sword.png(a plain blade) andflame_sword_glow.png(the same blade with orange flames licking up it). You’ll use both in the Practice to make the sword change look.
Step 3 — a model to wear the texture
A texture is just a flat image; a model is the shape that wears it. The models/ folder holds
the three-dimensional shapes used to render blocks and items, and an items model definition’s model
field is the namespaced id of one of these files. For a flat item like a sword, the model is tiny:
it borrows a standard “flat item” shape and points it at your PNG:
assets/mypack/models/item/flame_sword.json
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "mypack:item/flame_sword"
}
}
parent: minecraft:item/generated means “use the game’s standard flat-item shape.” layer0 is the
image that shape wears: your assets/mypack/textures/item/flame_sword.png.
Under the Hood (skippable). The full grammar of a
models/file (building custom 3-D shapes out of cuboids, faces, and display transforms) is its own large subject, separate from theitems/definition system this chapter teaches. For flat items you’ll almost always reuseminecraft:item/generatedexactly as above and just swap thelayer0texture, so you won’t need that grammar here. When you do want to model a custom 3-D shape from scratch, the wiki’s Model page is the place to go.
Step 4 — point the definition at your model
Now update flame_sword.json from the start of the chapter to use your model instead of a vanilla
one:
assets/mypack/items/flame_sword.json
{
"model": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword"
}
}
And give yourself the sword:
data/mypack/function/give_flame_sword.mcfunction
give @s iron_sword[item_model="mypack:flame_sword"]
You now have a fully custom item: a real iron sword (so it still swings and breaks blocks), wearing your own picture. This is the whole pipeline: image, shape, definition, pointer.
Overriding a vanilla item vs. a new visual
You have two ways to put a custom look in front of a player, and they’re worth telling apart:
- A new visual, keyed by
item_model. This is what you just did. The item keeps its real type (iron_sword) but carriesitem_model="mypack:flame_sword", so only this item looks custom. Every other iron sword in the world is untouched. This is the safe, normal choice. - Overriding a vanilla item. If you name your definition file after a vanilla item (say you
create
assets/minecraft/items/iron_sword.jsonin your pack), then the rule that an item’s model is based on theminecraft:item_modelcomponent still applies, but every iron sword defaults to that definition. That changes all iron swords for anyone using your pack. Use this only when you really mean “retexture the vanilla item everywhere.”
Tinting a model
A model type of minecraft:model can recolor parts of its texture without you drawing new art, using
a tint source. The tints field is an optional list of tint sources to apply to the elements of
the rendered model (the first entry applies to tintindex 0, the second to tintindex 1, and so
on). Each entry is a tint source object with its own type. The tint source types are:
minecraft:constant, minecraft:dye, minecraft:firework, minecraft:grass,
minecraft:map_color, minecraft:potion, minecraft:team, and minecraft:custom_model_data.
The simplest is constant, which returns a constant RGB color:
assets/mypack/items/red_blade.json
{
"model": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword",
"tints": [
{
"type": "minecraft:constant",
"value": 16711680
}
]
}
}
value is a packed RGB number, the same decimal-color trick you saw with colors in Chapter 22
(16711680 is pure red). For this to do anything, the model’s texture needs a part marked with
tintindex 0; untinted parts stay their original color. Elements with no tintindex specified
remain untinted.
The most useful tint source for our purposes is minecraft:custom_model_data, which returns a value
from the colors list in the minecraft:custom_model_data component. That’s the fourth row of our
table: the colors list on the item feeds a model tint. Its shape:
assets/mypack/items/dyeable_blade.json
{
"model": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword",
"tints": [
{
"type": "minecraft:custom_model_data",
"index": 0,
"default": 16777215
}
]
}
}
Both fields are simple: index is the index for the field in colors (default 0), and
default is an RGB value used when the item has no color there (16777215 is white). Now one
definition can render in any color you stamp into the item’s colors list: no extra art, no extra
files.
Conditional models: changing look by component state
This is where item definitions earn their keep. Three of the five types choose a model based on the item’s own state at render time.
condition — a yes/no switch
The condition shape is: a type of minecraft:condition, a property (the yes/no test), and two
models, on_true (the items model object used when the property is true) and on_false (used when
the property is false). There are many boolean property values; the handy ones for items include:
minecraft:damaged— “true if the item is damageable and has been used at least once.”minecraft:broken— “true if the item is damageable and has only one use remaining before breaking.”minecraft:using_item— “true if player is currently using this item.”minecraft:selected— “true if item is selected on a hotbar.”minecraft:has_component— “true if the given component is present on the item” (needs an extracomponentfield naming it).minecraft:custom_model_data— returns the value from the flags list in theminecraft:custom_model_datacomponent (this is theflagsrow of our table; it takes an optionalindex).
Here’s a sword that looks battered once it’s been used at all:
assets/mypack/items/worn_blade.json
{
"model": {
"type": "minecraft:condition",
"property": "minecraft:damaged",
"on_true": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword_glow"
},
"on_false": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword"
}
}
}
Notice on_true and on_false each hold a whole items model object, a type: minecraft:model
with its own model field. Model definitions nest: a chooser’s branches are themselves choosers (or
plain models).
select — pick by a named case
A select renders an items model based on a discrete property. Its shape: a type of
minecraft:select, a property, a list of cases, and a fallback. Each case has a when (the
value to match against the property; if it’s a list, it will match any value in it) and a model.
Watch out: fallback is optional, but the game will render a “missing” error model if it’s not
present, so always include one.
The property we care about is minecraft:custom_model_data, which returns the value from the
strings list in the minecraft:custom_model_data component, the strings row of our table. So the
string you put in the item’s data picks the model:
assets/mypack/items/team_blade.json
{
"model": {
"type": "minecraft:select",
"property": "minecraft:custom_model_data",
"index": 0,
"cases": [
{
"when": "red",
"model": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword_glow"
}
},
{
"when": "blue",
"model": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword"
}
}
],
"fallback": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword"
}
}
}
An item carrying custom_model_data={strings:["red"]} draws the glowing blade; ["blue"] draws the
plain one; anything else falls back to plain. (index here is the optional field for the
custom_model_data property, naming which slot of the strings list to read, default 0.)
range_dispatch — pick by a number
A range_dispatch renders an items model based on a numeric property. It selects the last entry
whose threshold is less than or equal to the property value. Its shape: a type of
minecraft:range_dispatch, a property, a list of entries (each an object with a threshold
float and a model), and an optional fallback. A great property here is minecraft:damage, which
returns a value from the minecraft:damage component and, with the default normalize: true,
divides it by the minecraft:max_damage component, clamped to 0.0 to 1.0. So 0.0 is a fresh tool
and 1.0 is about to break:
assets/mypack/items/wear_stages.json
{
"model": {
"type": "minecraft:range_dispatch",
"property": "minecraft:damage",
"entries": [
{
"threshold": 0.0,
"model": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword"
}
},
{
"threshold": 0.5,
"model": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword_glow"
}
}
],
"fallback": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword"
}
}
}
When the sword is below half-damaged it shows the plain blade; cross 50% wear and it switches to the
glow model. The matching custom_model_data source here would be floats (the custom_model_data
numeric property returns the value from the floats list), which is the last row of our table.
Practice — the enchanted flame sword
Goal: a sword that looks plain normally and glows once it carries an enchantment shimmer. In
Chapter 22 you learned the enchantment_glint_override component forces that shimmer on. We’ll have
the model switch on the presence of that component, using condition with the has_component
property (true if the given component is present on the item), with a component field naming which
one.
First, the definition:
assets/mypack/items/flame_sword.json
{
"model": {
"type": "minecraft:condition",
"property": "minecraft:has_component",
"component": "minecraft:enchantment_glint_override",
"on_true": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword_glow"
},
"on_false": {
"type": "minecraft:model",
"model": "mypack:item/flame_sword"
}
}
}
Then two ways to hand out the sword, plain then glowing:
data/mypack/function/give_plain.mcfunction
give @s iron_sword[item_model="mypack:flame_sword"]
data/mypack/function/give_enchanted.mcfunction
give @s iron_sword[item_model="mypack:flame_sword",enchantment_glint_override=true]
The first sword shows flame_sword.png; the second carries the glint component, so has_component
is true and the definition draws flame_sword_glow.png instead. The model changed itself, from data
alone.
Figure (to be captured). the give_enchanted sword in hand — glint shimmer plus the flaming glow texture
Try It! Rebuild this using the Chapter 22 linkage instead of
has_component. Set the condition’spropertytominecraft:custom_model_data(which reads the item’sflagslist), and give the sword withcustom_model_data={flags:[true]}. Same visible result, but now you control the switch with your own data instead of relying on a vanilla component.
What Can Go Wrong
You get a black-and-purple error model. The game couldn’t find the definition the item_model
component named. Minecraft is blunt about this: a nonexistent model will cause the missing model to
be used, rather than falling back to the item ID’s default model. Check that
assets/<namespace>/items/<id>.json exists, that the namespace in item_model matches the folder,
and remember the pointer omits the .json suffix: item_model="mypack:flame_sword", not
"mypack:flame_sword.json".
A select or range_dispatch shows the error model for some items. You forgot the fallback.
It’s optional, but the game will render a “missing” error model if it’s not present, so any item
whose value doesn’t match a case/entry has nothing to draw. Always include a fallback.
Your tint does nothing. A tint source only recolors model parts marked with the matching
tintindex; elements with no tintindex specified remain untinted. A standard
minecraft:item/generated flat item has no tint index unless the model adds one, so a plain custom
texture won’t change color from a tint alone.
You changed every iron sword by accident. You put your definition in
assets/minecraft/items/iron_sword.json instead of under your own namespace. That overrides the
vanilla item for everyone. For a one-off custom look, give your definition its own id under your
namespace and point item_model at it.