How attachables work
By default, custom items in Minecraft Bedrock render as extruded 2D sprites generated from their item texture, while custom armor items do not show anything on the player body unless configured. An attachable overrides this default rendering by wrapping a 3D model, texture, material, and animation set into a mini client-entity definition that attaches to the holder's skeleton.
Attachable JSON files live in the resource pack under the RP/attachables/ folder. The game links an attachable to a behavior pack item strictly by matching the identifier string inside the description block. When a player or mob holds or equips the item with that identifier, the client looks up the attachable and runs its render controllers.
Because attachables only control how an item looks when equipped on an entity, they do not change the 2D icon shown in the inventory slot, hotbar, or item frame. You still define the 2D inventory icon using the standard minecraft:icon component in your behavior pack item file.
Basic attachable definition
The structure of an attachable file closely mirrors a client entity file. Inside the description object, you declare the item identifier, map short names to actual resource identifiers for textures, geometry, and materials, and list the render controllers that put them together.
For armor or worn items, the bones in your custom geometry must share the exact names of the humanoid bones they are meant to follow (such as head, body, leftArm, rightArm, leftLeg, and rightLeg) and share the same pivot points. During rendering, the game automatically snaps bones with matching names in your attachable geometry to the pose of the parent entity's skeleton.
{
"format_version": "1.10.0",
"minecraft:attachable": {
"description": {
"identifier": "wiki:ruby_chestplate",
"materials": {
"default": "armor",
"enchanted": "armor_enchanted"
},
"textures": {
"default": "textures/models/armor/ruby_layer_1",
"enchanted": "textures/misc/enchanted_item_glint"
},
"geometry": {
"default": "geometry.humanoid.armor.chestplate"
},
"scripts": {
"parent_setup": "variable.chest_layer_visible = 0.0;"
},
"render_controllers": [
"controller.render.armor"
]
}
}
}Description fields reference
Every attachable uses the description object to register its assets and execute Molang logic. Most keys map a local short name (like default or enchanted) to a global resource identifier defined elsewhere in your resource pack.
| Field | What it does | Notes |
|---|---|---|
| identifier | Binds this attachable to the item with the exact same identifier. | Can also target vanilla items if you want to override their 3D model. |
| materials | Maps short names to material definitions such as armor, entity, or entity_alphatest. | Include an enchanted material entry if your render controller shows the glint texture. |
| textures | Maps short names to file paths relative to the resource pack root. | Do not include the .png extension in the path. |
| geometry | Maps short names to model identifiers defined in RP/models/entity/. | Bone names in the model dictate where the item attaches on the wielder. |
| animations | Maps short names to animations or animation controllers. | Used to position held items in first and third person or animate moving parts. |
| scripts | Runs Molang expressions at specific points in the render lifecycle. | Supports initialize, pre_animation, animate, and parent_setup. |
| render_controllers | Lists the render controllers that combine geometry, material, and texture. | controller.render.armor and controller.render.item_default are built-in options. |
Held items and perspective animations
Unlike armor, which drapes over multiple body bones, a held 3D item is usually bound to a single bone named rightItem or leftItem inside its geometry file. Because the camera angle and arm posture differ drastically between first-person view and third-person view, a single static model will rarely look right in both views out of the box.
To solve this, creators pair a held attachable with two positioning animations: one that rotates and translates the bone for first-person view, and another for third-person view. You trigger the right animation inside the scripts.animate array using the c.is_first_person Molang query.
In format version 1.10.0, each entry in the scripts.animate array can be an object where the key is the short name of the animation and the value is the Molang condition under which it runs.
{
"format_version": "1.10.0",
"minecraft:attachable": {
"description": {
"identifier": "wiki:heavy_hammer",
"materials": {
"default": "entity_alphatest",
"enchanted": "entity_alphatest_glint"
},
"textures": {
"default": "textures/items/heavy_hammer_3d",
"enchanted": "textures/misc/enchanted_item_glint"
},
"geometry": {
"default": "geometry.wiki_heavy_hammer"
},
"animations": {
"wield_first_person": "animation.wiki_heavy_hammer.first_person",
"wield_third_person": "animation.wiki_heavy_hammer.third_person"
},
"scripts": {
"animate": [
{
"wield_first_person": "c.is_first_person"
},
{
"wield_third_person": "!c.is_first_person"
}
]
},
"render_controllers": [
"controller.render.item_default"
]
}
}
}Interacting with the wearer via parent_setup
When a player equips a helmet or chestplate, the player's second skin layer (hat, jacket, sleeves, or pants) can clip through tight-fitting custom armor models. Attachables provide a special script key called parent_setup that executes Molang in the context of the wearing entity before the entity renders.
By setting standard player visibility variables to 0.0 inside parent_setup, you can hide the outer skin layer of the body part covered by your item. For example, setting variable.helmet_layer_visible = 0.0; hides the player's hat layer while the helmet is worn, and variable.boot_layer_visible = 0.0; hides the lower pant cuffs.
You can also use scripts.pre_animation inside the attachable to compute custom Molang variables for the attachable itself, such as switching texture arrays or scaling bones based on entity queries like q.is_sneaking or q.main_hand_item_use_duration.
Which versions this applies to
Attachables using format_version 1.10.0 are stable across modern Bedrock releases (1.16.100 and newer) and do not require any experimental toggles. Note that if an item uses the minecraft:wearable component in recent versions (1.20.80+) without a custom attachable, the game may attempt to render a default armor layer unless an attachable overrides it.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| Content Log shows: [Geometry][error] ... Geometry 'geometry.my_item' not found, and the item is invisible when held. | The geometry identifier in the attachable does not match the identifier inside your RP/models/entity/ file, or the model uses an older format version without proper identifier registration. | Open the model JSON in RP/models/entity/, check the description.identifier string under minecraft:geometry, and make sure it matches the value in the attachable's geometry block. |
| The 3D item renders at the player's feet or floats detached from the hand in third-person view. | The root bone in the 3D model is not named to match a bone on the player's skeleton. | Rename the parent bone of your held item model to rightItem (case-sensitive) and place its pivot near the grip of the item. |
| Armor or held item renders bright pink and black (missing texture) when enchanted. | The attachable uses controller.render.armor or controller.render.item_default, both of which expect a texture short-named 'enchanted' and a material short-named 'enchanted' to exist when the item has enchantments. | Add the 'enchanted' key to both the materials object and the textures object (pointing to 'textures/misc/enchanted_item_glint') in your attachable description. |
| The inventory icon is still flat even though the attachable loads without errors. | Attachables only render when the item is equipped or held by an entity in the world; they do not replace the 2D UI icon. | Render a 2D image of your model to a PNG file and assign it to the item using RP/textures/item_texture.json and the minecraft:icon component in the behavior pack. |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
