Skip to content

Entity skins

✅ Available

TiedUp!‘s NPCs (kidnappers, damsels, maids, guards…) pick their appearance from a pool of data-driven skins. A skin is two files: a tiny JSON describing it, plus the texture PNG it points at. Add a JSON + PNG pair to your addon pack and the matching NPC type starts rolling your skin into its random pool — no Java, no model work.

A skin is the JSON (under data/) plus its texture (under assets/) — both live in your one addon pack. See Packaging for the full folder layout; within it, your two files go here:

data/<namespace>/skins/<entity-type>/<skin-id>.json ← the definition
assets/tiedup/textures/entity/<…>/<skin-id>.png ← the texture

You only add files — you never edit a shipped one. The <skin-id> part of the filename is conventional; the actual id comes from the JSON’s id field (see the schema).

Only id is required; everything else has a default.

FieldTypeDefaultNotes
idstringRequired. The skin id. Also the PNG filename (<id>.png) and the registry key. Must be unique within the type.
hasSlimArmsboolfalsetrue = Alex (3px) arms, false = Steve (4px) arms. Matches how you authored the texture.
defaultNamestring"NPC"Display name shown for an NPC wearing this skin.
genderstring"female""male" or "female" (case-insensitive). Anything else falls back to female. Drives model/voice/text selection.
texturestring (resource location)derivedOptional. Explicit texture under any namespace, e.g. "mypack:textures/entity/damsel/foo.png". Used verbatim when present; omit it to auto-derive tiedup:textures/entity/<type>/<id>.png.

The smallest valid definition — id only (gets Steve arms, name "NPC", female):

{
"id": "anastasia"
}

What the shipped skins actually look like:

{
"id": "anastasia",
"hasSlimArms": true,
"defaultName": "Anastasia"
}

A male kidnapper with classic arms:

{
"id": "dean",
"hasSlimArms": false,
"defaultName": "Dean",
"gender": "male"
}

These are the only ten folder names that are scanned. The folder is the entity type; the texture sub-path is auto-mapped (note several differ from the folder name).

skins/ folder (entity type)NPCTexture folder → assets/tiedup/textures/entity/…
kidnapperKidnapperkidnapper/
kidnapper_eliteElite kidnapperkidnapper/elite/
kidnapper_archerArcher kidnapperkidnapper/archer/
kidnapper_merchantMerchant kidnapperkidnapper/merchant/
maidMaidkidnapper/maid/
slave_traderTraderkidnapper/trader/
labor_guardGuardguard/
masterMastermaster/
damselDamseldamsel/
damsel_shinyShiny damseldamsel/shiny/

So a skin id: "athena" placed in data/<ns>/skins/kidnapper_elite/ looks for its texture at assets/tiedup/textures/entity/kidnapper/elite/athena.png — the JSON folder and the PNG folder are not the same string for the special-cased types in the table above.

  1. After a /reload (or restart) your skins are rescanned. An NPC of that type then picks a random skin from the pool at spawn — more JSON files mean more variety.
  2. Pick a unique id per type: a second skin with an already-used id is dropped, not merged.
  3. A JSON that fails to parse (e.g. missing id) is skipped and the rest still load — if a skin doesn’t appear, you’ll see a warning in the log.

An NPC’s display name comes from its skin’s defaultNameexcept numbered “mob” skins (ids like dam_mob_1, knp_mob_1, …), which get a random name from a gender-matched pool.

Those pools are data-driven too. Add names by dropping JSON in data/<namespace>/tiedup_npc_names/:

data/mypack/tiedup_npc_names/female_extra.json
{ "gender": "female", "names": ["Mireille", "Soraya", "Bao"] }
FieldNotes
gender"female" or "male". A name is only drawn from the pool matching the NPC’s gender.
namesarray of strings; blank entries are ignored.

Your file merges into the pool (it never replaces the built-in names), so you only add. The picked name travels to clients with the entity, so a name pool installed on the server only works in multiplayer — no client copy needed. Male NPCs draw from the male pool (a small male pool ships by default); if a gender’s pool is empty, names fall back to the other gender, then to a built-in shortlist.

  1. Author the texture as a 64×64 player skin PNG. Decide Steve vs. Alex arms.
  2. Save it to assets/tiedup/textures/entity/damsel/rosalind.png (the tiedup namespace, the damsel/ folder from the type table, filename = your id).
  3. Write the definition to data/<your-ns>/skins/damsel/rosalind.json:
    {
    "id": "rosalind",
    "hasSlimArms": true,
    "defaultName": "Rosalind",
    "gender": "female"
    }
  4. /reload (or restart). Your skin joins the damsel pool, and new damsels can roll it.

Overview & content pipeline

Where datapack (data/) vs. resourcepack (assets/) files live, and how a combined pack is laid out. → Overview

Packaging

Bundling your skins (and items, meshes, animations) into a shippable pack. → Packaging