HomeJavaModsDex Cosmetics
Dex Cosmetics
Dex Cosmetics — screenshot 1Dex Cosmetics — screenshot 2

Dex Cosmetics

A server-side cosmetics mod for Fabric 1.21.1. Hats, back items (capes, wings, backpacks), item skins, and visual effects (particles, glow outlines, Bedrock-format particles). 100% server-installed — vanilla clients see everything through Polymer's auto-served resource pack.

Requirements

Dependencies

Dependency Version Type Role
fabric-api 0.116.12+1.21.1 Required Core Fabric APIs (events, commands, networking)
fabric-language-kotlin 1.13.11 / Kotlin 2.3.21 Required Mod is written in Kotlin
polymer 0.9.19+1.21.1 Required Server-side custom items + model registration
text-placeholder-api 2.4.2+1.21 Required (transitive) MiniMessage-style text parsing
LuckPerms 5.4 API Optional Permission checks for admin commands; falls back to vanilla op-level if absent
Cobblemon 1.7.3+1.21.1 Optional Needed only for snowstorm-particle effects; gated at runtime

Installation

  1. Drop the mod jar into your server's mods/ folder along with its required dependencies (Fabric API, Fabric Language Kotlin, all four Polymer modules, sgui, placeholder-api).
  2. Start the server once — on first run it generates config/dex_cosmetics/ with the default settings file, bundled example cosmetics, and the directory layout for adding your own.
  3. (Optional) Install LuckPerms if you want permission-based admin command access. Without it, admin commands gate on op level 4.
  4. (Optional) Install Cobblemon if you want snowstorm-particle effects. Without it those cosmetics still load but render nothing.

Clients connect normally — Polymer-autohost serves the resource pack automatically on join. The pack is marked required by default; players who decline will be kicked. This is configurable.

Configuration

Global config — config/dex_cosmetics/config.json

{
  "require_resource_pack": true,
  "resource_pack_kick_message": "This server requires the Dex Cosmetics resource pack.",
  "autosave_interval_seconds": 300,
  "particle_tick_budget_per_player": 32,
  "admin_permission": "dexcosmetics.admin",
  "allow_item_skin_sharing": true,
  "rename_item_to_skin_name": false,
  "resource_pack_mode": "auto",
  "custom_model_data_start": 2000,
  "menu_categories": {
    "ITEM": true,
    "HAT": true,
    "BACK": true,
    "EFFECT": true,
    "BALLOON": false,
    "POKEMON": false
  },
  "menu_focus": "HAT"
}

Cosmetic definitions — config/dex_cosmetics/cosmetics/<type>/<id>.json

One JSON file per cosmetic, grouped into four subdirectories:

Each file defines:

{
  "id": "my_cosmetic",
  "type": "HAT",
  "display_name": "<gold>My Hat</gold>",
  "description": ["Lore line 1", "Lore line 2"],
  "model": "dex_cosmetics:hats/my_cosmetic",
  "texture": "dex_cosmetics:hats/my_cosmetic/my_cosmetic",
  "model_parent": "minecraft:item/generated",
  "transform": {
    "offset_x": 0, "offset_y": 0, "offset_z": 0,
    "scale_x": 1, "scale_y": 1, "scale_z": 1
  }
}

Per type:

Models — config/dex_cosmetics/model/<type>/<id>.json

Drop a Blockbench export here named after the cosmetic id; the pack will use it automatically. If absent, a simple {parent, layer0} model is created from the cosmetic's model_parent and texture fields.

For held tools (item skins, etc.), make sure the model has "parent": "minecraft:item/handheld" and a proper display.

Textures — config/dex_cosmetics/textures/<type>/<id>/<png>

A file at textures/hats/my_hat/example.png appears in the pack as assets/dex_cosmetics/textures/hats/my_hat/example.png and is referenceable as dex_cosmetics:hats/my_hat/example. .mcmeta files alongside PNGs pass through, so animated textures work.

Snowstorm particles — config/dex_cosmetics/snowstorm_particles/<id>.particle.json

Bedrock-format particle definitions. The description.identifier field inside the JSON is what an EFFECT cosmetic references via effect.snowstorm.particle_id. Cobblemon's BedrockParticleEffectRepository picks them up at pack-build time.

Features

Cosmetic types

Hats — sent via fake EntityEquipmentUpdateS2CPacket so vanilla's helmet-bone armor pipeline renders them. Head rotation, pitch-based forward shift, perfect tracking. The wearer's real helmet stays in their inventory untouched.

Back items — invisible marker entity mounted as a passenger of the wearer, with the cosmetic item in the HEAD equipment slot. Automatically hides during SWIMMING / FALL_FLYING / SLEEPING / SPIN_ATTACK poses and respawns on pose exit.

Item skins — players apply skins through the cosmetics GUI by holding the target item and clicking the skin icon. Optional config to strip the skin when a non-owner picks the item up.

Effects — three flavors via the kind field:

Per-player ownership

SQLite-backed per-player ownership of cosmetics. Players see their full catalog in the GUI but can only equip cosmetics they own. Admins grant/revoke via commands.

Storage lives in <world>/dex_cosmetics/cosmetics.db. Two tables: player_owned (uuid, cosmetic_id) and player_equipped (uuid, type, cosmetic_id). Schema is created on first run.

Crate / shop integration

Existing crate plugins, shops, and loot tables grant cosmetics by running:

/cosmetics give <player> <cosmetic_id>

(or /cosmetics take to revoke). This is the supported integration point — anything that can execute a console command can give cosmetics.

Player commands

Command Permission Description
/cosmetics none Opens the cosmetics GUI
/cosmetics remove none Removes any applied skin from the held item
/cosmetics give <player> <id> admin Grants ownership of a cosmetic
/cosmetics take <player> <id> admin Revokes ownership
/cosmetics list <player> admin Lists what the player owns
/cosmetics reload admin Reloads all cosmetic configs and rebuilds the resource pack
/cosmetics generatepack admin Manually generates resource pack

Resource pack assembly happens at SERVER_STARTING after tag load:

  1. CosmeticItems.registerAll allocates a CMD per cosmetic + per (skin, item) variant via PolymerResourcePackUtils.requestModel.
  2. DexCosmetics.buildResourcePack triggers Polymer's RESOURCE_PACK_CREATION_EVENT.
  3. The event handlers run pipeUserTextures, pipeSnowstormParticles, PackModelGenerator.writeAll, GlowIconGenerator.writeAll, and write the blocks + particles atlas overrides.
  4. polymer-autohost serves the resulting polymer/resource_pack.zip on subsequent joins.

Making a cosmetic

  1. Model: in Blockbench, design the cosmetic. Use Java Block/Item project type so the export includes parent and display blocks.
  2. Texture: export the PNG and drop it under config/dex_cosmetics/textures/<type>/<id>/<id>.png.
  3. Cosmetic config: write a JSON file under config/dex_cosmetics/cosmetics/<type>/<id>.json (mirror the bundled examples).
  4. Model file (optional but common): if you have a Blockbench export with multiple textures, custom elements, etc., save it as config/dex_cosmetics/model/<type>/<id>.json.
  5. Reload: /cosmetics reload or restart the server. Players need to reconnect to re-download the updated pack.
Quick facts

Install steps are the general flow for this file type — How to install Minecraft Java mods & modpacks walks through it step by step.

Verified by MCModsHub

These come from our own check of the pack file, not from the source page.

Explore more