Privacy
Language: Suomi

Model part definitions

The fields of a model part definition: which items it matches, how it displays, and the settings that tie its model to your animations.

This page has not been translated into Finnish yet, so it is shown in English. Read in English

On this page

A definition is one .json file that tells Punchy! which held items get their own 3D model in first person, which geometry and texture that model uses, and which clips move it. This page lists the fields of that file that choose the items, files, display, animation entries, model settings, physics and particles, how Punchy! picks one definition for an item, how the model sits in the hand, and what makes Punchy! throw a file away. It is for pack makers who have a model and want it in the hand, and for anyone whose definition does not show.

Before you start

  • Install Punchy! 3.0 or newer from Modrinth or CurseForge. The fields on this page were checked against Punchy! 3.0 for Fabric on Minecraft 26.3.
  • You need a resource pack to put the files in. Resource packs explains how to make one and turn it on.
  • A definition points at a geometry file and a texture. This page gives you a tiny pair to test with. Geometry and textures shows how to make your own.
  • For the Studio steps you need Punchy! Studio, from Modrinth or CurseForge.

What a definition is made of

A model part is a small set of files. Only the definition is found by its folder. Punchy! loads every other file by the exact id you write in the definition, so their folders are your choice. These are the names Studio uses, and the ones this page uses too.

assets/minecraft/punchy/model_parts_items/
  definitions/lantern.json              the definition (this page)
  geo/lantern.geo.json                  the geometry: bones and cubes
  textures/lantern.png                  the texture
  animations/lantern.animation.json     item clips that move the bones
FileRequiredWhat it holds
DefinitionYesThe items it covers, the files it uses, and every setting below.
GeometryYesThe bones and cubes of the model, in Bedrock geometry format.
TextureYesA PNG for the whole model. Single bones can take their own.
Item clipsNoAnimations for the model’s own bones, played by the animation entries of the definition.

The folder is named model_parts_items, and the namespace folder above it can be any name. A definition can sit at any depth under definitions/.

Definitions are not rp_geo_map files. rp_geo_map is a separate resource pack item model path, and this page does not cover it.

Make your first definition

You will make a lantern with a swaying flame that smokes, goes still under water, and swings when you attack. First the four files, then where they go.

Write the files

The geometry has two bones: lantern and its child flame. Every cube lists all six faces, so every face is drawn. This geometry file is saved as geo/lantern.geo.json.

{
  "format_version": "1.12.0",
  "minecraft:geometry": [
    {
      "description": { "identifier": "geometry.lantern", "texture_width": 16, "texture_height": 16 },
      "bones": [
        {
          "name": "lantern",
          "pivot": [0, 0, 0],
          "cubes": [
            {
              "origin": [-3, 0, -3],
              "size": [6, 6, 6],
              "uv": {
                "north": { "uv": [0, 0], "uv_size": [16, 16] },
                "south": { "uv": [0, 0], "uv_size": [16, 16] },
                "east": { "uv": [0, 0], "uv_size": [16, 16] },
                "west": { "uv": [0, 0], "uv_size": [16, 16] },
                "up": { "uv": [0, 0], "uv_size": [16, 16] },
                "down": { "uv": [0, 0], "uv_size": [16, 16] }
              }
            }
          ]
        },
        {
          "name": "flame",
          "parent": "lantern",
          "pivot": [0, 6, 0],
          "cubes": [
            {
              "origin": [-1, 6, -1],
              "size": [2, 3, 2],
              "uv": {
                "north": { "uv": [0, 0], "uv_size": [16, 16] },
                "south": { "uv": [0, 0], "uv_size": [16, 16] },
                "east": { "uv": [0, 0], "uv_size": [16, 16] },
                "west": { "uv": [0, 0], "uv_size": [16, 16] },
                "up": { "uv": [0, 0], "uv_size": [16, 16] },
                "down": { "uv": [0, 0], "uv_size": [16, 16] }
              }
            }
          ]
        }
      ]
    }
  ]
}

The item clips are three small animations. They are saved as animations/lantern.animation.json.

{
  "format_version": "1.8.0",
  "animations": {
    "lantern_sway": {
      "loop": true,
      "animation_length": 2,
      "bones": {
        "lantern": {
          "rotation": { "0": [0, 0, -3], "1": [0, 0, 3], "2": [0, 0, -3] }
        }
      }
    },
    "lantern_still": {
      "loop": true,
      "animation_length": 1,
      "bones": {
        "lantern": { "rotation": [0, 0, 0] }
      }
    },
    "lantern_swing": {
      "animation_length": 0.6,
      "bones": {
        "lantern": {
          "rotation": { "0": [0, 0, 0], "0.3": [-40, 0, 0], "0.6": [0, 0, 0] }
        }
      }
    }
  }
}

The texture is a 16 by 16 PNG saved as textures/lantern.png. In any image editor, make a new 16 by 16 pixel image, fill every pixel with one orange such as #E8861C, and export it as a PNG. Every face of both cubes shows the whole image, so a flat square is enough to see the model, and any other 16 by 16 picture works too.

The definition ties them together. It is saved as definitions/lantern.json.

{
  "items": ["minecraft:lantern", "minecraft:soul_lantern"],
  "geo": "minecraft:punchy/model_parts_items/geo/lantern.geo.json",
  "texture": "minecraft:punchy/model_parts_items/textures/lantern",
  "animations": [
    "minecraft:punchy/model_parts_items/animations/lantern.animation.json"
  ],
  "modelPartsAnimation": [
    { "type": "idle", "name": "lantern_sway" },
    {
      "type": "idle",
      "name": "lantern_still",
      "inside_water": true,
      "disable_all_particles": true,
      "skip_blend_in": true,
      "skip_blend_out": true
    },
    { "type": "attack", "name": "lantern_swing" }
  ],
  "bone_emission": { "strength": 100, "blur": true, "flame": 100 },
  "particles": [
    { "type": "minecraft:smoke", "bone": "flame", "rate": 3 }
  ]
}

What each part does:

  • items covers the lantern and the soul lantern.
  • geo, texture and animations name the three other files by their full ids.
  • The first idle entry plays lantern_sway all the time. The second idle entry is more specific: when your eyes are under water it plays lantern_still instead, cuts to it without blending, and silences the particles.
  • The attack entry plays lantern_swing when you attack with the lantern.
  • bone_emission makes the flame bone glow at full level, with a blur glow around it.
  • particles lets smoke rise from the flame bone, three times a second.

Put them in a pack

  1. In your game’s resourcepacks folder, make a folder called Lantern pack. Inside it, make pack.mcmeta with the text below. The numbers are for Minecraft 26.3; Resource packs has the other versions.

    {
      "pack": {
        "description": "A lantern with a swaying flame",
        "pack_format": 97,
        "min_format": 97,
        "max_format": 97
      }
    }
  2. Beside pack.mcmeta, create the folders assets/minecraft/punchy/model_parts_items/definitions, geo, textures and animations, so that the four folders sit side by side under model_parts_items.

  3. Save the geometry, the item clips, the texture and the definition in their folders, with the names above.

  4. Turn the pack on under Options…, then Resource Packs…. Move it to Selected, and press Done.

  5. Join a creative world and run /give @s lantern. Hold it and switch to first person.

  6. If you edited the files while the world was open, press F3+T to reload the resources. Punchy! reads the definition again, so you do not restart the game.

You should see a small block with a glowing top, swaying in your hand. If you do not, go to Things that drop a whole definition.

Or build it in Punchy! Studio

Studio writes the geometry, the clips and the definition for you, and shows the model in your hand while you edit it.

  1. Join a world, hold a lantern, switch to first person and press F6. If the editor opens in the Third Person perspective, pick First Person with the switch between the menus and the workspace tabs.
  2. Open the Model workspace.
  3. Choose File > New Model Part (Ctrl+N). Type Lantern in Name and minecraft:lantern in Held Item, then press Create. You start with one bone and one textured cube.
  4. Open the Definition tab. In the Items panel, the Items field holds the item ids and #tags of the definition, separated by commas. Add minecraft:soul_lantern.
  5. Choose View > Live Link with Punchy (Ctrl+L). Punchy! now draws your unsaved model in your hand.
  6. Open the Animation tab and use the Add menu to add an item clip with Add Clip and an animation entry with Add Entry. Set the entry’s Type and Clip. For the water entry, set Under Water to Yes, and tick No Particles, Skip Blend In and Skip Blend Out.
  7. Check the Lint panel on the Definition tab. Nothing to report. means Punchy! will load the definition.
  8. Choose File > Export Model Part… (Ctrl+E), pick the Pack, and press Export. Export First in Order is on for a new model part, so the definition is written into 0_punchy_studio and sorts first. Untick it if you do not want that.

Video coming soon

File > New Model Part, then the Definition tab.

Video coming soon

The live link shows your unsaved definition in your own hand.

The smallest definition

Three keys are enough: the items, the geometry and the texture.

{
  "item": "minecraft:lantern",
  "geo": "minecraft:punchy/model_parts_items/geo/lantern.geo.json",
  "texture": "minecraft:punchy/model_parts_items/textures/lantern"
}

Everything else on this page is optional. Without display, Punchy! uses the item’s usual first person transform for each hand.

Which definition covers an item

Punchy! reads every .json file under definitions/ in every active pack and every namespace, at any depth. For each held stack it picks one definition. The rules, in order:

  1. The definitions are sorted by their full id as text, ignoring case, namespace first. Folder and file names therefore decide who wins.
  2. A definition whose items lists the held item is a candidate. The first unnamed candidate in the sorted order wins.
  3. A definition with a customName is a named definition. It wins over every unnamed one when the stack carries that name.
  4. If a named definition covers the item and the held stack does not carry that name, no unnamed definition is used for it. The vanilla model draws.
a_pack:punchy/model_parts_items/definitions/lantern.json              tried first
minecraft:punchy/model_parts_items/definitions/0_first/lantern.json
minecraft:punchy/model_parts_items/definitions/lantern.json

The order of your resource packs does not matter between different ids. If two packs have a definition at the same path in the same namespace, only the one from the higher pack loads. To make a definition win, give its id an early sort: put it in a folder such as definitions/0_first/. Studio’s Export First in Order option does this with a folder named 0_punchy_studio. Resource packs shows the same rule next to the other pack-order rules.

Video coming soon

The Model Parts Library says which definition Punchy! draws.

Match a renamed item

Add customName to cover only stacks that carry a name, such as one renamed on an anvil.

{
  "items": ["minecraft:lantern"],
  "customName": "Sun Lantern",
  "geo": "minecraft:punchy/model_parts_items/geo/sun_lantern.geo.json",
  "texture": "minecraft:punchy/model_parts_items/textures/sun_lantern"
}

A lantern renamed sun lantern or SUN LANTERN matches. The text compared is the stack’s custom name, not its hover text or lore. A plain lantern gets no model part at all, because a named definition now covers lanterns. To keep the plain lantern model as well, you cannot add an unnamed definition for it. Name every variant you want instead.

Fields that choose the item

Item matching
KeyTypeWhat it doesExample
itemsstring arrayThe items the definition covers. Either items or item is required. minecraft:lantern and lantern mean the same item. #minecraft:swords covers every item in that item tag. Each entry is trimmed, and an entry that is not a valid id is skipped. When items is present, item is not read, and an empty list drops the definition.["minecraft:lantern", "#minecraft:swords"]
itemstringOne item id. Read only when items is missing. Use items once you have more than one.minecraft:lantern
customNamestringMakes this a named definition. The held stack must carry a custom name equal to this text, ignoring case and the spaces at both ends. A blank value is ignored, and name is not tried then.Sun Lantern
namestringThe same as customName. Read only when the customName key is missing.

A stack matches by its item, or by a tag it belongs to. Nothing else about the stack counts, apart from the custom name.

Fields that name the files

Files
KeyTypeWhat it doesExample
geoRequiredresource idThe geometry file. Punchy! uses it exactly as written, so write the whole id with the folder and the .geo.json ending. A bad id drops the definition. A file that does not exist does not: the definition stays, draws nothing, and the vanilla model shows.minecraft:punchy/model_parts_items/geo/lantern.geo.json
textureRequiredresource idThe main texture of the whole model. A path under punchy/model_parts_items/textures/ gets .png added when it is missing. Any other path gets textures/ put in front unless it already starts with textures/, and .png added, so minecraft:lantern and minecraft:textures/lantern both mean minecraft:textures/lantern.png.minecraft:punchy/model_parts_items/textures/lantern
animationsresource id arrayItem clip files. Write each id in full, with the .animation.json ending. All files are loaded into one set of clips, and a later file replaces a clip with the same name. When animations is present, animation is not read.["minecraft:punchy/model_parts_items/animations/lantern.animation.json"]
animationresource idOne clip file. Read only when animations is missing.
modelPartsAnimationobject arrayThe animation entries: which clip plays at which moment. See Animation entries.

Ids use lowercase letters, digits, _, -, . and /, with at most one : after the namespace. A capital letter makes the id invalid. Without a namespace, minecraft is used.

Display

display places the model in your hand. Without it, Punchy! uses the vanilla first person transform of the held item for each hand. With it, you write the transform yourself, one entry per hand.

{
  "items": ["minecraft:lantern"],
  "geo": "minecraft:punchy/model_parts_items/geo/lantern.geo.json",
  "texture": "minecraft:punchy/model_parts_items/textures/lantern",
  "display": {
    "firstperson_righthand": {
      "rotation": [0, 20, 0],
      "translation": [0, -16, 32],
      "scale": [1, 1, 1]
    },
    "firstperson_lefthand": {
      "rotation": [0, 20, 0],
      "translation": [0, -16, 32],
      "scale": [1, 1, 1]
    }
  }
}
The display object
KeyTypeWhat it does
firstperson_righthandobjectThe transform for the right hand. Used when the object has no thirdperson_righthand.
firstperson_lefthandobjectThe transform for the left hand. Used when the object has no thirdperson_lefthand.
thirdperson_righthandobjectIf it is there, Punchy! uses it for the right hand and ignores firstperson_righthand.
thirdperson_lefthandobjectIf it is there, Punchy! uses it for the left hand and ignores firstperson_lefthand.
Inside a display entry
KeyTypeDefaultWhat it doesExample
rotation3 numbers[0, 0, 0]Degrees around X, Y and Z. For the left hand, Y and Z are negated.[0, 20, 0]
translation3 numbers[0, 0, 0]Moves the model. 16 units move it one pixel of the model, which is 1/16 of a block, so one unit is 1/256 of a block. For the left hand, X is negated.[0, -16, 32]
scale3 numbers[1, 1, 1]Multiplies the model along each axis.[1.2, 1.2, 1.2]

Some things to know:

  • Write both hands. A hand with no entry uses the vanilla transform, not the other hand’s.
  • Use the same numbers for both hands. Punchy! mirrors the model for the left arm and flips the signs above, so the left hand looks like the right.
  • An array with fewer than three numbers is read as the default. A value that is not an array drops the whole definition.
  • Model parts draw only in your own first person hands. The inventory, the other players’ hands and third person still show the vanilla item, so display only changes what you see in your hands.

Video coming soon

Studio's Display tab, with the model moving in your hand as you type.

In Studio, the Display tab has a Right Arm and a Left Arm panel. When the definition has no display entry for an arm, that panel shows only Use Vanilla First Person, ticked. Untick it to add an entry, and the Rotation, Translation and Scale rows appear. Ticking it again removes the entry for that arm.

Animation entries

modelPartsAnimation is a list of entries. Each entry says: at this moment, in these conditions, play this clip from the item clip files. Item clips move the model’s bones. They play next to the first person clip that moves the arms.

{
  "modelPartsAnimation": [
    { "type": "idle", "name": "lantern_sway" },
    { "type": "idle", "name": "lantern_rain", "weather_detection": { "raining": true } },
    { "type": "attack", "name": "lantern_swing", "items": ["minecraft:lantern"] },
    { "type": "hand_in", "name": "lantern_raise", "skip_blend_in": true }
  ]
}

If a moment has no entry, Punchy! plays the idle entry instead. With no idle entry either, the model stays in its rest pose.

Types

The type of an entry says which moment it is for. Case, underscores, hyphens and spaces are ignored, so useItem, use_item and Use-Item are the same.

TypePunchy! asks for it whenLoops
idleNothing else is happening. It is also the fallback when a moment has no entry or no clip.Yes
attackYou attack.No
miningYou mine a block.Yes
useItemYou use the item: draw a bow, charge a crossbow, throw a trident, use a spear, or use another item such as a bucket or a goat horn.While you hold the use key on an item that stays in use, such as a bow, crossbow, trident or spear. A bucket or a goat horn plays once per use.
useDrinkYou drink.No
useEatYou eat.No
fishingrodYou cast or reel in a fishing rod. throw names the clip of the cast and pull the clip of the reel.No
fallingYou fall.Yes
hand_inThe item comes up into your hand (equip).No
hand_outThe item goes away (put away).No
inspectYou press the Inspect key.No
triggerableYou press a custom animation key.No
in_waterNothing asks for it directly. An entry of this type is only a candidate when idle is asked for. To tie a clip to water, give an idle entry the in_water or inside_water key instead.Yes

When several of these start at the same time, the higher one wins: attack, triggerable, inspect, hand_out, hand_in, mining, the cast and reel of fishingrod, useItem, then useDrink and useEat, then any other type, then idle.

While you use an item, Punchy! lets the vanilla model draw it, unless the definition has an entry of a use or consume type, such as useItem, useDrink or useEat, or a using state model. If you want your model to stay while you eat or draw a bow, add an entry of the matching type.

Keys of an entry

Keys of a modelPartsAnimation entry
KeyTypeDefaultWhat it doesExample
typeRequiredstringThe moment this entry is for. See the table above. An entry with no type never matches.idle
namestringThe clip to play, as named in the item clip file. Punchy! also reads animation and var_1, and takes the first of animation, name, var_1 that is not blank. For the right hand it tries <name>_right first, for the left hand <name>_left, then the bare name, then the name with the definition's namespace in front. If no clip is found, Punchy! plays the idle clip. When the left hand plays a clip whose name ends in _left, the pose is mirrored on X.lantern_sway
throw, pullstringOnly in a fishingrod entry: the clip that plays when you cast and the clip that plays when you reel in. Also read as throw_animation, cast, start_cast, pull_animation, reel and reel_in. Left out, the clip named by animation, name or var_1 plays for both."rod_cast"
itemsstring arrayevery item of the definitionLimits the entry to stacks that match this list of ids or #tags. Use it when one definition covers several items that need different clips.["minecraft:soul_lantern"]
in_waterbooleanThe player touching water must equal this. True when the player is in water, the eyes are in water, or any of 27 points around the body is water. false means not touching water.true
inside_waterbooleanThe eyes being under water must equal this. When true, the entry also stays matched for a tick or two after you leave the water.true
block_detectionobjectA block near the player. See Conditions.
weather_detectionobjectRain, thunder or clear sky. See Conditions.
time_detectionobjectA window of the day. See Conditions.
biome_detectionobjectA biome or biome tag. See Conditions.
keep_loopingstringThe name of a clip that loops after this entry's clip ends. The entry also stays matched for a few ticks when its conditions flicker (weather entries excepted).lantern_sway
skip_blend_inbooleanfalseCut into this clip with no blend. Without it, Punchy! blends over 0.4 seconds when a clip takes over from a clip that is still playing, and over 0.6 seconds when the idle clip starts after a clip has ended or replaces another idle clip.true
skip_blend_outbooleanfalseOn the entry that is playing: when another entry takes over or the clip stops, cut with no blend out.true
blend_from_current_originbooleanfalseStarts the blend into this clip from the pose the model shows at that moment. Also read as blendFromCurrentOrigin, rebase_blend_in and rebaseBlendIn.
disable_swim_animationbooleanfalseWhile you hold a stack this entry's items filter matches, Punchy! does not play the swim pose on that hand. It works even when this entry is not the one playing.
disable_all_particlesbooleanfalseWhile this entry plays, no particle emitter of that hand emits.
disable_physics_bonesstring arrayBones that ignore pendulum physics while this entry plays. When the key is there, even as an empty list, it replaces the definition's own disable_physics_bones list. Also read as disable_pendulum_bones.["flame"]

A list field given as text, such as "items": "minecraft:lantern" inside an entry, drops the whole definition.

Conditions

An entry can ask about the world around the player. All conditions on an entry must pass. These objects go in the entry, next to type.

Condition objects
KeyTypeDefaultWhat it doesExample
block_detection.blocksstring arrayBlock ids or #tags. One of them must be in the search area. With no target at all, the condition passes.["minecraft:water", "#minecraft:logs"]
block_detection.blockstringOne block id or tag. Read only when blocks is empty or missing.
block_detection.radiusinteger0A cube around the search origin, in every direction. 0 checks one block. A negative value counts as 0.
block_detection.offsetX, offsetY, offsetZinteger0Moves the search origin from the player's block position.
weather_detection.rainingbooleanMust match rain: true when the world is raining or rain falls on the player. When true, rain keeps counting for about two seconds after it stops.true
weather_detection.thunderingbooleanMust match thunder. Thunder counts only while it rains.
weather_detection.clearbooleantrue means not raining and not thundering.
time_detection.mininteger-1Start of the window, on the day clock from 0 to 23999. -1 means no lower bound.13000
time_detection.maxinteger-1End of the window. -1 means no upper bound. When min is above max, the window runs through midnight.23000
time_detection.rangetwo integersA shorter way to write min and max. When it has two values, it replaces both.[13000, 23000]
biome_detection.biomesstring arrayBiome ids or #tags. One of them must be in the search area. With no target at all, the condition passes.["#minecraft:is_ocean"]
biome_detection.biomestringOne biome id or tag. Read only when biomes is empty or missing.
biome_detection.radiusinteger0A cube around the search origin, as for blocks.
biome_detection.offsetX, offsetY, offsetZinteger0Moves the search origin, as for blocks.

An id with no : gets the minecraft namespace. A leading # makes it a tag.

{
  "type": "idle",
  "name": "lantern_night_swamp",
  "time_detection": { "range": [13000, 23000] },
  "biome_detection": { "biomes": ["minecraft:swamp", "minecraft:mangrove_swamp"] }
}

Conditions goes through each check with more examples.

Which entry plays

When Punchy! asks for a moment, it goes through the list like this:

  1. It keeps the entries whose type is that moment, whose items filter matches the stack and whose conditions all pass.
  2. Each kept entry gets a score: inside_water is worth 3, in_water 2, and each of block_detection, weather_detection, time_detection and biome_detection 1. The score adds up the conditions the entry writes. Only entries whose conditions pass are scored.
  3. The entry with the highest score wins. Equal scores keep the order of the file, so the first one wins. Entries with no conditions have a score of 0 and are used only when no scored entry passes. Among those, the first in the file wins.

So an idle that asks for rain beats a plain idle while it rains, and an idle that asks for water beats both. You can list several idle entries side by side.

Model settings

These keys change how the model looks. Each one is optional. Names of bones must match the bones of the geometry exactly, capital letters included. Only bone_textures also accepts a name that differs in capitals. Every snippet below is a complete JSON object so you can check it on its own. To use one, copy the key and its value into your definition.

Glow

bone_emission makes bones glow. It is an object of bone names to levels, plus a few settings.

{
  "bone_emission": { "strength": 100, "blur": true, "clamp": false, "flame": 100, "wick": 12 }
}
Inside bone_emission
KeyTypeDefaultWhat it doesExample
<bone>number 0 to 1000The glow level of that bone, from a JSON number. Values from 1 to 15 set how bright the glow overlay is. Values above 15 add bloom, and the bloom shows only when blur is on. 0 is no glow. The name must match exactly, and child bones do not inherit it.100
blurbooleanfalseAdds a second, larger glow pass around glowing bones, and filters the glow texture smoothly.true
clampbooleanfalseSamples the glow texture clamped to its edge instead of repeating it.
strengthinteger 0 to 100100One multiplier for every bone's glow. Also read as intensity and brightness; they are the same setting. The key names blur, clamp, strength, intensity and brightness are reserved, so a bone with one of those names cannot glow.

Bone textures

bone_textures gives single bones their own texture. Use the object form for a few bones, or the list form to give one texture to many.

{
  "bone_textures": { "flame": "minecraft:punchy/model_parts_items/textures/flame_lit" }
}
{
  "bone_textures": [
    { "texture": "minecraft:punchy/model_parts_items/textures/glass", "bones": ["window_left", "window_right"] }
  ]
}

The texture ids are written like texture. Punchy! finds a bone’s texture by its exact name, then by a match that ignores case, then up through the parent bones, and falls back to the main texture. In the list form, a later entry replaces an earlier one for the same bone.

Texture animation

An animated texture is one PNG with the frames stacked from top to bottom.

{
  "texture_anim": { "frames": 4, "frametime": 3, "frame_height": 16 },
  "bone_texture_anim": {
    "flame": { "frames": 6, "frametime": 2, "frame_height": 16 }
  }
}
Inside texture_anim and each bone_texture_anim entry
KeyTypeDefaultWhat it doesExample
framesinteger1How many frames are stacked in the PNG. It is at least 1. With 1, nothing animates.4
frametimeinteger1Game ticks each frame lasts. It is at least 1.3
frame_heightinteger0The height of one frame in pixels. 0 means the geometry's texture height. It is at least 1 when written.16

texture_anim animates every bone texture that has no animation of its own. bone_texture_anim is an object of bone names to the same three keys, and applies to that bone only. A bone entry does not inherit values from texture_anim: a value you leave out becomes 1, 1 and 0.

The PNG must be exactly frames times the frame height tall. When it is not, the texture stays still and Punchy! says nothing.

Dynamic textures

dynamic_bone_textures swaps one bone’s texture, or the whole geometry, by what the held item holds. It is an object or a list of specs. The alias dynamicBoneTextures is read only when dynamic_bone_textures is missing.

{
  "dynamic_bone_textures": {
    "type": "texture",
    "bone": "contents",
    "source": "axol_variants",
    "fallback": "minecraft:punchy/model_parts_items/textures/axolotl_pink",
    "map": { "blue": "minecraft:punchy/model_parts_items/textures/axolotl_blue" }
  }
}
Keys of a dynamic spec
KeyTypeDefaultWhat it does
typestringtexturetexture swaps the texture of one bone. geo swaps the whole geometry. Any other value counts as texture.
bonestringThe bone to retexture. Required for texture, ignored for geo.
sourcestringsulfur_cube_contentWhat picks the map entry. sulfur_cube_content uses the item id of the block a sulfur cube has absorbed. axol_variants uses the variant of the bucketed axolotl. Case does not matter. Any other value matches nothing, so only the fallback applies.
mapobjectMaps what the source reports to a texture id, or a geometry id for geo. A texture id is written like texture. A geometry id is not read the way the top-level geo is: when it does not start with punchy/model_parts_items/geo/, geo/ is put in front unless it already starts with geo/, and .geo.json is added when it is missing. Writing the full id works only when it starts with punchy/model_parts_items/geo/ or geo/, so keep the geometry files you swap in under one of those two folders.
fallbackresource idUsed when the map has no entry for what the source reports. It is written the same way as the ids in map.

Dynamic textures has the full walk-through.

Mirroring

bone_mirror flips the animation keys of a bone in every item clip of the definition. Each bone takes a boolean, or an object with position and rotation booleans.

{
  "bone_mirror": { "flame": { "position": false, "rotation": true } }
}

Only false does something. It negates the X position of the keys, and the X and Y rotation. true does nothing. A plain false does both. A position or rotation that is an object drops the whole definition.

Camera transparent bones

{
  "camera_transparent_bones": ["glass"]
}

The faces of these bones, and of the bones under them, that turn away from you are not drawn. It helps glass and flames that you look at from inside. It does not apply to a bone that has physics. The alias inside_visible_bones is read only when camera_transparent_bones is missing.

State models

A state model changes the definition for one situation, most often only its geometry. Every key you leave out of a state stays as the definition has it.

{
  "state_models": {
    "using": { "geo": "minecraft:punchy/model_parts_items/geo/lantern_raised.geo.json" },
    "fishing_rod_cast": { "geo": "minecraft:punchy/model_parts_items/geo/rod_cast.geo.json" }
  }
}
StatePunchy! draws it when
usingYou use this item with this hand.
fishing_rod_castYou are fishing with this item in this hand. It wins over using.

The state names are not case sensitive. The geo is used as written, like the main geo. A state can also hold other keys of a definition, such as texture. Particle lists in a state are added to the definition’s own, bone_emission, bone_textures, bone_texture_anim, bone_physics and display are merged key by key with the definition’s, and any other key replaces the definition’s. A using state model also keeps the model visible while you use the item. In Studio, the State Models panel on the Definition tab edits these, and the State switch in the stage header previews them.

Fishing rod line

Two keys help a fishing rod whose model draws its own line. They matter only for minecraft:fishing_rod. Punchy! reads them from the definition that draws the rod in your hand, chosen as in Which definition covers an item, so a named definition can carry its own.

{
  "items": ["minecraft:fishing_rod"],
  "geo": "mypack:punchy/model_parts_items/geo/fishing_rod.geo.json",
  "texture": "mypack:punchy/model_parts_items/textures/fishing_rod",
  "fishing_line_anchor": { "bone": "rod_tip", "position": [0, 9.5, 0.85] },
  "hide_bones_while_cast": ["hanging_line"]
}
Fishing rod keys
KeyTypeWhat it doesExample
fishing_line_anchorobjectWhere the cast fishing line starts in first person. bone is a bone of the geometry. position is exactly three numbers, in pixels inside that bone, as Blockbench shows them. Any other position means no anchor, and the line keeps its normal start.{ "bone": "rod_tip", "position": [0, 9.5, 0.85] }
hide_bones_while_caststring arrayBones hidden, together with every bone under them, while your hook is out and that hand holds the rod. Use it to hide a line that is drawn into the model.["hanging_line"]

Neither key has a default: with no anchor the line starts where it normally does, and with no list nothing is hidden. Both keys work on every Minecraft version and loader. Studio has no fields for these keys and keeps them as you wrote them.

Axolotl feedback

{
  "physicsFeedback": true
}

Turns on the axolotl style feedback pose. It does something only for geometry shaped like an axolotl: a head bone, a body or body_root bone, and a legs_front or leg1 bone. The aliases fallingFeedBack and fallingFeedback are read when the key before them is missing. Studio calls it Axolotl Feedback.

Physics keys

Pendulums, creature feedback and slime squash are set per bone in bone_physics. The alias bonePhysics is read only when bone_physics is missing. The value is an object of bone names to specs, or a list of such objects; the specs for one bone are merged. A spec can also be a list of specs, or just true, which turns on creature feedback and slime squash for that bone with no pendulum.

{
  "bone_physics": {
    "flame": { "pendulum_mode": "full", "limit_deg": 25, "gravity": 0.8 },
    "contents": { "enableSlimePhysics": true, "slimeImpactPercent": 60 }
  },
  "disable_physics_bones": ["lantern"]
}

A spec needs a pendulum_mode, or enableCreaturePhysics, or enableSlimePhysics (or one of their aliases, listed below). Without one of them, Punchy! drops that spec.

Keys of a bone physics spec
KeyTypeDefaultWhat it doesExample
pendulum_modestring or booleannoneHow the bone swings. full (also pendulum_full, full_pendulum, or true) swings freely. forward (also pendulum_forward, forward_pendulum) swings along the view. Hyphens and spaces count as underscores. Also read as pendulumMode, pendulum and physics_mode.full
enableCreaturePhysicsbooleanfalseCreature style feedback on this bone. Also read as creature and puffer.
enableSlimePhysicsbooleanfalseSlime squash on this bone. Also read as slime and slimeBlock.
limit_degnumberHow far the pendulum may swing, in degrees. Also read as limitDeg, pendulum_limit_deg and pendulumLimitDeg. Left out, Punchy! uses its own default.
limit_deg_upnumberThe upper limit. Also limitDegUp, pendulum_limit_deg_up, pendulumLimitDegUp.
limit_deg_downnumberThe lower limit. Also limitDegDown, pendulum_limit_deg_down, pendulumLimitDegDown.
forcenumberThe pendulum force. Also pendulum_force, pendulumForce.
speednumberThe pendulum speed. Also pendulum_speed, pendulumSpeed.
camera_sensnumberHow much turning the camera moves it. Also cameraSens, pendulum_camera_sens, pendulumCameraSens.
gravitynumberThe pendulum gravity. Also pendulum_gravity, pendulumGravity.
motion_sensnumberHow much walking moves it. Also motionSens, pendulum_motion_sens, pendulumMotionSens.
invertbooleanInverts the swing. Also pendulum_invert, pendulumInvert.
impactInclinationPercentnumber 0 to 100100Scales the tilt on the side it leans while you fall or tilt the camera down, from 0 to 100. A bigger value counts as 100. Also impact_inclination_percent, impactInclination, impact_inclination, landingInclinationPercent, landing_inclination_percent, landingInclination, landing_inclination.
fallInclinationPercentnumber 0 to 100100Scales the tilt on the other side, which is the punch of a landing and the lean when you tilt the camera up. Also fall_inclination_percent, fallInclination, fall_inclination, upwardInclinationPercent, upward_inclination_percent, upwardInclination, upward_inclination.
impactTranslationPercentnumber 0 to 100100Scales the vertical and depth (Y and Z) shift during the lean of impactInclinationPercent. Also impact_translation_percent, landingTranslationPercent, landing_translation_percent, impactTranslation, impact_translation, landingTranslation, landing_translation.
fallTranslationPercentnumber 0 to 100100Scales the same shift during the lean of fallInclinationPercent. Also fall_translation_percent, upwardTranslationPercent, upward_translation_percent, fallTranslation, fall_translation, upwardTranslation, upward_translation.
slimeImpactPercentnumber 0 to 100100Scales the slime squash at take-off and landing. Also slime_impact_percent, impactSlimePercent, impact_slime_percent, slimeImpact, slime_impact.
slimeFallPercentnumber 0 to 100100Scales the slime stretch while falling. Also slime_fall_percent, fallSlimePercent, fall_slime_percent, slimeFall, slime_fall.

When you merge several specs for one bone, a percentage of exactly 100 never replaces an earlier value, because 100 is the default.

disable_physics_bones takes bones out of the item’s pendulum physics, along with the bones under them. The alias disable_pendulum_bones is read only when disable_physics_bones is missing. An animation entry that sets its own disable_physics_bones replaces this list while it plays. A bone with physics takes the nearest parent’s spec, not a merge of all of them.

Item physics explains the tuning side of the same effects, and Studio’s Physics tab has presets and a test rig.

Particles

particles lists emitters that spawn from a bone. The keys particle, particle_effects, particle_emission and particleEmission are read too, and all five are added together. Each emitter is written in one of three forms.

{
  "particles": [
    "minecraft:smoke",
    "type=minecraft:flame,bone=flame,rate=4",
    { "type": "minecraft:smoke", "bone": "flame", "rate": 3, "enabled": true }
  ]
}
  • A bare particle id emits that particle with its defaults.
  • Text with = is a list of key=value pairs separated by commas. particle(...) around the pairs is optional.
  • An object writes the same keys as JSON. Numbers, booleans and text work. A list of three numbers is read as x:y:z.

Two object keys are about the emitter itself. enabled set to false turns the emitter off. triggers must be an object of flags such as jump, landing, walking, sprinting, swimming, attacking and mining. A list there is not read. Particles lists every key and trigger, and the settings that switch particles and their glow off for the whole game are below.

Settings that affect every definition

These are Punchy!‘s own settings, not keys of a definition.

SettingWhereEffect
Resource Pack Model PartsItems & WorldWhen it is off, no model part loads or draws. A change shows after you press F3+T.
Enable Particle SystemEffectsWhen it is off, no model part emits particles.
Enable Model Parts GlowEffectsWhen it is off, the particles of model parts lose their glow and full brightness. The particles still appear. The glow of bone_emission does not depend on it.
Enable Boat/Minecart/Raft Models, Enable Piston Effects, Enable Chest Effects, Enable Enchanting EffectsItems & WorldPunchy! draws its own models for these held items, before it looks at model parts. Turn the matching option off to let a definition draw the item instead.

Open the F8 menu to reach them. Settings and controls shows where they are.

Things that drop a whole definition

Punchy! checks a definition when it loads the resources. If anything below is wrong, it removes the whole file and writes no message. The items stay vanilla.

What is wrongExample
The file is not valid JSON, or its top level is not an object.A missing comma. A list [ ... ] at the top.
No item.No items and no item. items is an empty list. items holds only blank text.
No geo, or the id is not valid.geo missing. A capital letter in the id.
No texture, or the id is not valid.texture missing.
A value of the wrong JSON type.items, animations or modelPartsAnimation that is not a list. display, or one of its hand entries, that is not an object. rotation, translation or scale that is not an array. Text that is not a whole number where a number belongs in texture_anim or a bone_texture_anim entry. A field of an animation entry that holds a list or an object where one value belongs, or one value where a list or an object belongs, such as "items": "minecraft:lantern".

Fix the file and press F3+T. In Studio, the Lint panel on the Definition tab names the reason: Punchy drops this definition, followed by what it found.

Things that keep a definition but draw nothing

These leave the definition in place. It still covers its items, so it hides later definitions for the same items, and the vanilla model draws.

  • The geometry file is missing or broken. Punchy! does not check that the file exists when it reads the definition. A geometry with no minecraft:geometry list, no bones, or a bone without a name does not load.
  • The item is drawn by another renderer. Held chests, boats, rafts, minecarts, pistons and the enchanting table use Punchy!‘s own models first. See the settings above.
  • You are using the item. While you eat, drink or draw a bow, the vanilla model draws, unless the definition has a matching entry or a using state model.
  • A named definition covers the item. A stack without that name gets no model part. See Match a renamed item.
  • Another definition sorts earlier. Your definition is shadowed. See Which definition covers an item.

If Resource Pack Model Parts is off, no definition loads at all. Turn it on under Items & World in the F8 menu, then press F3+T.

The texture id is not checked when the definition loads. If the model shows wrong or not at all, open the pack and check that a file sits at the id you wrote.

A few smaller things are skipped without a message. An entry names a clip that is not in the file, so the idle clip plays. A physics spec has no mode, so it is dropped. An item clip file with a broken clip keeps the clips before it and loses the clips after it. A texture animation whose PNG is not frames times frame height tall stays still.

Last checked against the mod on 29 October 2026.