Privacy
Language: Norsk bokmål

Variants and presets

Ship several versions of one model part, know which one Punchy! draws, let players pick by item name, and add particles that show only on enchanted items.

This page has not been translated into Norwegian Bokmål yet, so it is shown in English. Read in English

On this page

A variant is a second version of a model part: the same lantern with sparks instead of smoke, or one that only shows when the item has a certain name. Punchy! loads every definition in your pack and then draws one of them for the held item, so making a variant is mostly a question of making the right one win. This page is for pack makers who already have a model part definition and want to ship presets, named versions, or particles that depend on enchantments.

Before you start

  • Install Punchy! 3.0 or newer from Modrinth or CurseForge. This page was checked against Punchy! 3.0 for Fabric on Minecraft 26.3.
  • Have the lantern pack from Model part definitions working: definitions/lantern.json, geo/lantern.geo.json, textures/lantern.png and animations/lantern.animation.json. Every example below reuses those files. That page gives the text of the definition, the geometry and the clips, how to draw the texture (a flat orange 16 by 16 square is enough) and the pack.mcmeta. Keep everything below in that one pack.
  • Know how to reload. Press F3+T in a world after you change a file. Punchy! reads your definitions and compat files again, and the chat says [Debug]: Reloaded resource packs when it is done.
  • For the Studio steps you need Punchy! Studio, from Modrinth or CurseForge.

How Punchy! picks one variant

A variant is not a special kind of file. It is an ordinary definition that lists the same item as another definition. Punchy! never merges two definitions and never fills the gaps of one from another, so every variant is a complete file of its own.

For each held item Punchy! then picks exactly one definition. The pick depends on three things:

  1. The item’s name. A definition with a customName answers only stacks that carry that name.
  2. The sort order of the ids. Among unnamed definitions that list the item, the first one wins. Ids are sorted as text, ignoring letter case, starting with the namespace. A folder name is part of the id, so folders decide who wins.
  3. The pack that holds the file. Two packs that ship a file at exactly the same path are one id. Minecraft uses the file from the pack higher in the list, as it does for every other resource.
SituationWhat Punchy! draws
Two unnamed definitions list the itemThe one whose id sorts first. The other one is shadowed.
A named definition lists the item and the stack carries its nameThe named definition.
Two named definitions share a nameThe one whose id sorts first.
A named definition lists the item and the stack has no name, or another nameThe vanilla model. No unnamed definition is used for that item.
No definition lists the itemThe vanilla model.

There are four more ways to change how one model part looks, and none of them needs a second file:

You wantUseRead
A different clip in water, rain, at night or in a biomeSeveral idle entries in modelPartsAnimation, each with a conditionItem clips and Conditions
A different texture or geometry for what a bucket holdsdynamic_bone_texturesDynamic textures
Another geometry, or other keys, while you use the item or cast a rodstate_modelsModel part definitions
Extra particles while the item has certain enchantmentsenchantment_variants in a compat fileEnchantment variants below

Make two presets and switch between them

You will add two presets to the lantern pack, a spark version and a calm version, and then change which one shows by renaming a folder. Nothing else changes: the presets use the same geometry, texture and clips as the base lantern.

Model parts draw only in first person. In third person the item keeps its vanilla model, so switch the camera to first person whenever you test a preset.

  1. In your pack, open assets/minecraft/punchy/model_parts_items/definitions. The base lantern.json from the definitions page is in it.
  2. Make a folder a_spark and save the first file below in it as lantern.json.
  3. Make a folder b_calm and save the second file below in it as lantern.json.
  4. Press F3+T in a world, then hold a lantern in first person. The ids sort as a_spark, then b_calm, then the base lantern.json, so the spark preset wins. Its crit particles are small and the arm covers part of the lantern, so the Studio check below is the surest way to see which preset Punchy! picked.
  5. Rename the folder a_spark to z_spark and reload with F3+T. Now b_calm is first, so Punchy! draws the calm preset, which has no blur halo around the flame and no particles. You may not be able to tell the two apart in first person, so check the pick in Studio as well.
  6. Rename b_calm to z_calm and reload. The ids now sort as the base lantern.json, then z_calm, then z_spark, so the base lantern with its smoke is back.

The spark preset, definitions/a_spark/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": [
    "particle(type=minecraft:crit, bone=flame, rate=6, life=0.5, size=0.02, velocity=0:0.02:0)"
  ]
}

The calm preset, definitions/b_calm/lantern.json. It sets the flame glow to 40 and leaves blur off, so the flame has no halo around it, and it has no particles at all:

{
  "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,
      "skip_blend_in": true,
      "skip_blend_out": true
    },
    { "type": "attack", "name": "lantern_swing" }
  ],
  "bone_emission": { "flame": 40 }
}

Video coming soon

Renaming a folder changes which preset sorts first.

Check who wins in Punchy! Studio

You do not have to guess the order. Studio lists it.

  1. Join a world, hold a lantern, switch to first person and press F6. That is the default key for Open Animation Editor under Punchy Studio in the key binds. 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, then choose File > Open Model Part… (Ctrl+O).
  3. In the Model Parts Library, stay on Resource Packs and type lantern in Search definitions and items.
  4. Select each definition. The rows share the name lantern, so read the first line of the detail pane: it shows the full id with the folder. The pane’s entry for minecraft:lantern says rendered, shadowed by another definition, blocked by the named definition, or never matches. A definition Punchy! throws away is marked dropped by Punchy, with the reason.

Video coming soon

The Model Parts Library says which definition Punchy! draws and which ones it shadows.

Keep a preset small

A preset only needs to differ in the keys that make it different. Everything else stays the same text, so point it at the files the base already uses:

  • geo, texture and animations name the base’s files by id. Do not copy the geometry or the texture into the preset’s folder: a definition loads its files by the exact id you write, wherever they sit.
  • Change only what the preset is about. The keys that usually differ are particles, bone_emission, bone_texture_anim, bone_textures (a different texture on one bone), modelPartsAnimation and display.
  • Keep the same file name in every preset folder, here lantern.json, so the folder is the only thing that tells them apart.

A model part you make in Studio exports with its own geometry, texture and clips, named after its File Name in the Definition tab. To share one set of files between presets, open the exported definition in a text editor, point geo, texture and animations at the base files, and delete the copies.

Ship presets to players

The active preset is whichever definition wins, so a player’s choice has to come from the files. Pick the way that suits your pack:

  • A folder to rename. Ship the presets in subfolders of definitions with sort prefixes like the ones in the steps above (a_, b_ and z_), and tell players to put 0_ in front of the folder they want and reload. Numbers sort before letters, so a 0_ folder beats the rest. It is the same idea as the steps above, with a different prefix.
  • A parked folder. Keep inactive presets in a folder beside definitions, such as assets/minecraft/punchy/model_parts_items/presets/spark/lantern.json. Punchy! reads the files under definitions, so anything in presets is never loaded. To switch, the player copies a preset file over definitions/lantern.json.
  • A small pack per preset. Make each preset its own resource pack with one file in it, at the same path as the base: assets/minecraft/punchy/model_parts_items/definitions/lantern.json. A player turns the preset pack on above the base pack in Options…, then Resource Packs…, and Minecraft uses the file from the pack that is higher in the list. This is the one choice a player can make without opening a folder.

In Studio, the Export First in Order switch in the Definition tab (and in the export dialog) writes the definition to definitions/0_punchy_studio/. Use it when your preset has to beat a definition from another pack.

Variants chosen by the item’s name

A named definition is the one variant a player can pick in game: renaming an item on an anvil switches the model. You will give the lantern two named looks, one for a lantern renamed Sun Lantern and one for Moon Lantern.

Do this in a copy of the pack. A named definition shuts out every unnamed definition for its item, so your plain lantern.json and the presets stop answering for lanterns.

  1. In definitions, make a folder names. The folder means nothing to Punchy!. It only keeps the files together and sorts them.
  2. Save the first file below as definitions/names/sun_lantern.json.
  3. Save the second file below as definitions/names/moon_lantern.json.
  4. Reload with F3+T, then give yourself a lantern with /give @s minecraft:lantern.
  5. Hold it. It draws as the plain vanilla lantern, because named definitions cover lanterns and this stack has no name.
  6. Rename it to Sun Lantern on an anvil and hold it again. Punchy! now draws the lantern model from your pack, not the vanilla lantern, using sun_lantern.json. Rename another lantern to moon lantern: capital letters and spaces at the ends do not matter, so moon_lantern.json draws. The two files differ in the flame glow (100 with a blur halo for the sun, 35 with no blur for the moon) and in the particles (flame for the sun, end rod for the moon), but the two models look alike in daylight, so tell them apart by the name you gave.

definitions/names/sun_lantern.json:

{
  "items": ["minecraft:lantern"],
  "customName": "Sun 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": "attack", "name": "lantern_swing" }
  ],
  "bone_emission": { "strength": 100, "blur": true, "flame": 100 },
  "particles": [
    "particle(type=minecraft:flame, bone=flame, rate=4, life=0.6, size=0.03)"
  ]
}

definitions/names/moon_lantern.json:

{
  "items": ["minecraft:lantern"],
  "customName": "Moon 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": "attack", "name": "lantern_swing" }
  ],
  "bone_emission": { "flame": 35 },
  "particles": [
    "particle(type=minecraft:end_rod, bone=flame, rate=2, life=1.2, size=0.02)"
  ]
}

Video coming soon

The anvil name picks the variant.

A few things follow from the rule:

  • The stack’s custom name is compared, not its hover text or lore. The text is trimmed and compared without letter case.
  • name works as an alias: when a definition has no customName key, its name key does the same job. Use customName in your own files so the intent is clear.
  • The soul lantern is untouched here, because neither named file lists it. Any unnamed definition that lists minecraft:soul_lantern still draws for it.
  • An unnamed lantern model cannot sit next to named ones. Name every look you want, as in Match a renamed item.
  • In Studio, the Definition tab has a Custom Name field in the Items panel.

Enchantment variants

An enchantment variant adds particles while the held item has certain enchantments. It lives in a compat file, and it works on any item, with or without a model part. You will make a diamond sword that crackles on every swing, burns when it has Fire Aspect, and puffs clouds when it has Knockback or Sweeping Edge.

A model part definition can hold an enchantment_variants list of its own, which changes keys of that definition, such as its texture, while the item has the enchantments. Punchy! 3.0 applies that list only on Minecraft 1.21.11. On every other version it is read and does nothing, so use the compat file below.

  1. In your pack, create the folder assets/minecraft/punchy/compat/.
  2. Save the file below as sword_enchants.json in it.
  3. Join a world, run /give @s minecraft:diamond_sword, hold it in first person and swing it. Crit particles appear at the sword on every swing.
  4. Run /enchant @s minecraft:fire_aspect 1 and swing again. Flames join the crit particles.
  5. Run /enchant @s minecraft:sharpness 3 and swing. Soul fire flames join too, because the second variant needs both enchantments.
  6. Give yourself a new sword and run /enchant @s minecraft:knockback 1. Clouds appear, because the third variant needs only one of its two enchantments.
{
  "itemSpecific": {
    "minecraft:diamond_sword": {
      "kind": "SWORD",
      "particle_emitters": [
        "particle(type=minecraft:crit, target=item_center, trigger_attacking=true, count=2, life=0.4, size=0.05)"
      ],
      "enchantment_variants": [
        {
          "enchantments": ["minecraft:fire_aspect"],
          "particle_emitters": [
            "particle(type=minecraft:flame, target=item_center, trigger_attacking=true, count=4, life=0.6, size=0.06)"
          ]
        },
        {
          "enchantments": [
            "minecraft:fire_aspect",
            { "id": "minecraft:sharpness", "min_level": 3 }
          ],
          "priority": 1,
          "particle_emitters": [
            "particle(type=minecraft:soul_fire_flame, target=item_center, trigger_attacking=true, count=4, life=0.6, size=0.06)"
          ]
        },
        {
          "enchantments": ["minecraft:knockback", "minecraft:sweeping_edge"],
          "match": "any",
          "priority": 2,
          "particle_emitters": [
            "particle(type=minecraft:cloud, target=item_center, trigger_attacking=true, count=3, life=0.5, size=0.05)"
          ]
        }
      ]
    }
  }
}

What each swing fires, by what the sword carries:

The sword hasEmitters that fire on a swing
No enchantmentscrit
Fire Aspectcrit, flame
Fire Aspect and Sharpness 3 or morecrit, flame, soul fire flame
Sharpness 5 onlycrit
Knockback or Sweeping Edgecrit, cloud

How Punchy! builds that list:

  • It starts with the entry’s own emitters, here the crit.
  • It adds the emitters of every variant that matches, from the lowest priority to the highest. Two variants with the same priority keep the order of the file.
  • An emitter written twice with the same text counts once.
  • It checks the held stack again every frame, so taking an enchanted sword out of your hand changes the particles at once.
  • When a variant matches, the entry’s list replaces the emitters of the item’s group in item. The group’s emitters are not added on top.
  • The emitters draw in first person.

On an item that has a model part, an emitter can name a bone, as bone=flame does on the lantern, and the particles come out of that bone. Without a model part, use target=item_center. Particles explains every emitter key.

A variant lives in an itemSpecific entry, and an entry can be for one renamed item. Write the key minecraft:diamond_sword#fancy with "renamed": "Fancy sword", and only swords with that name use that entry and its variants. Compat rules explains the key.

Make it in Punchy! Studio

  1. Join a world, hold a diamond sword, switch to first person and press F6 (or the key you set for Open Animation Editor). 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. Select your destination pack in the Rules outliner and press New Compat File. In the dialog, double-click File Name to select the my_rules.json already in it, type sword_enchants and press New Compat File. Studio adds .json and selects the new file. On export it writes the file to assets/minecraft/punchy/compat/ in that pack.
  3. With the new file selected, press Edit as Text. A new file is empty and has no itemSpecific section yet, so write the entry by hand: { "itemSpecific": { "minecraft:diamond_sword": {} } }. Press Ctrl+Enter to Apply the text.
  4. Select the minecraft:diamond_sword target under itemSpecific, open the Enchantment Variants panel and press Add Variant. A new variant asks for Sharpness.
  5. In the variant’s first row, replace minecraft:sharpness with minecraft:fire_aspect. That box is Enchantment, and the two small boxes after it are Lowest Level and Highest Level (they read 1 and any until you type, and hovering a box shows its name). Use them for a range, Add Enchantment for a second requirement, and the Match and Priority fields as in the table below.
  6. In Variant 1 Emitters, press Add Emitter. A new emitter is a flame particle at the item’s center. A variant without an emitter is dropped, and Studio says so in the panel.
  7. In the emitter’s Timing and Triggers panel, tick Attacking. An emitter with no trigger fires all the time.
  8. Press Ctrl+Enter to Apply, then Ctrl+E to export. Hold the enchanted sword and swing it.

Once a file has an itemSpecific section, Add Target on that section adds further items to it.

Video coming soon

An enchantment variant made in the Bindings workspace.

Keys of an enchantment variant

The enchantment_variants list of an itemSpecific entry
KeyTypeDefaultWhat it doesExample
enchantment_variantslistThe variants of this entry. Also written enchantmentVariants. Within one entry every variant is kept, and each matching variant adds its emitters. When two compat files give the same item entry, variants with the same enchantments text and the same match merge into one.[ { ... }, { ... } ]
enchantmentsRequiredlistWhat the held item must carry. Each element is an enchantment id, or an object with id, min_level and max_level. A value that is not a list, or a list with no valid id, drops the variant.["minecraft:sharpness"]
matchstringallany, in any letter case, applies the variant when one listed enchantment matches. Any other value, or none, needs every one of them.
priorityinteger0The order the matching variants add their emitters, lowest first. It never decides whether a variant matches.2
particle_emittersRequiredemitter, text or listThe emitters this variant adds, in the three ways to write an emitter. Punchy! also reads particleEmitters, particle, particles, particle_effects, particleEffects, particle_emission and particleEmission here. A variant with no emitter is dropped.
One element of the enchantments list
KeyTypeDefaultWhat it doesExample
idRequiredenchantment idThe enchantment, such as minecraft:sharpness. The namespace is optional: sharpness reads as minecraft:sharpness. A plain text element instead of an object is an id that needs level 1 or more."minecraft:sharpness"
min_levelinteger1The lowest level that counts. Also minLevel. A negative number becomes 0, and 0 matches an item that does not carry the enchantment at all.3
max_levelintegerno limitThe highest level that counts. Also maxLevel. A negative number means no limit.5

A level has to be a JSON number. A level written as text, such as "3", is ignored and the default is used.

Why my variant does not show

  • Two definitions for one item. Only the one whose id sorts first draws, and the other is shadowed. That is normal. Open the Model Parts Library in Studio to see which one wins.
  • A mistake drops the first preset, and the next one draws. A definition with no valid item, geo or texture is thrown away without a message, so the next definition in the order takes over and looks like a wrong choice. A definition that points at a geometry file that does not exist stays, still wins and draws nothing, so the vanilla model shows and the presets after it never get a turn.
  • The folder is not under definitions. Punchy! reads the .json files under model_parts_items/definitions. Only when that folder holds no files does it fall back to any .json under model_parts_items whose path contains /definitions/. A preset in model_parts_items/presets is never loaded. A folder called presets inside definitions is loaded.
  • A capital letter or a space in a name. Minecraft resource ids allow only lower case letters, digits, _, - and . (plus / between folders). Keep every file and folder name under definitions to those characters, because a name with a capital letter or a space is not a valid id.
  • A field with the wrong JSON type. Some fields with the wrong JSON type make Punchy! drop the whole definition without a message, such as items, animations or modelPartsAnimation that is not a list, display that is not an object, or a field of an animation entry that holds a list or an object where one value belongs. The next definition in the order takes over. Check each key against the tables in Model part definitions.
  • You are testing in third person. Model parts draw only in first person, so a preset never shows in third person. Switch the camera to first person.
  • A named definition covers the item. An unnamed stack gets the vanilla model, even though an unnamed definition lists it. See Variants chosen by the item’s name.
  • A blank custom name. "customName": "" is ignored, and the definition counts as unnamed. The name key is not tried in its place. name is read only when the customName key is missing.
  • A tag in items. A definition that lists #minecraft:swords competes for every sword. It can shadow a preset made for one sword.
  • The same path in two packs. Minecraft hands Punchy! only the file of the higher pack. The file in the lower pack never loads, so it cannot act as a second variant.
  • An enchantment variant that does nothing. Check these in order. The key is in a compat file, in an itemSpecific entry. enchantments is a list. At least one id in it is real; a bare id such as sharpness reads as minecraft:sharpness, so the namespace is optional. The variant has an emitter, and the emitter has a trigger that fires. A min_level of 0 matches every item, so use 1 or more. See Compat rules for what drops a whole compat file.
  • No reload. Press F3+T after every change.
  • Model part definitions has every key of a definition and the full rule for which one covers an item.
  • Resource packs shows how pack order and id order work together.
  • Particles explains every emitter key, trigger and glow setting.
  • Compat rules holds the itemSpecific entries that carry enchantment variants.
  • Item clips and Conditions pick a clip by water, weather, time and biome inside one definition.
  • Dynamic textures swaps a texture or geometry by what a bucket holds.
  • Model parts is the overview of the whole system.

Last checked against the mod on 29 October 2026.