Complete Configuration Reference

Configuration Reference

Current CoreArmorX YAML files, reload boundaries, runtime model, permissions, troubleshooting, and production checks.

0. Before You Configure

Minimum requirements are Paper 1.21.11+, Java 21+, CoreArmorX installed on a Paper server, and a permission plugin only if progression locks are enabled.

Default behavior is conservative: progression locks, skin durability, and fire/lava stripping are disabled by default, and foreign custom item transformations are blocked when detected.

1. File Layout

plugins/CoreArmorX/
  config.yml
  armor-upgrades.yml
  armor-skins.yml
  messages.yml

plugin.yml is bundled inside the jar and documents commands, aliases, permissions, and plugin identity.

2. Reload vs Restart

Use /corearmorx reload for normal YAML edits, recipe changes, message edits, lore template changes, and progression permission node changes in YAML. Restart when replacing the jar, changing Paper/Minecraft version, or recovering from startup-only errors.

Existing YAML files are not automatically merged with newly packaged defaults. Compare live files with packaged defaults when updating snapshots.

3. Clean Setup Checklist

  • Install the jar and let defaults generate.
  • Decide whether to keep recipes.override-vanilla-equipment-recipes: true.
  • Configure upgrade and skin permissions only if progression-locks.enabled: true.
  • Keep custom item behavior on BLOCK_IF_DETECTED unless conversion is intentional.
  • Test recipes with separate one-item ingredient slots.

4. Runtime Model

CoreArmorX has two item modes. Normal upgraded armor uses vanilla material as the source of truth and does not receive CoreArmorX PDC. Skinned netherite armor changes material for the visual skin, keeps a netherite-equivalent profile, and stores clean material, skin identity, lore snapshot, model mode, and optional skin durability in PDC.

Already-skinned armor cannot be upgraded or skinned again until stripped.

5. config.yml

Controls global debug mode, protected vanilla recipe behavior, recipe book discovery, ingredient groups, default upgrade behavior, generated lore, leather color placeholders, inventory model mode, skin removal, fire/lava stripping, progression locks, and custom item protection.

# CoreArmorX main configuration.
#
# CoreArmorX is designed as a Paper-only vanilla+ armor progression plugin.
# This file controls global behavior. Recipe definitions live in:
# - armor-upgrades.yml
# - armor-skins.yml
#
# All text shown to players is configured in messages.yml.

settings:
  # Enables extra startup/reload diagnostic logs.
  # Keep false on production unless you are debugging configuration or recipe behavior.
  debug: false

recipes:
  # When true, CoreArmorX blocks protected vanilla direct armor recipe outputs at
  # crafting time and uses progression recipes instead. It does not remove
  # minecraft:* recipes from the server registry, so reload/disable is safe.
  # Leather armor and vanilla diamond -> netherite smithing are not touched.
  override-vanilla-equipment-recipes: true

  # Cooldown used by blocked-crafting messages to avoid chat spam.
  # Value is in server ticks. 20 ticks = 1 second.
  blocked-message-cooldown-ticks: 40

  recipe-book:
    # Registers static placeholder recipes so players can discover CoreArmorX
    # recipes naturally in the vanilla recipe book.
    enabled: true

ingredient-groups:
  # Ingredient groups let upgrade/skin definitions reference a named set instead
  # of a single Bukkit Material. Runtime matching is MATERIAL_ONLY, so any item
  # whose Material is listed here can satisfy that ingredient cost.
  #
  # The static recipe-book entry still uses the first valid material as the
  # representative ingredient; the runtime matcher accepts the whole group.
  COPPER_ARMOR_MATERIALS:
    - COPPER_INGOT

  # Chainmail uses nuggets by default to keep it as an intermediate vanilla+ step.
  CHAINMAIL_ARMOR_MATERIALS:
    - IRON_NUGGET

  IRON_ARMOR_MATERIALS:
    - IRON_INGOT

  GOLD_ARMOR_MATERIALS:
    - GOLD_INGOT

  DIAMOND_ARMOR_MATERIALS:
    - DIAMOND

  TURTLE_HELMET_MATERIALS:
    - TURTLE_SCUTE

upgrades:
  # Master switch for armor upgrade crafting.
  enabled: true

  # Default cost behavior used when an armor-upgrades.yml entry does not override it.
  # VANILLA_RECIPE_COST means helmet 5, chestplate 8, leggings 7, boots 4.
  cost-mode: VANILLA_RECIPE_COST

  # Durability behavior after an upgrade:
  # - REFILL: output item is fully repaired.
  # - KEEP_DAMAGE: preserves the exact damage value when possible.
  # - KEEP_PERCENTAGE: preserves the percentage of durability already used.
  durability-mode: REFILL

  # When true, anvil repair cost is preserved by Bukkit/Paper meta conversion
  # whenever the target item supports it. When false, upgrade output repair cost
  # is cleared.
  preserve-repair-cost: true

skins:
  # Master switch for visual skin recipes.
  enabled: true

  # V1 skin crafting is intentionally fixed to clean netherite armor in a
  # vanilla crafting table. Already-skinned items must be stripped first.

  lore:
    # Adds generated CoreArmorX lore lines that identify the active visual skin.
    # CoreArmorX snapshots the original item lore into PDC before rebuilding
    # the final lore from generated-lines.
    enabled: true

    # Legacy single-line format. Used only if generated-lines is empty.
    format: "<reset><gray>Skin: <white>{skin}"

    # MiniMessage lines rendered from current config every time the item is
    # refreshed, dyed, fixed, or skin durability changes.
    # The final item lore is exactly this list after placeholder expansion.
    # To display the saved original item lore, add a line that is exactly
    # {item_lore}. If this line is missing, the saved original lore remains in
    # PDC for skin removal/reset, but is not shown on the skinned item.
    #
    # Available placeholders:
    # - {item_lore}: must be its own list entry; expands to the saved original lore
    # - {skin}
    # - {skin_id}
    # - {real_tier}
    # - {visual_skin}
    # - {clean_material}
    # - {leather_color}: readable hex, same as {leather_color_hex}
    # - {leather_color_hex}: readable #RRGGBB value
    # - {leather_color_rgb}: readable R,G,B value
    # - {leather_color_square}: ready-to-render colored square MiniMessage
    # - {leather_color_minimessage}: MiniMessage color tag, for example <#A06540>
    # - {leather_color_name}: nearest readable color name
    # - {skin_durability_current}
    # - {skin_durability_max}
    # - {skin_durability_damage}
    # - {skin_durability_remaining}
    # - {skin_durability_percent}
    # - {skin_durability_bar}
    generated-lines:
      - "{item_lore}"
      - "<gray>Skin: <white>{skin}"
      # Example durability line. Uncomment it when skin-durability is enabled
      # in armor-skins.yml and you want the skin durability shown in lore.
      # - "<gray>Skin Durability: <white>{skin_durability_current}</white>/<white>{skin_durability_max}</white> {skin_durability_bar}"

  leather-color:
    # Enables leather color placeholders for leather-skinned armor.
    # If false, all leather color placeholders render as empty strings.
    placeholders: true

    # Character used by {leather_color_square}. It is rendered with the item's
    # leather color through MiniMessage.
    square-character: "\u25A0"

    default-color:
      # LEATHER_DEFAULT uses vanilla leather default color when no leather meta
      # is available. CUSTOM_HEX uses custom-hex instead.
      mode: LEATHER_DEFAULT
      custom-hex: "#A06540"

armor-skins:
  inventory-model:
    # REAL_TIER makes skinned netherite armor look like netherite in inventory
    # while keeping the visual skin when equipped.
    #
    # VISUAL_SKIN disables that inventory override and shows the visual Material
    # icon in the inventory.
    mode: REAL_TIER

skin-removal:
  # Master switch for removing a skin through crafting.
  enabled: true

  # Tool required in the crafting matrix with a skinned armor piece.
  # If damage-tool is true and consume-tool is false, this material must have
  # durability. Otherwise removal recipes are skipped and a config warning is logged.
  tool: SHEARS

  # If true, one shears item is consumed.
  consume-tool: false

  # If true, shears take durability damage instead of being consumed.
  damage-tool: true

  # Durability damage applied to shears when damage-tool is true.
  damage-amount: 1

skin-stripping:
  # If false, dropped skinned armor is protected from configured fire/lava
  # destruction causes and keeps the skin.
  #
  # If true, configured causes strip the skin and convert the item back into
  # clean netherite instead of destroying it.
  enabled: false

  # Supported v1 causes:
  # - LAVA
  # - FIRE
  causes:
    - LAVA
    - FIRE

  # MVP supports STRIP_SKIN only.
  mode: STRIP_SKIN

progression-locks:
  # Master switch for permission-based progression locks.
  # CoreArmorX does not store progression state internally.
  enabled: false

  blocks:
    # Blocks protected direct crafting/skin recipes when permission checks fail.
    crafting: true

    # Blocks armor upgrade recipes when permission checks fail.
    upgrades: true

    # Default false: found/traded/given armor remains usable.
    # If true, equipping/using armor requires corearmorx.use.<tier>.
    usage: false

  permissions:
    # Players with this permission bypass all CoreArmorX progression checks.
    bypass: "corearmorx.progression.bypass"

    # Prefix used when usage locking is enabled.
    # Example: corearmorx.use.netherite
    usage-prefix: "corearmorx.use"

compatibility:
  custom-items:
    # Custom item protection mode:
    # - BLOCK_IF_DETECTED: block transformation if foreign PDC data is found.
    # - REPLACE_ANYWAY: allow CoreArmorX transformations even when foreign PDC
    #   data is present. Use only when you know those custom items are safe.
    behavior: BLOCK_IF_DETECTED

{item_lore} must be its own generated lore entry. If it is missing, original lore remains stored in PDC but is not displayed.

6. armor-upgrades.yml

Defines normal armor progression recipes and special one-piece endpoint recipes. Supported fields include enabled, from-tier, from-material, to-tier, to-material, ingredient, cost-mode, count, and permission.

# CoreArmorX armor upgrade definitions.
#
# These recipes change the real armor tier. They do not write CoreArmorX PDC
# on normal upgraded items.
#
# Supported fields:
# - enabled: true/false
# - from-tier: LEATHER, COPPER, CHAINMAIL, IRON, GOLD, DIAMOND, NETHERITE
# - from-material: exact Bukkit Material, used for special one-piece recipes
# - to-tier: target tier for normal four-piece armor sets
# - to-material: exact Bukkit Material, used for special one-piece recipes
# - ingredient: Bukkit Material or ingredient-groups.<id> from config.yml
# - cost-mode: VANILLA_RECIPE_COST or CUSTOM
# - count: explicit ingredient count, used only when cost-mode is CUSTOM
# - permission: permission required when progression locks are enabled
#
# VANILLA_RECIPE_COST means:
# - helmet: 5
# - chestplate: 8
# - leggings: 7
# - boots: 4

upgrades:
  leather_to_copper:
    # First progression step after vanilla leather armor.
    enabled: true
    from-tier: LEATHER
    to-tier: COPPER
    ingredient: COPPER_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.upgrade.leather_to_copper"

  copper_to_chainmail:
    # Uses iron nuggets so chainmail feels like an intermediate vanilla+ tier.
    enabled: true
    from-tier: COPPER
    to-tier: CHAINMAIL
    ingredient: CHAINMAIL_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.upgrade.copper_to_chainmail"

  chainmail_to_iron:
    # Converts chainmail into iron using the normal armor-piece material counts.
    enabled: true
    from-tier: CHAINMAIL
    to-tier: IRON
    ingredient: IRON_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.upgrade.chainmail_to_iron"

  iron_to_gold:
    # Optional alternate progression branch from iron to gold.
    enabled: true
    from-tier: IRON
    to-tier: GOLD
    ingredient: GOLD_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.upgrade.iron_to_gold"

  iron_to_diamond:
    # Main progression path from iron to diamond.
    # Diamond -> netherite remains vanilla smithing and is not handled here.
    enabled: true
    from-tier: IRON
    to-tier: DIAMOND
    ingredient: DIAMOND_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.upgrade.iron_to_diamond"

  iron_helmet_to_turtle:
    # Special helmet-only progression branch.
    # Uses exact materials so this does not create recipes for other armor pieces.
    enabled: true
    from-material: IRON_HELMET
    to-material: TURTLE_HELMET
    ingredient: TURTLE_HELMET_MATERIALS
    count: 5
    permission: "corearmorx.upgrade.iron_helmet_to_turtle"

The default armor cost model is helmet 5, chestplate 8, leggings 7, boots 4.

7. armor-skins.yml

Defines netherite-only visual skin recipes, maps output materials, and controls optional skin durability. Default skin ids are leather, copper, chainmail, iron, gold, and diamond.

# CoreArmorX netherite skin definitions.
#
# Skin recipes are netherite-only. A skin changes the real Material to the
# configured output material while CoreArmorX applies netherite-equivalent
# durability, attributes, fire resistance, and PDC identity.
#
# Supported fields:
# - enabled: true/false
# - display-name: name used in generated lore and messages
# - ingredient: Bukkit Material or ingredient-groups.<id> from config.yml
# - cost-mode: VANILLA_RECIPE_COST or CUSTOM
# - count: explicit ingredient count, used only when cost-mode is CUSTOM
# - dyeable: true only for leather skin
# - permission: permission required when progression locks are enabled
# - output-materials: visual output Material per armor piece
#
# VANILLA_RECIPE_COST means:
# - helmet: 5
# - chestplate: 8
# - leggings: 7
# - boots: 4

skins:
  leather:
    # Dyeable visual skin. Vanilla leather dye recipes should keep CoreArmorX data.
    enabled: true
    display-name: "Leather"
    ingredient: LEATHER
    cost-mode: VANILLA_RECIPE_COST
    dyeable: true
    permission: "corearmorx.skin.leather"
    output-materials:
      helmet: LEATHER_HELMET
      chestplate: LEATHER_CHESTPLATE
      leggings: LEATHER_LEGGINGS
      boots: LEATHER_BOOTS

  copper:
    # Copper visual skin. Requires Paper/Minecraft versions with copper armor.
    enabled: true
    display-name: "Copper"
    ingredient: COPPER_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.skin.copper"
    output-materials:
      helmet: COPPER_HELMET
      chestplate: COPPER_CHESTPLATE
      leggings: COPPER_LEGGINGS
      boots: COPPER_BOOTS

  chainmail:
    # Chainmail visual skin, using iron nuggets as the material cost.
    enabled: true
    display-name: "Chainmail"
    ingredient: CHAINMAIL_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.skin.chainmail"
    output-materials:
      helmet: CHAINMAIL_HELMET
      chestplate: CHAINMAIL_CHESTPLATE
      leggings: CHAINMAIL_LEGGINGS
      boots: CHAINMAIL_BOOTS

  iron:
    # Iron visual skin.
    enabled: true
    display-name: "Iron"
    ingredient: IRON_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.skin.iron"
    output-materials:
      helmet: IRON_HELMET
      chestplate: IRON_CHESTPLATE
      leggings: IRON_LEGGINGS
      boots: IRON_BOOTS

  gold:
    # Gold visual skin. CoreArmorX does not add custom piglin logic in v1.
    enabled: true
    display-name: "Gold"
    ingredient: GOLD_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.skin.gold"
    output-materials:
      helmet: GOLDEN_HELMET
      chestplate: GOLDEN_CHESTPLATE
      leggings: GOLDEN_LEGGINGS
      boots: GOLDEN_BOOTS

  diamond:
    # Diamond visual skin. This does not affect vanilla diamond -> netherite smithing.
    enabled: true
    display-name: "Diamond"
    ingredient: DIAMOND_ARMOR_MATERIALS
    cost-mode: VANILLA_RECIPE_COST
    permission: "corearmorx.skin.diamond"
    output-materials:
      helmet: DIAMOND_HELMET
      chestplate: DIAMOND_CHESTPLATE
      leggings: DIAMOND_LEGGINGS
      boots: DIAMOND_BOOTS

skin-durability:
  # Skin durability is stored in CoreArmorX PDC and applies only to skinned
  # armor. It does not replace vanilla DAMAGE/MAX_DAMAGE on the real item.
  #
  # Supported v1 modes:
  # - DISABLED: no skin durability is tracked.
  # - GLOBAL: every skin uses global.max-durability.
  # - BY_SKIN: each skin reads by-skin.materials.<skin>, then fallback values.
  # - BY_ITEM: each piece reads by-item.materials.<skin>.<piece>, then fallback values.
  mode: DISABLED

  global:
    # Used only when mode is GLOBAL.
    # Every skinned armor item receives this same skin max durability.
    max-durability: 5000

  by-skin:
    # Used when mode is BY_SKIN and as a fallback for BY_ITEM.
    # If a skin material is missing below, CoreArmorX uses default-max-durability.
    default-max-durability: 5000

    materials:
      # Skin max durability per visual skin material.
      leather: 6000
      copper: 5000
      chainmail: 5500
      iron: 7000
      gold: 2500
      diamond: 9000

  by-item:
    # Used only when mode is BY_ITEM.
    # Missing piece values fall back to the material default, then BY_SKIN,
    # then this default-max-durability.
    default-max-durability: 5000

    materials:
      leather:
        # Fallback for leather pieces not listed below.
        default-max-durability: 6000
        helmet: 1800
        chestplate: 3200
        leggings: 2800
        boots: 1500

      copper:
        default-max-durability: 5000
        helmet: 1500
        chestplate: 2700
        leggings: 2300
        boots: 1250

      chainmail:
        default-max-durability: 5500
        helmet: 1650
        chestplate: 2930
        leggings: 2570
        boots: 1380

      iron:
        default-max-durability: 7000
        helmet: 2100
        chestplate: 3730
        leggings: 3270
        boots: 1750

      gold:
        default-max-durability: 2500
        helmet: 750
        chestplate: 1330
        leggings: 1170
        boots: 630

      diamond:
        default-max-durability: 9000
        helmet: 2700
        chestplate: 4800
        leggings: 4200
        boots: 2250

  damage:
    # Supported v1 mode: MIRROR_REAL_DAMAGE.
    # When the real armor takes durability damage, skin damage increases by the
    # same amount multiplied by multiplier.
    mode: MIRROR_REAL_DAMAGE
    multiplier: 1.0

  # Supported v1 action: REMOVE_SKIN.
  # When skin damage reaches max, the skin is stripped and the armor returns
  # to its clean netherite Material. Materials are not refunded.
  on-break: REMOVE_SKIN

  mending:
    # Supported v1 modes:
    # - DISABLED: CoreArmorX does not touch mending.
    # - SPLIT: odd repair points go to the real item, the rest repairs the skin.
    # - DOUBLE: vanilla repair remains unchanged and the skin repairs by the
    #   same amount. Recommended when damage mode is MIRROR_REAL_DAMAGE.
    mode: DISABLED

  placeholders:
    # Value inserted into durability placeholders when skin durability is
    # disabled or missing on the inspected item.
    disabled-value: ""

    # Basic MiniMessage bar fragments used by {skin_durability_bar}.
    # Include color tags here because the renderer does not hardcode colors.
    bar-segments: 10
    bar-full: "<green>|"
    bar-empty: "<dark_gray>|"

Skin durability modes are DISABLED, GLOBAL, BY_SKIN, and BY_ITEM. Mending modes are DISABLED, SPLIT, and DOUBLE.

8. messages.yml

Messages use Adventure MiniMessage. The configured prefix is prepended automatically. Only documented placeholders near each message should be used.

Inspect messages are useful for checking current material, clean material, visual skin, inventory model mode, CoreArmorX data, generated lore state, original lore snapshot, skin durability, leather color, tier, and armor piece.

# CoreArmorX messages.
#
# All user-facing text should live here.
# Messages use Adventure MiniMessage syntax:
# https://docs.advntr.dev/minimessage/format.html
#
# Placeholder format is {placeholder}. A message only receives placeholders
# that are meaningful for that specific command or event.

# Prefix is prepended automatically by MessageService to every configured message.
prefix: "<dark_gray>[<aqua>CoreArmorX</aqua>]</dark_gray> "

commands:
  # Generic permission failure for commands.
  no-permission: "<red>You do not have permission to do this."

  # Sent when an unknown /corearmorx subcommand is used.
  unknown: "<red>Unknown command. Use <white>/corearmorx help</white>."

  # Sent after /corearmorx reload successfully reloads configs and recipes.
  reloaded: "<green>CoreArmorX reloaded."

  # Placeholder:
  # - {version}: plugin version from plugin.yml
  version: "<gray>CoreArmorX version <white>{version}</white>."

  # Help command lines. Permission-gated lines are only shown when the sender
  # has the corresponding permission.
  help-header: "<gray>CoreArmorX commands:"
  help-version: "<dark_gray>- <aqua>/corearmorx version</aqua>"
  help-reload: "<dark_gray>- <aqua>/corearmorx reload</aqua>"
  help-inspect: "<dark_gray>- <aqua>/corearmorx inspect</aqua>"
  help-fixitem: "<dark_gray>- <aqua>/corearmorx fixitem</aqua>"

  # Sent when a player-only command is run from console.
  player-only: "<red>This command can only be used by a player."

crafting:
  # Sent when a protected vanilla armor recipe is blocked.
  blocked-vanilla-craft: "<red>You must upgrade the previous armor tier first."

  # Sent when permission-based progression blocks an upgrade or skin recipe.
  no-permission: "<red>You do not have permission for this armor progression."

  # Sent when compatibility mode blocks transformation of a detected custom item.
  custom-item-blocked: "<red>This custom item cannot be modified by CoreArmorX."

progression:
  # Sent when progression-locks.blocks.usage is true and the player lacks
  # the required corearmorx.use.<tier> permission.
  usage-blocked: "<red>You do not have permission to use this armor tier."

admin:
  # Sent by /corearmorx inspect when the player has no held item.
  inspect-empty-hand: "<red>Hold an armor item first."

  # Sent by /corearmorx fixitem when the player has no held item.
  fix-empty-hand: "<red>Hold an armor item first."

  # Sent by /corearmorx fixitem when the held item is not CoreArmorX skinned armor.
  fix-not-skinned: "<red>This item is not a CoreArmorX skinned armor item."

  # Sent by /corearmorx fixitem after the profile/lore/PDC refresh completes.
  fixed: "<green>Item fixed."

  inspect:
    # Header for /corearmorx inspect output.
    header: "<gray>Item inspection:"

    # Placeholder:
    # - {material}: current Bukkit Material name
    current-material: "<dark_gray>- <gray>Current Material: <white>{material}</white>"

    # Placeholder:
    # - {material}: saved clean netherite Material for skinned armor
    clean-material: "<dark_gray>- <gray>Clean Material: <white>{material}</white>"

    # Placeholder:
    # - {skin}: saved visual skin tier
    visual-skin: "<dark_gray>- <gray>Visual Skin: <white>{skin}</white>"

    # Placeholder:
    # - {mode}: REAL_TIER or VISUAL_SKIN
    inventory-model-mode: "<dark_gray>- <gray>Inventory Model Mode: <white>{mode}</white>"

    # Placeholder:
    # - {value}: true/false
    has-core-data: "<dark_gray>- <gray>Has CoreArmorX Data: <white>{value}</white>"

    # Placeholder:
    # - {value}: true/false
    generated-lore: "<dark_gray>- <gray>Generated Skin Lore: <white>{value}</white>"

    # Placeholder:
    # - {value}: true/false
    original-lore: "<dark_gray>- <gray>Original Lore Snapshot: <white>{value}</white>"

    # Placeholder:
    # - {damage}: skin durability damage stored in PDC
    # - {max}: skin max durability stored in PDC
    # - {remaining}: max minus damage
    # - {percent}: remaining percent
    skin-durability: "<dark_gray>- <gray>Skin Durability: <white>{remaining}</white>/<white>{max}</white> <dark_gray>({percent}%, damage {damage})"

    # Sent when skin durability mode is disabled or the item has no skin
    # durability PDC.
    skin-durability-disabled: "<dark_gray>- <gray>Skin Durability: <white>disabled</white>"

    # Placeholder:
    # - {color}: leather color as #RRGGBB
    leather-color: "<dark_gray>- <gray>Leather Color: <white>{color}</white>"

    # Placeholder:
    # - {tier}: detected armor tier for normal armor
    tier: "<dark_gray>- <gray>Tier: <white>{tier}</white>"

    # Placeholder:
    # - {piece}: detected armor piece for normal armor
    piece: "<dark_gray>- <gray>Piece: <white>{piece}</white>"

9. plugin.yml

Complete bundled plugin descriptor. Maven resolves ${project.version} when the release jar is built.

name: CoreArmorX
main: it.icewolf23x.corearmorx.CoreArmorXPlugin
version: ${project.version}
api-version: '1.21'
description: Vanilla+ armor progression and netherite armor skins for Paper.
author: IceWolf23X
prefix: CoreArmorX
commands:
  corearmorx:
    description: CoreArmorX main command.
    usage: /corearmorx
    aliases:
      - cax
permissions:
  corearmorx.admin:
    description: Grants all CoreArmorX admin permissions.
    default: op
    children:
      corearmorx.admin.reload: true
      corearmorx.admin.inspect: true
      corearmorx.admin.fixitem: true
      corearmorx.progression.bypass: true
  corearmorx.admin.reload:
    description: Allows reloading CoreArmorX configuration.
    default: op
  corearmorx.admin.inspect:
    description: Allows inspecting held CoreArmorX armor items.
    default: op
  corearmorx.admin.fixitem:
    description: Allows repairing CoreArmorX metadata/profile on the held item.
    default: op
  corearmorx.progression.bypass:
    description: Bypasses CoreArmorX permission progression locks.
    default: op
  corearmorx.skin.*:
    description: Allows every CoreArmorX armor skin.
    default: op
    children:
      corearmorx.skin.leather: true
      corearmorx.skin.copper: true
      corearmorx.skin.chainmail: true
      corearmorx.skin.iron: true
      corearmorx.skin.gold: true
      corearmorx.skin.diamond: true
  corearmorx.upgrade.*:
    description: Allows every CoreArmorX armor upgrade.
    default: op
    children:
      corearmorx.upgrade.leather_to_copper: true
      corearmorx.upgrade.copper_to_chainmail: true
      corearmorx.upgrade.chainmail_to_iron: true
      corearmorx.upgrade.iron_to_gold: true
      corearmorx.upgrade.iron_to_diamond: true
      corearmorx.upgrade.iron_helmet_to_turtle: true
  corearmorx.use.*:
    description: Allows using every CoreArmorX armor tier when usage locks are enabled.
    default: op
    children:
      corearmorx.use.leather: true
      corearmorx.use.copper: true
      corearmorx.use.chainmail: true
      corearmorx.use.iron: true
      corearmorx.use.gold: true
      corearmorx.use.diamond: true
      corearmorx.use.netherite: true
      corearmorx.use.turtle: true

10. Permissions

corearmorx.admin
corearmorx.admin.reload
corearmorx.admin.inspect
corearmorx.admin.fixitem
corearmorx.progression.bypass
corearmorx.upgrade.*
corearmorx.skin.*
corearmorx.use.*

Usage permissions matter only when both progression-locks.enabled and progression-locks.blocks.usage are true.

11. Troubleshooting Quick Reference

No recipe appears

  • Check recipes.recipe-book.enabled.
  • Check the relevant entry has enabled: true.
  • Run /corearmorx reload.
  • Check console warnings for invalid materials or costs above 8.

Recipe output appears but clicking does nothing

  • Check progression permissions if locks are enabled.
  • Use separate one-item ingredient slots.
  • Confirm the base item is not already skinned.
  • Check custom item compatibility mode.

Skinned armor lost expected lore

Ensure {item_lore} exists in skins.lore.generated-lines, then hold the item and run /corearmorx fixitem.

Player cannot equip armor

Check progression-locks.blocks.usage, then grant corearmorx.use.<tier> or corearmorx.progression.bypass.

12. Production Validation Checklist

  • Run /corearmorx reload.
  • Confirm console has no CoreArmorX warnings.
  • Craft one normal upgrade from each configured path.
  • Craft one skin recipe.
  • Remove one skin with shears.
  • Inspect a skinned item with /corearmorx inspect.
  • Run /corearmorx fixitem.
  • Test fire/lava behavior if skin stripping changed.
  • Test permissions with a non-op account if progression locks are enabled.