Privacy
Language: 简体中文

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.

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 resourcepacks with a pack.mcmeta and an assets folder. 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.

  1. In your pack, create the folder assets/minecraft/punchy/compat/.
  2. Inside it, create a file named my_tuning.json and paste the example below.
  3. Open Options, then Resource Packs…, move your pack from Available to Selected, the right-hand list, and press Done.
  4. Join a world and press F3+T to reload resources. Punchy reads its compat files again on every reload.
  5. 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.

  1. 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.
  2. 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.
  3. 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.
  4. With the new file selected, press Edit as Text, type { "item": { "SWORD": {} } } and press Apply. SWORD now shows under the item section. To add more targets later, select a section and press Add Target. In the item section the dialog asks for a Group, for example SWORD, a custom group name or a related: key. In itemSpecific it asks for an Item id such as minecraft:diamond_sword.
  5. 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.
  6. Select the file itself to edit Custom Groups, Global Transforms and Proxies. Edit as Text opens the whole file as JSON.
  7. 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.

The Bindings workspace: a new rule lands in the pack's punchy_studio.json under itemSpecific, and the Effective column shows which rule Punchy would use.

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.json is read too. Use lowercase letters, digits and _, ., -.
  • Punchy’s own built-in pack ships a tuning_template.json with 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.

Root keys of a compat file
KeyTypeWhat it does
itemobjectEntries 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.
itemSpecificobjectEntries keyed by one item id. The most specific rule. See Item specific entries.
customGroupslistNamed lists of item ids that you can use as keys in item. Also spelled custom_groups. See Custom groups.
globalItemside setA pose per hand for every held item.
globalArmside setA pose per hand for every arm.
armMeshobjectMoves Punchy's arm mesh, not the item. Only the key global is read, and it holds a side set.
emptyHandobjectTuning and clips for an empty hand. See Empty hand.
spatialGuiCompatobjectTakes the same keys as emptyHand. Only Punchy's Spatial GUI compat reads it, so most packs never need it. Also spelled spatial_gui_compat.
default_animationslistClip entries that apply to every item and fill the types an item's own list leaves out. Also spelled defaultAnimations. See Animation lists.
chestProxyobjectPlaces the chest in a held chest boat, chest raft or chest minecart. See Proxies.
enchantParticleProxyobjectPlaces where the enchanting particles of a held enchanting table fly to.
paddleProxyobjectPlaces the paddle of a held boat or raft.
fishingLineProxyobjectPlaces 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_line_anchor. 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 setWhat it movesPose fields it reads
transforms on an entry, globalItem, emptyHand.transformsThe held itemAll of them
armTransforms on an entry, globalArm, emptyHand.armTransformsThe armscale, offsets, rotations
armMesh.globalPunchy’s arm meshscale, offsets, rotations
The proxy mapsThe proxied partscale, offsets, rotations

Pivots matter for items only. The arm, the arm mesh and the proxies ignore them.

Fields of a pose
KeyTypeDefaultWhat it doesExample
scalenumbernone (0)Multiplies the size. 1.0 is normal. A pose without scale is drawn at size 0, so always write it.
offXnumber0Moves left or right.0.06
offYnumber0Moves up or down.-0.05
offZnumber0Moves the pose along Z.
rotXnumber0Rotation in degrees around X.12.0
rotYnumber0Rotation in degrees around Y.
rotZnumber0Rotation in degrees around Z.
pivotXnumber0The point the item turns about, on X. Items only. pivotY and pivotZ work the same.
physicsstringA pendulum mode for this side: NONE, FULL_PENDULUM or FORWARD_PENDULUM, in any letter case. An unknown name gives NONE. Items only. Here it must be text, not an object.
disable_sprint_lateral_tiltbooleanTurns off the sideways tilt of the item and arm while sprinting. Also spelled disableSprintLateralTilt. Items only.
keep_arm_tuningbooleanKeeps the arm tuning applied while a clip plays; without it Punchy fades the arm tuning out during clips. Covers both hands unless keep_arm_tuning_l or keep_arm_tuning_r sets that side. Also spelled keepArmTuning. Items only.
keep_trigger_arm_tuningbooleanKeeps the arm tuning only for the arm that starts the action. Also keepTriggerArmTuning, keep_main_arm_tuning, keepMainArmTuning. Items only.
keep_arm_tuning_lbooleankeep_arm_tuning for the left arm only. Also keepArmTuningL. Items only. On a pose, when keep_arm_tuning is missing, the first of the _l and _r keys that is set is used, whichever hand the pose is for.
keep_arm_tuning_rbooleankeep_arm_tuning for the right arm only. Also keepArmTuningR. 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.

KindWhat Punchy puts here
EMPTY_HANDNothing in the hand
SWORD, AXE, PICKAXE, SHOVEL, HOEItems in the item tags of those tools, so tagged modded tools count too
SPEARItems in the spears tag, and items with a kinetic weapon component (not tridents)
FOODAnything you can eat or drink
LANTERNLantern, soul lantern and copper lanterns
CREATURE_BUCKETThe axolotl, tropical fish, pufferfish, cod, salmon and tadpole buckets
BUCKETEvery other bucket, including items whose id contains bucket
MINECART, BOATMinecart items, and boat and raft items
BOW, ARROW, CROSSBOW, SHIELDThose items
FISHING_RODFishing rods, the carrot on a stick and the warped fungus on a stick
TRIDENT, SPYGLASS, FLINT, MACETrident, spyglass, flint and steel, mace
TORCH, CHEST, BUTTON_PLATE, TRAPDOOR, CARPET, BEDBlock items of that block type
FULL_BLOCKAny other block item that is a full cube
BUILDING_BLOCKS, COLORED_BLOCKS, NATURAL_BLOCKS, FUNCTIONAL_BLOCKSOther block items in the item tag minecraft:building_blocks, minecraft:colored_blocks, minecraft:natural_blocks or minecraft:functional_blocks. The game defines none of these tags, so they apply only when a data pack adds them
BLOCKEvery other block item
INGREDIENTEvery other item
SHUBBA_DUCK, FLOWER_PENDULUM, REDSTONENever 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 has pattern_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.

Keys of an item entry
KeyTypeWhat it does
transformsside setItem poses for each hand.
armTransformsside setArm poses for each hand.
physicsstring, object or listA 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_sprint_lateral_tiltbooleanNo sideways tilt while sprinting, for poses that do not set their own value.
keep_arm_tuningbooleanKeep arm tuning during actions, for both hands unless a side key overrides it. Also keep_arm_tuning_l and keep_arm_tuning_r: the side key wins for that side.
keep_trigger_arm_tuningbooleanKeep arm tuning only for the arm that starts the action.
disable_mining_animationbooleanTurns off the mining animation. Also disableMiningAnimation, disable_mining.
disable_mace_fall_animationbooleanTurns off the mace fall animation. Also disableMaceFallAnimation.
disable_fall_arm_animationbooleanTurns off the fall arm animation. Also disableFallArmAnimation, disable_fall_animation, disableFallAnimation.
disable_walk_on_waterbooleanTurns off the walk on water animation. Also disable_walkonwater, disable_walk_on_water_v2, disable_walk_on_water_animation.
disable_dry_outbooleanTurns off the dry out animation. Also disable_dryout, disable_dryout_animation.
disable_swimingbooleanWhile 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_handed), neither arm swims and the idle keeps playing, so the item stays in both hands. The key has one m. Also disable_swimming, disable_swim, disable_swim_animation.
customAnimationlistClip entries for this item. See Animation lists.
customItemAnimationslistItem-level clip entries, checked before customAnimation when Punchy looks for the item's own clips.
particle_emitterslist or objectParticle emitters on the held item. particle, particles, particle_effects and particle_emission are read the same way, each on its own. See Particles.
betterCombatlistBetter Combat combos, each with type set to melee_combo and attack_1 to attack_6.
pattern_matchingstringTurns the entry into a pattern. Also patternMatching. See Pattern matching.
kindstringThe kind given to the items a pattern matches. Used by patterns only.
armKindstringThe 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 }
      }
    }
  }
}
Keys of a custom group
KeyTypeWhat it does
nameRequiredstringThe group name. Use it as a key in item, written exactly the same, capitals included.
itemsRequiredlist of stringsItem ids. A bare name such as stick means minecraft:stick. An id that does not exist in the game is skipped.
  • A group with no name or no items is 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 the items filter of a clip entry: use item ids and #tags there.
  • 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, as BLOCK, and a milk bucket as BUCKET) 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 with kind, or write kind on 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". The related: 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 is INGREDIENT. That kind replaces the item’s natural kind. The related:dagger entry above writes "kind": "SWORD" for this reason.
  • The matched items receive transforms, armTransforms, physics, the flags, customAnimation, customItemAnimations, the particle keys, betterCombat, kind and armKind. Their arm values follow the arm kind, which is the kind unless you set armKind.
  • 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 itemSpecific entry 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 as minecraft: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 in minecraft: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.
  • renamed is 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.
Keys of an item specific entry
KeyTypeWhat it does
kindstringThe 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.
armKindstringThe arm kind for armTransforms. If it is missing or invalid, Punchy tries kind as an arm kind, then AXE.
renamedstringApply this entry only to stacks with this custom name. Letter case and outer spaces do not matter.
bone_physicsstring, object or listPendulum settings for the bones of the item's model part. Also bonePhysics. See Item physics.
enchantment_variantslistExtra particle emitters while the held item has certain enchantments. Also enchantmentVariants.

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 }
          ]
        }
      ]
    }
  }
}
  • enchantments must be a list. Each element is an enchantment id, or an object with id, min_level (default 1) and max_level (default no limit). The item’s level must be at least min_level, and at most max_level when that is not negative.
  • match set to any makes 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/halo is a picture you make: a square PNG, for example 64 by 64 pixels, saved as assets/mypack/textures/particle/halo.png in 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_model is 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 additive for the held item or the particle’s texture decides over the particle’s own additive key.
  • Particles without additive are drawn as before. The key works on every Minecraft version and loader Punchy! supports.
  • Punchy! Studio has no field for additive yet. 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 keyKeysWhat it places
chestProxyboat, raft, minecartThe chest inside a held chest boat, chest raft or chest minecart
enchantParticleProxybook, book_left, book_rightWhere the enchanting particles of a held enchanting table fly to
paddleProxyboat, raft, each with _left or _rightThe paddle of a held boat or raft
fishingLineProxyrod, fishing_rod, each with _left or _rightWhere 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, paddleProxy and fishingLineProxy accept a hand suffix. Without a suffix, the entry applies to both hands. chestProxy takes 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 fishingLineProxy does not move the start there. It places the line for a model-parts rod whose definition has no fishing_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_animations fill in the types the chosen list does not define. An entry is identified by its type plus its key (an interaction entry also by its items, blockState and 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 items filter 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 any default_animations exist, which is the case with Punchy!‘s own template, two entries of one list with the same type and key (an interaction entry: the same items, blockState and conditions) count as one and the later one stays. Give entries that must both exist a different type, or for triggerable a different key.
  • The items filter. 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 type melee_combo or one with a betterCombat list 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.

  1. 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).
  2. The item’s own entry. Punchy looks for an itemSpecific entry in this order: one whose renamed matches 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.
  3. 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.
  4. 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:

  1. Punchy’s built-in values and globalItem and globalArm
  2. The kind group, such as SWORD
  3. A custom group that lists the item
  4. A pattern entry, the longest pattern first
  5. An itemSpecific entry for the plain item id
  6. An itemSpecific entry whose renamed matches 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:

  1. Punchy clears its tuning and registers the custom groups of the merged compat files.
  2. It reads and merges every compat file as described above, and applies the result.
  3. It applies your saved tuning file, config/punchy/punchy_tuning.json, only when no tuning profile is active.
  4. It registers the active tuning profile’s own custom groups.
  5. It applies the choices from Mix the Packs.
  6. 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, armMesh or 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 physics object 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 or related:.
  • An itemSpecific key that is not a valid lower-case item id.
  • A pattern entry with no kind and a key that is not a kind: its items turn into INGREDIENT.
  • An itemSpecific entry for food with no kind: an apple or a potion turns into INGREDIENT (a carrot into BLOCK, a milk bucket into BUCKET) and loses the food group’s clips.
  • A food item listed in a custom group: it turns into INGREDIENT (a carrot into BLOCK, a milk bucket into BUCKET) 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.
  • emptyHand flags with no transforms or physics next 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:

  1. 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.
  2. You did not reload. Press F3+T.
  3. The player has an active tuning profile or a saved tuning file that sets the same field. See load order.
  4. The item has its own entry, and its list replaced the group’s list.

Last checked against the mod on 30 October 2026.