Skip to content

02 Datapacks Adding Skins

json-nn edited this page Jul 22, 2026 · 1 revision

Adding Skins: the Datapack

This page covers the JSON files that register skins — their IDs, names, colors, and metadata. Registering a skin here doesn't make it look like anything by itself; that's the resource pack's job (next page). Think of this file as the "database entry," and the resource pack as the "artwork."

File location

data/<any_namespace>/skins/<any_file_name>.json
  • <any_namespace> can be anything — your pack's own namespace is fine, it doesn't need to match mcpskins or the gun pack's namespace.
  • <any_file_name> can also be anything, but naming the file after the weapon it configures (m4a1.json, ak74.json, ...) keeps a pack organized as it grows.
  • One file describes the skins for exactly one weapon (see the warning below about splitting a weapon across multiple files).

MCPSkins loads every JSON file under any data/*/skins/ folder, from every active datapack, on world load and on /reload.

Schema

{
  "base_gun": "tacz:m4a1",
  "skins": [
    {
      "id": "m4a1_cobra",
      "name": "Cobra",
      "label_color": "0xFF5533",
      "rarity": "RARE",
      "collection": "Snake Pack",
      "description": "Strike fast, strike quiet.",
      "is_new": true
    }
  ]
}

Top level

Field Required Type Description
base_gun yes string The exact GunId of the weapon this file adds skins for, including its namespace — this is the same value the gun pack itself registers the weapon under (e.g. tacz:m4a1, or create_armorer:cannon for a third-party gun pack). Copy it verbatim from the gun pack; don't guess.
skins yes array The list of skins for this weapon. Can be empty, but there's not much point in that.

Each entry in skins

Field Required Type Default Description
id yes string The skin's unique ID. See "About IDs" below — this is the single most important field to get right.
name yes string Display name shown in menus and chat. This is plain text, not a translation key — see the note below.
label_color yes string A hex color, e.g. "0xFF5533" or "#FF5533". This is the single source of truth for the skin's accent/tint color wherever the mod shows one (menus, chat, the unlock item's icon tint).
rarity no string "COMMON" One of COMMON, UNCOMMON, RARE, EPIC, LEGENDARY. Purely cosmetic/organizational — used for filtering, sorting, and the accent color in the Armory screen, and as the tier system for the fusion mechanic. Unrecognized or blank values silently fall back to COMMON.
collection no string "" (none) A free-text collection/set name, used to group related skins together in the Armory UI.
description no string "" (none) Short flavor text shown in the Armory's detail panel.
is_new no boolean false Shows a "NEW" badge on the skin in the Armory grid. There's no automatic expiry — turn it off yourself once a skin isn't new anymore.

Note on name and description. These are literal strings baked straight into the skin data, not translation keys — you will not find m4a1_cobra in any en_us.json, and you don't need to add one. This keeps skin packs simple (no lang file required) but does mean skin names/descriptions aren't automatically translated for different client languages; if you need localization, you're on your own to swap the file per language, since the mod itself doesn't route these through the translation system.

About IDs — read this before naming your first skin

A skin's id does three jobs at once, and understanding all three will save you a lot of confusion:

  1. It's the skin's identity everywhere in the mod — commands, network sync, the "unlocked skins" list.
  2. It's the texture file name the resource pack looks for (see the next page) — the resolver builds a path directly from this string.
  3. It's the key used in each player's personal "unlocked skins" set.

Because of job #3, skin IDs must be globally unique across your entire server — not just unique per weapon. Two different weapons cannot both use a skin called "cobra", because unlocking one would silently also "unlock" the other in the player's eyes. The recommended, collision-proof naming scheme is:

<base_gun_short_name>_<skin_name>

e.g. m4a1_cobra, ak74_golden, deagle_neon. This is exactly what's used in the example above and throughout this wiki.

Tip — skins from third-party packs. If your skin lives in its own resource pack under its own namespace (rather than the mcpskins namespace — see the next page), you can prefix the ID with that namespace, e.g. "id": "mypack:golden_cobra". This only affects where the texture files are looked up; it's still one flat global ID space for ownership purposes, so the uniqueness rule above still applies.

The automatic "Default" skin

You never need to (and shouldn't) manually register a "no skin"/stock entry — MCPSkins adds one automatically for every base_gun it sees, named Default, with ID default:<base_gun> (e.g. default:tacz:m4a1), white color, COMMON rarity, and it's always considered "owned" by every player. This is also the value the mod treats as "no skin applied" internally — you'll see "default:" prefixes referenced elsewhere in this wiki for exactly that reason.

Optional fields are safe to omit

If you're maintaining an older skin pack, you don't need to backfill rarity/collection/description/is_new — a JSON file with only id, name, and label_color per skin loads exactly as before, with all four optional fields defaulting as documented above. Nothing breaks.

⚠️ One file per weapon — don't split a weapon across two datapacks

MCPSkins rebuilds its entire skin registry from scratch on every reload, keyed by base_gun. If two different JSON files (whether from the same pack or two different active datapacks) both declare a base_gun of "tacz:m4a1", the second one processed completely replaces the first — their skin lists are not merged. In practice this means:

  • ✅ Fine: Pack A configures tacz:m4a1, Pack B configures tacz:ak74. No conflict.
  • ✅ Fine: Two files inside the same pack, as long as neither repeats a base_gun already used elsewhere.
  • ❌ Broken: Pack A and Pack B both try to add skins to tacz:m4a1. Whichever pack's file loads last "wins," and the other pack's skins for that weapon silently vanish (their ids still work for anything already saved in a player's unlock list, but they'll never show up as available to preview/select again while the winning pack is active).

If you're combining multiple community skin packs for the same weapon, merge their skins arrays into a single file by hand rather than loading both as-is.

A quick example with everything filled in

{
  "base_gun": "tacz:ak74",
  "skins": [
    {
      "id": "ak74_desert",
      "name": "Desert Storm",
      "label_color": "0xC9A66B",
      "rarity": "UNCOMMON",
      "collection": "Battlefield",
      "description": "Sand-worn and battle-tested."
    },
    {
      "id": "ak74_golden",
      "name": "Golden Eagle",
      "label_color": "0xFFD700",
      "rarity": "LEGENDARY",
      "collection": "Battlefield",
      "description": "For the ones who never miss.",
      "is_new": true
    }
  ]
}

Next: turn ak74_golden from a database entry into something that actually looks golden — Adding Skins: the Resource Pack.