Compat rules
Write compat files that tune how Punchy! holds items: groups, patterns, per-item entries, empty hand, poses and proxies, and which rule wins.
-
Punchy! Studio
This page has not been translated into Simplified Chinese yet, so it is shown in English. Read in English
On this page
A compat file is a small JSON file inside a resource pack. It tells Punchy! how to hold and animate items: where each item sits in the hand, which clips play for it, how the arm and the arm mesh are placed, and what the empty hand does. This page is for pack makers who want to tune a whole kind of item, a group of items or one single item, and know which rule wins when several apply.
Before you start
- Punchy! 3.0 or newer and a resource pack of your own: a folder in
resourcepackswith apack.mcmetaand anassetsfolder. If you have none yet, Resource packs shows how to make one. - Clips come from animation files. A compat file only says which clip plays for which item and where the item sits. To make the clips, read Create an animation.
- A text editor, or Punchy! Studio if you prefer fields to JSON. Both paths are below.
Make your first compat file
This file tilts every sword, makes golden tools a little bigger, and gives the diamond sword its own position. Copy it, then read the reference to change it.
- In your pack, create the folder
assets/minecraft/punchy/compat/. - Inside it, create a file named
my_tuning.jsonand paste the example below. - Open Options, then Resource Packs…, move your pack from Available to Selected, the right-hand list, and press Done.
- Join a world and press F3+T to reload resources. Punchy reads its compat files again on every reload.
- Hold an iron sword, then a golden pickaxe, then the diamond sword. Each one now sits the way the file says.
{
"globalItem": {
"right": { "scale": 1.0, "offY": -0.02 },
"left": { "scale": 1.0, "offY": -0.02 }
},
"customGroups": [
{
"name": "gold_tools",
"items": ["minecraft:golden_pickaxe", "minecraft:golden_axe", "minecraft:golden_shovel"]
}
],
"item": {
"SWORD": {
"pattern_matching": "sword",
"disable_sprint_lateral_tilt": true,
"transforms": {
"right": { "scale": 1.0, "offY": -0.05, "rotZ": 8.0 },
"left": { "scale": 1.0, "offY": -0.05, "rotZ": -8.0 }
},
"physics": { "name": "FORWARD_PENDULUM", "limitDeg": 25.0, "speed": 1.0 }
},
"gold_tools": {
"transforms": {
"right": { "scale": 1.1, "rotX": 10.0 },
"left": { "scale": 1.1, "rotX": 10.0 }
}
}
},
"itemSpecific": {
"minecraft:diamond_sword": {
"kind": "SWORD",
"transforms": {
"right": { "scale": 1.0, "offY": -0.08, "rotZ": 12.0 },
"left": { "scale": 1.0, "offY": -0.08, "rotZ": -12.0 }
}
}
}
}
Every pose in this file has a scale. A pose without one is drawn at size 0 and the item vanishes. Punchy does not copy the right side to the left, so write both sides. When you mirror a pose by hand, flip the sign of offX, rotY, rotZ and pivotX, as the rotZ values do here.
Write the file in the Bindings workspace
Punchy! Studio’s Bindings workspace writes the same files for you. It checks the JSON as you go and tells you when Punchy would ignore a whole file.
- Join a world, hold a sword, 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.
- Open the Bindings workspace with Ctrl+B. The first entry in the Rules outliner is your destination pack: the pack this animation was last exported to, or My Punchy Animations until you pick another in the Export to Resource Pack window. The next export (Ctrl+E) writes its files.
- Select the destination pack and press New Compat File. Type a File Name such as
my_tuning. Use lowercase letters, digits and_,.,-or/. The new file is selected, and it is empty. - With the new file selected, press Edit as Text, type
{ "item": { "SWORD": {} } }and press Apply.SWORDnow shows under theitemsection. To add more targets later, select a section and press Add Target. In theitemsection the dialog asks for a Group, for exampleSWORD, a custom group name or arelated:key. InitemSpecificit asks for an Item id such asminecraft:diamond_sword. - With the target selected, the Target panel holds Kind, Arm Kind and Pattern (or Custom Name for a single item). The Transforms panel has a Hand switch, Scale, Offset, Rotation and Pivot. A new side starts at scale 1.
- Select the file itself to edit Custom Groups, Global Transforms and Proxies. Edit as Text opens the whole file as JSON.
- Press Ctrl+Enter to Apply, then Ctrl+E to export. Keep Activate the pack and play it now ticked. The game reloads and the editor closes by itself, so you can check the item in your hand.
To bind your clip to an item, you do not need a file of your own. In the Bindings workspace, New Rule for This Clip (Ctrl+N) adds the rule for you, as the clip below shows.

Video coming soon
Video coming soon
Where compat files live
Punchy reads every .json file in these two folders of every selected resource pack:
assets/minecraft/punchy/compat/<name>.json
assets/punchy/compat/<name>.json
- Subfolders work:
compat/weapons/daggers.jsonis read too. Use lowercase letters, digits and_,.,-. - Punchy’s own built-in pack ships a
tuning_template.jsonwith the stock values. It is an ordinary pack in the list: keep your pack above Punchy! and yours wins. - If two packs have a file at the same path, Punchy reads both and merges them. The pack higher in the list wins each field, and the other fills only what is still empty. See which rule wins.
- A file that Punchy cannot read is skipped without a message. See Things that drop a file or a rule.
- Edit the file, then press F3+T. No restart is needed.
Root keys
These are all the keys that change how Punchy holds or animates items. Any other key is ignored without a message, so a typo does nothing.
| Key | Type | What it does |
|---|---|---|
item | object | Entries keyed by an item kind such as SWORD, by a custom group name, or by a pattern. Each entry applies to every matching item. See Kind groups. |
item | object | Entries keyed by one item id. The most specific rule. See Item specific entries. |
custom | list | Named lists of item ids that you can use as keys in item. Also spelled custom_. See Custom groups. |
globalItem | side set | A pose per hand for every held item. |
globalArm | side set | A pose per hand for every arm. |
armMesh | object | Moves Punchy's arm mesh, not the item. Only the key global is read, and it holds a side set. |
emptyHand | object | Tuning and clips for an empty hand. See Empty hand. |
spatial | object | Takes the same keys as emptyHand. Only Punchy's Spatial GUI compat reads it, so most packs never need it. Also spelled spatial_. |
default_ | list | Clip entries that apply to every item and fill the types an item's own list leaves out. Also spelled default. See Animation lists. |
chestProxy | object | Places the chest in a held chest boat, chest raft or chest minecart. See Proxies. |
enchant | object | Places where the enchanting particles of a held enchanting table fly to. |
paddle | object | Places the paddle of a held boat or raft. |
fishing | object | Places where the fishing line leaves a rod that has no tip for Punchy! to start the line from. On every Minecraft version the cast line starts at the tip of the rod in your hand, so this proxy places the line only for a model-parts rod whose definition has no fishing_. See Proxies. |
Poses and transforms
A pose places something: a scale, an offset, a rotation and sometimes a pivot. A side set holds one pose for each hand:
{ "right": { "scale": 1.0, "offX": 0.0 }, "left": { "scale": 1.0, "offX": -0.0 } }
A side you leave out is not changed by that entry. Punchy does not copy one side to the other, so write both. To mirror by hand, flip the sign of offX, rotY, rotZ and pivotX.
Different keys move different things, and each reads a different set of pose fields:
| Where you write the side set | What it moves | Pose fields it reads |
|---|---|---|
transforms on an entry, globalItem, empty | The held item | All of them |
arm on an entry, globalArm, empty | The arm | scale, offsets, rotations |
arm | Punchy’s arm mesh | scale, offsets, rotations |
| The proxy maps | The proxied part | scale, offsets, rotations |
Pivots matter for items only. The arm, the arm mesh and the proxies ignore them.
| Key | Type | Default | What it does | Example |
|---|---|---|---|---|
scale | number | none (0) | Multiplies the size. 1.0 is normal. A pose without scale is drawn at size 0, so always write it. | |
offX | number | 0 | Moves left or right. | 0.06 |
offY | number | 0 | Moves up or down. | -0.05 |
offZ | number | 0 | Moves the pose along Z. | |
rotX | number | 0 | Rotation in degrees around X. | 12.0 |
rotY | number | 0 | Rotation in degrees around Y. | |
rotZ | number | 0 | Rotation in degrees around Z. | |
pivotX | number | 0 | The point the item turns about, on X. Items only. pivotY and pivotZ work the same. | |
physics | string | A pendulum mode for this side: NONE, FULL_ or FORWARD_, in any letter case. An unknown name gives NONE. Items only. Here it must be text, not an object. | ||
disable_ | boolean | Turns off the sideways tilt of the item and arm while sprinting. Also spelled disable. Items only. | ||
keep_ | boolean | Keeps the arm tuning applied while a clip plays; without it Punchy fades the arm tuning out during clips. Covers both hands unless keep_ or keep_ sets that side. Also spelled keep. Items only. | ||
keep_ | boolean | Keeps the arm tuning only for the arm that starts the action. Also keep, keep_, keep. Items only. | ||
keep_ | boolean | keep_ for the left arm only. Also keep. Items only. On a pose, when keep_ is missing, the first of the _l and _r keys that is set is used, whichever hand the pose is for. | ||
keep_ | boolean | keep_ for the right arm only. Also keep. Items only. |
A pose that sets one of these flags keeps its own value. A flag written on the entry around the pose fills only the poses that do not set it.
Here are the three global places together:
{
"globalItem": {
"right": { "scale": 1.0, "offY": -0.02 },
"left": { "scale": 1.0, "offY": -0.02 }
},
"globalArm": {
"right": { "scale": 1.0, "rotZ": 2.0 },
"left": { "scale": 1.0, "rotZ": -2.0 }
},
"armMesh": {
"global": {
"right": { "scale": 1.0, "offX": 0.02 },
"left": { "scale": 1.0, "offX": -0.02 }
}
}
}
globalItem and globalArm are the base for every item. An item pose (transforms) on a kind group or an item entry replaces the global item pose for that side. Arm poses work differently: the armTransforms of an item specific entry or a custom group member are added to globalArm, so their offsets add up and their scale counts from 1.0. A kind group’s armTransforms also move with whatever your globalArm changes in scale and offsets. armMesh moves only the arm mesh: the item stays where it is.
Tool kinds
Punchy sorts every item into a kind. The kind decides which item group applies to it. Write kinds in capitals, exactly as below. sword is not SWORD.
| Kind | What Punchy puts here |
|---|---|
EMPTY_HAND | Nothing in the hand |
SWORD, AXE, PICKAXE, SHOVEL, HOE | Items in the item tags of those tools, so tagged modded tools count too |
SPEAR | Items in the spears tag, and items with a kinetic weapon component (not tridents) |
FOOD | Anything you can eat or drink |
LANTERN | Lantern, soul lantern and copper lanterns |
CREATURE_ | The axolotl, tropical fish, pufferfish, cod, salmon and tadpole buckets |
BUCKET | Every other bucket, including items whose id contains bucket |
MINECART, BOAT | Minecart items, and boat and raft items |
BOW, ARROW, CROSSBOW, SHIELD | Those items |
FISHING_ | Fishing rods, the carrot on a stick and the warped fungus on a stick |
TRIDENT, SPYGLASS, FLINT, MACE | Trident, spyglass, flint and steel, mace |
TORCH, CHEST, BUTTON_, TRAPDOOR, CARPET, BED | Block items of that block type |
FULL_BLOCK | Any other block item that is a full cube |
BUILDING_, COLORED_, NATURAL_, FUNCTIONAL_ | Other block items in the item tag minecraft:, minecraft:, minecraft: or minecraft:. The game defines none of these tags, so they apply only when a data pack adds them |
BLOCK | Every other block item |
INGREDIENT | Every other item |
SHUBBA_, FLOWER_, REDSTONE | Never chosen by Punchy. Give an item one of these with kind |
You can force any kind on an item with the kind key (see Item specific entries and Pattern matching).
The arm has its own list of kinds, used by armKind. It is the list above without CHEST, plus BLOCK_DOUBLE, BOW_DOUBLE and CROSSBOW_DOUBLE. CHEST has no arm kind of its own: a held chest takes the BLOCK arm values, and armTransforms on an item.CHEST entry does nothing. An item specific entry whose kind has no arm kind stores its arm values for AXE.
Kind groups and the item key
The item object holds the group layer. Each key can be one of three things:
- An item kind, in capitals:
SWORD. The entry applies to every item of that kind. - A custom group name, exactly as written in
customGroups. The entry applies to every item in the group. - A pattern: a key that starts with
related:, or any entry that haspattern_matching. The entry applies to every item the pattern matches.
Any other key does nothing. A key like sword in lower case is not applied. One key can be a kind and carry pattern_matching too, as SWORD does in the first example: it then applies as the kind group and as a pattern.
| Key | Type | What it does |
|---|---|---|
transforms | side set | Item poses for each hand. |
arm | side set | Arm poses for each hand. |
physics | string, object or list | A pendulum for the item: a mode name, or an object with name and settings, or a list where the first entry with a name counts. An unknown name is ignored. See Item physics. |
disable_ | boolean | No sideways tilt while sprinting, for poses that do not set their own value. |
keep_ | boolean | Keep arm tuning during actions, for both hands unless a side key overrides it. Also keep_ and keep_: the side key wins for that side. |
keep_ | boolean | Keep arm tuning only for the arm that starts the action. |
disable_ | boolean | Turns off the mining animation. Also disable, disable_. |
disable_ | boolean | Turns off the mace fall animation. Also disable. |
disable_ | boolean | Turns off the fall arm animation. Also disable, disable_, disable. |
disable_ | boolean | Turns off the walk on water animation. Also disable_, disable_, disable_. |
disable_ | boolean | Turns off the dry out animation. Also disable_, disable_. |
disable_ | boolean | While you hold the item, the arm that holds it does not play the swim stroke, and the other arm swims as usual. When the item is in your main hand and its idle clip holds it with both hands (dual_), neither arm swims and the idle keeps playing, so the item stays in both hands. The key has one m. Also disable_, disable_, disable_. |
custom | list | Clip entries for this item. See Animation lists. |
custom | list | Item-level clip entries, checked before custom when Punchy looks for the item's own clips. |
particle_ | list or object | Particle emitters on the held item. particle, particles, particle_ and particle_ are read the same way, each on its own. See Particles. |
better | list | Better Combat combos, each with type set to melee_ and attack_1 to attack_6. |
pattern_ | string | Turns the entry into a pattern. Also pattern. See Pattern matching. |
kind | string | The kind given to the items a pattern matches. Used by patterns only. |
armKind | string | The arm kind given to the items a pattern matches. |
An older form puts right and left straight on the entry. It still works on kind keys and custom group keys when transforms is missing, but a pattern entry loses it. Write transforms.
Here is a group entry with clips and flags:
{
"item": {
"AXE": {
"disable_mining_animation": true,
"customAnimation": [
{ "type": "attack", "var_1": "axe_swing_1", "var_2": "axe_swing_2", "critical_hit": "axe_swing_crit" },
{ "type": "inspect", "name": "axe_inspect" }
],
"transforms": {
"right": { "scale": 1.0, "rotX": 6.0 },
"left": { "scale": 1.0, "rotX": 6.0 }
}
}
}
}
The clip names are clips from your own animation files.
Custom groups
A custom group is a name for a list of items. Use it when a kind is too wide, for example to give three tools the same pose.
{
"customGroups": [
{ "name": "daggers", "items": ["minecraft:iron_sword", "minecraft:golden_sword", "stick"] }
],
"item": {
"daggers": {
"transforms": {
"right": { "scale": 0.8, "offY": -0.04 },
"left": { "scale": 0.8, "offY": -0.04 }
}
}
}
}
| Key | Type | What it does |
|---|---|---|
nameRequired | string | The group name. Use it as a key in item, written exactly the same, capitals included. |
itemsRequired | list of strings | Item ids. A bare name such as stick means minecraft:. An id that does not exist in the game is skipped. |
- A group with no
nameor noitemsis skipped. - If two files define the same group name, the first file wins. The names are compared without regard to letter case.
- Group names work as keys in
item. They do not work inside theitemsfilter of a clip entry: use item ids and#tagsthere. - Define groups in a compat file of a pack. Punchy registers groups from compat files and from the active tuning profile only, so a group in your saved tuning file does nothing.
- A group member does not follow the item’s usual kind. Punchy works the kind out for the item without its food step and pins it, so an apple or a potion in a group ends up as
INGREDIENT(a food that is also a block item, such as a carrot, asBLOCK, and a milk bucket asBUCKET) and loses the food group clips. Do not put food in a custom group. To force a kind on a whole family, use a pattern withkind, or writekindon an item specific entry.
Pattern matching
A pattern entry finds items by a piece of text in their name. It is the quickest way to cover modded items without listing them.
{
"item": {
"SWORD": {
"pattern_matching": "sword",
"transforms": {
"right": { "scale": 1.0, "offY": -0.05 },
"left": { "scale": 1.0, "offY": -0.05 }
}
},
"related:dagger": {
"kind": "SWORD",
"disable_sprint_lateral_tilt": true,
"transforms": {
"right": { "scale": 0.9, "offY": -0.03 },
"left": { "scale": 0.9, "offY": -0.03 }
}
}
}
}
How patterns work:
- The text is trimmed and compared in lower case, as plain text. There are no wildcards and no regular expressions.
- It matches an item when it appears in the item id (
examplemod:crystal_sword), in the id path (crystal_sword) or in the translation key. The display name is not checked. "related:dagger"as a key does the same as"pattern_matching": "dagger". Therelated:prefix works in any letter case.- Every matched item gets a kind. Punchy uses the entry’s
kind. If there is none, it uses the key itself as a kind name. If that is not a kind either, the kind isINGREDIENT. That kind replaces the item’s natural kind. Therelated:daggerentry above writes"kind": "SWORD"for this reason. - The matched items receive
transforms,armTransforms,physics, the flags,customAnimation,customItemAnimations, the particle keys,betterCombat,kindandarmKind. Their arm values follow the arm kind, which is thekindunless you setarmKind. - When several patterns match one item, the longest text goes first. Equal lengths go in alphabetical order of their keys. An item takes the first pattern that reaches it.
- An
itemSpecificentry whose key is the full item id, namespace included (minecraft:iron_sword), always beats a pattern. A key without the namespace, or with a suffix such asminecraft:iron_sword#test, does not block it. - Punchy runs the patterns on every reload, against every item registered at that time, modded items included.
Empty hand
emptyHand tunes the hand when it holds nothing. It never applies to an item.
{
"emptyHand": {
"armTransforms": {
"right": { "scale": 1.0, "offX": -0.02, "offY": 0.2, "offZ": -0.2, "rotY": -76.0, "rotZ": 36.0 },
"left": { "scale": 1.0, "offX": 0.02, "offY": 0.2, "offZ": -0.2, "rotY": 76.0, "rotZ": -36.0 }
},
"customAnimation": [
{ "type": "attack", "var_1": "my_punch" }
]
}
}
It takes transforms, armTransforms, physics, customAnimation, customItemAnimations, betterCombat, disable_mining_animation and the flags disable_sprint_lateral_tilt, keep_arm_tuning, keep_trigger_arm_tuning, keep_arm_tuning_l and keep_arm_tuning_r. Those flags are applied together with transforms or physics: on their own they do nothing.
Item specific entries
itemSpecific is the most exact layer. One key is one item.
{
"itemSpecific": {
"minecraft:diamond_sword": {
"kind": "SWORD",
"transforms": {
"right": { "scale": 1.0, "offY": -0.08, "rotZ": 12.0 },
"left": { "scale": 1.0, "offY": -0.08, "rotZ": -12.0 }
},
"customAnimation": [
{ "type": "attack", "var_1": "diamond_swing_1", "var_2": "diamond_swing_2" }
]
},
"minecraft:totem_of_undying": {
"kind": "INGREDIENT",
"transforms": {
"right": { "scale": 1.0, "offY": 0.05 },
"left": { "scale": 1.0, "offY": 0.05 }
}
},
"minecraft:totem_of_undying#patrick": {
"renamed": "Patrick totem",
"kind": "INGREDIENT",
"transforms": {
"right": { "scale": 1.3, "offY": 0.15 },
"left": { "scale": 1.3, "offY": 0.15 }
}
}
}
}
How the key works:
- The key is an item id.
minecraft:can be left out. - Add
#,|or@and any text to make two keys for one item unique, as inminecraft:totem_of_undying#patrick. Punchy cuts the key at that sign and keeps the id. The text after it is only a label. - Write the id in lower case. A key with capitals and no separator is not a valid id and is dropped without a message.
renamedis what makes an entry apply to a renamed item. Punchy compares it with the stack’s custom name, trimmed and in lower case. A stack with a matching name uses that entry. Any other stack of the item uses the plain entry.
| Key | Type | What it does |
|---|---|---|
kind | string | The kind Punchy uses for this item, in capitals. A lower-case value is ignored without a message, and the entry then behaves as if it had no kind: it freezes the item's natural kind, see below. |
armKind | string | The arm kind for arm. If it is missing or invalid, Punchy tries kind as an arm kind, then AXE. |
renamed | string | Apply this entry only to stacks with this custom name. Letter case and outer spaces do not matter. |
bone_ | string, object or list | Pendulum settings for the bones of the item's model part. Also bone. See Item physics. |
enchantment_ | list | Extra particle emitters while the held item has certain enchantments. Also enchantment. |
An item specific entry also takes every key of an item entry, except pattern_matching and the old right and left form.
Set kind on food. An entry without kind writes the item’s natural kind into itself, and Punchy then uses that kind for the stack. For the entry, Punchy works the kind out without its food step, so an apple or a potion ends up as INGREDIENT (a food that is also a block item, such as a carrot, as BLOCK, and a milk bucket as BUCKET) and loses the food group’s clips. Write "kind": "FOOD" on an entry for anything you can eat or drink. Studio’s lint reports items that would change kind, and this is one.
Set armKind next to armTransforms. With neither armKind nor a valid kind, the arm values are stored for AXE. The offsets and scale in the armTransforms of an item specific entry, or of a custom group member, are added to globalArm.
Enchantment variants
A variant adds particle emitters while the held item has the enchantments it lists.
{
"itemSpecific": {
"minecraft:diamond_sword": {
"kind": "SWORD",
"enchantment_variants": [
{
"enchantments": ["minecraft:sharpness", { "id": "minecraft:fire_aspect", "min_level": 2 }],
"match": "any",
"priority": 1,
"particle_emitters": [
{ "type": "minecraft:flame", "target": "item_center", "triggers": ["attacking"], "count": 4, "life": 1, "size": 0.06 }
]
}
]
}
}
}
enchantmentsmust be a list. Each element is an enchantment id, or an object withid,min_level(default 1) andmax_level(default no limit). The item’s level must be at leastmin_level, and at mostmax_levelwhen that is not negative.matchset toanymakes the variant apply when one requirement matches. Anything else, or nothing, needs all of them.priority(default 0) sorts the matching variants: lower numbers add their emitters first.- A variant with no valid requirement or no emitters is dropped.
Additive glow on a particle emitter
Every particle emitter, in particle_emitters of a compat rule or in the particles of a definition, can write "additive": true. The particle’s light then adds to what is behind it, so the dark edges of a glow picture no longer darken the sky around it. It is off by default, and in a script string you write additive=true.
{
"itemSpecific": {
"minecraft:golden_sword": {
"particle_emitters": [
{
"type": "minecraft:end_rod",
"texture": "mypack:particle/halo",
"target": "item_center",
"size": 0.9,
"alpha": 0.9,
"lock_in_model": true,
"fullbright": true,
"additive": true
}
]
}
}
}
mypack:particle/halois a picture you make: a square PNG, for example 64 by 64 pixels, saved asassets/mypack/textures/particle/halo.pngin the same pack, with a soft white dot in the middle that fades to black at the edge. Black adds no light, so only the dot shows.- A halo pinned in the model with
lock_in_modelis drawn whole over the item, not cut off where the item is in front of it. Other additive particles keep the depth test, so whatever is in front of them hides them. - A shading rule that sets
additivefor the held item or the particle’s texture decides over the particle’s ownadditivekey. - Particles without
additiveare drawn as before. The key works on every Minecraft version and loader Punchy! supports. - Punchy! Studio has no field for
additiveyet. It keeps the key as written, and its preview draws the glow the usual way.
Every other key of an emitter is in Particles.
Proxies
Some held items are drawn with a helper part. A proxy map moves that part. Each entry is a pose, and only scale, offsets and rotations are read.
| Root key | Keys | What it places |
|---|---|---|
chestProxy | boat, raft, minecart | The chest inside a held chest boat, chest raft or chest minecart |
enchant | book, book_left, book_right | Where the enchanting particles of a held enchanting table fly to |
paddle | boat, raft, each with _left or _right | The paddle of a held boat or raft |
fishing | rod, fishing_, each with _left or _right | Where the fishing line leaves the held rod when Punchy! has no rod tip to start it from (see below) |
- Keys are read in any letter case, but write them in lower case. A key that is not in the table is ignored.
enchantParticleProxy,paddleProxyandfishingLineProxyaccept a hand suffix. Without a suffix, the entry applies to both hands.chestProxytakes no suffix.- On every Minecraft version the cast line starts at the tip of the rod in your hand, for a flat rod and for a 3D rod model alike, so
fishingLineProxydoes not move the start there. It places the line for a model-parts rod whose definition has nofishing_line_anchor.
{
"chestProxy": {
"boat": { "scale": 0.95, "offX": 0.04, "offY": -0.2, "offZ": -0.5, "rotY": -92.0 }
},
"paddleProxy": {
"boat_right": { "scale": 1.0, "offX": 0.02 },
"boat_left": { "scale": 1.0, "offX": -0.02 }
}
}
Animation lists in compat files
customAnimation is a list of entries. Each entry says: when this happens (type), play this clip. The compat file is where the entries are attached to items.
{
"item": {
"SWORD": {
"customAnimation": [
{ "type": "attack", "var_1": "swing_1", "var_2": "swing_2", "var_3": "swing_3", "critical_hit": "swing_crit" },
{ "type": "inspect", "name": "sword_inspect" },
{ "type": "triggerable", "id": "mypack:sword_flourish", "title": "Sword flourish", "name": "sword_flourish", "key": "H" }
]
}
},
"default_animations": [
{ "type": "inspect", "name": "my_inspect" }
]
}
- Which list an item uses. A list on an item specific entry replaces the group list completely, even if it is empty. The group’s types are not inherited. The group list is used only when the item’s entry has none.
- Defaults.
default_animationsfill in the types the chosen list does not define. An entry is identified by itstypeplus itskey(aninteractionentry also by itsitems,blockStateand conditions). A default is dropped when the chosen list has an entry with the same identity. - Which entry in a list. When several entries of one type could play, the more specific one goes first. An
itemsfilter counts most. Each condition (in_water,inside_water,block_detection,weather_detection,time_detection,biome_detection) adds a little. Equal entries keep the order of the list. This only orders entries with different identities. While anydefault_animationsexist, which is the case with Punchy!‘s own template, two entries of one list with the same type and key (aninteractionentry: the sameitems,blockStateand conditions) count as one and the later one stays. Give entries that must both exist a differenttype, or fortriggerablea differentkey. - The
itemsfilter. Item ids and#tags. Custom group names never match here. A missing or empty list means every item. - Better Combat. In
default_animations, an entry of typemelee_comboor one with abetterCombatlist is moved to the Better Combat defaults.
Every key of an entry, every type and every condition is in Animation reference and Types and triggers.
How an item is matched and which rule wins
For the item in your hand, Punchy goes through these steps.
- The kind. If an entry for the stack has a
kind, that is the kind. Otherwise Punchy works it out from the item (see Tool kinds). - The item’s own entry. Punchy looks for an
itemSpecificentry in this order: one whoserenamedmatches the stack’s custom name, then the entry for the plain item id. The first one found is used. Pattern entries and custom group members live in the same place, as entries written for single items. - Transforms and flags. For each hand, Punchy uses the item’s own pose when its entry has one. Otherwise it uses the pose of the item’s kind group. Otherwise it uses the global pose.
- Clips. The item’s own list when it has one, otherwise the kind group’s list, then the defaults fill the gaps.
When two entries reach the same item, the stronger one wins. From weakest to strongest:
- Punchy’s built-in values and
globalItemandglobalArm - The kind group, such as
SWORD - A custom group that lists the item
- A pattern entry, the longest pattern first
- An
itemSpecificentry for the plain item id - An
itemSpecificentry whoserenamedmatches the stack
A key the stronger entry does not write falls back to the weaker entry. If the item has no pose of its own for a hand, the kind group’s pose still applies. Studio’s Effective column shows this for any held item: the rule Punchy would use, from which file and pack, and the rules that lost. Do not list one item in two custom groups that set the same field.
When two files, from one pack or from two, write the same field, the file Punchy reads first wins, and later files only fill what is empty. Punchy reads packs from the top of the list down, so keep your pack above Punchy! and it comes before Punchy’s own template. When a key has a value in no file, Punchy’s built-in value stays.
Load order with tuning profiles
Punchy builds its tuning in this order every time resources load:
- Punchy clears its tuning and registers the custom groups of the merged compat files.
- It reads and merges every compat file as described above, and applies the result.
- It applies your saved tuning file,
config/punchy/punchy_tuning.json, only when no tuning profile is active. - It registers the active tuning profile’s own custom groups.
- It applies the choices from Mix the Packs.
- It applies the active tuning profile itself last.
So what you save in the Hand Editor and the active profile in config/punchy/profiles/ come after compat files and override them for whatever they set. A pack cannot change that. Players can remove your values by saving their own, or put them back with Reset To Default in the editor, which deletes the saved file and clears the active profile.
Things that drop a file or a rule
Punchy reads each compat file in one go. If anything in it is wrong in the wrong way, the whole file is skipped and nothing is logged. Studio’s Bindings workspace reports these before you export, and shows “Punchy would ignore this file” with the reason.
These drop the whole file:
- A key written twice inside
item,itemSpecific,armMeshor a proxy map. The same key twice in a plain object keeps the last value, but a repeated key in these maps drops the file. - A value of the wrong type: an object where a number is expected, text where a list is expected, a
physicsobject inside a pose (a pose takes a name), a decimal where a whole number is expected. - Text after the closing brace, a root that is not an object, bad escapes in a string or any other broken JSON.
These drop only the rule:
- A lower-case kind key such as
sword, or a key that is not a kind, a group, a pattern orrelated:. - An
itemSpecifickey that is not a valid lower-case item id. - A pattern entry with no
kindand a key that is not a kind: its items turn intoINGREDIENT. - An
itemSpecificentry for food with nokind: an apple or a potion turns intoINGREDIENT(a carrot intoBLOCK, a milk bucket intoBUCKET) and loses the food group’s clips. - A food item listed in a custom group: it turns into
INGREDIENT(a carrot intoBLOCK, a milk bucket intoBUCKET) and loses the food group’s clips. - A misspelled key: Punchy ignores keys it does not know.
- A custom group name inside a clip entry’s
items: it never matches. emptyHandflags with notransformsorphysicsnext to them.
This hides the item without dropping anything:
- A pose with no
scale. It is applied at size 0, so the item vanishes.
Why my change does nothing:
- The pack is not in the right-hand Selected list of the resource pack screen, or it is below another pack that sets the same field.
- You did not reload. Press F3+T.
- The player has an active tuning profile or a saved tuning file that sets the same field. See load order.
- The item has its own entry, and its list replaced the group’s list.
Related pages
- Animation reference: every key of a clip entry.
- Types and triggers: which
typeplays when. - Create an animation: make the clips these files point to.
- Tuning editor and debug: place items in game and save the result.
- Mix the packs: how a player chooses between packs that define the same thing.
- Item physics: pendulum modes and settings.
- Particles: the keys of a particle emitter.
- Punchy! Studio: the editor behind the Bindings workspace.
- Troubleshooting: when a pack does not load.
- Punchy! Moves compat files: third-person compat files have their own format.
Last checked against the mod on 30 October 2026.