Dex Cosmetics
ModHats. Wings. Snowstorm Particles. Custom item skins. All server-side. Your players don't install a thing.
Type
Mod
Modrinth Downloads
13
Modrinth ID
nkJq3egB
Last Updated
Jun 7, 2026
Description
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
- Minecraft: 1.21.1
- Mod loader: Fabric 0.19.2 or newer
- Server-side only — clients run vanilla; no client install required
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 runtimeInstallation
- 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).
- 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.
- (Optional) Install LuckPerms if you want permission-based admin command access. Without it, admin commands gate on op level 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" }- require_resource_pack — when true, clients who decline the pack are kicked with resource_pack_kick_message. Set false to allow players in without it (they'll see vanilla everything).
- autosave_interval_seconds — currently informational; player data is persisted on every grant/revoke/equip.
- particle_tick_budget_per_player — currently informational; particle cosmetics throttle via interval_ticks per cosmetic.
- admin_permission — LuckPerms permission node checked for /cosmetics give/take/list/reload/generatepack. Without LuckPerms, op-level 4 is required.
- allow_item_skin_sharing — when true (default), skinned items keep their skin when dropped/traded. When false, the skin component is stripped the moment a non-owner picks the item up.
- rename_item_to_skin_name — when true, items with an applied skin show the cosmetic's display name instead of the vanilla item name. Name override happens at sync time on the client copy, so trading doesn't permanently rename the underlying stack.
Cosmetic definitions — config/dex_cosmetics/cosmetics/<type>/<id>.json
One JSON file per cosmetic, grouped into four subdirectories:
- hats/ — head equipment (type: HAT)
- back/ — capes, wings, backpacks (type: BACK)
- items/ — held-item skins (type: ITEM)
- effects/ — particles, glow, snowstorm (type: EFFECT)
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:
- HAT — uses transform to bake an offset/scale into the model's display.head perspective.
- BACK — only scale.x is read (uniform scale via SCALE attribute). Position is fixed by vanilla armor-stand mount logic.
- ITEM — needs item_skin: { compatible_items: [...] }. Each entry is an item id (minecraft:diamond_sword) or tag (#minecraft:swords).
- EFFECT — needs effect: { kind: "particle" | "glow" | "snowstorm", ... }. See bundled examples in cosmetics/effects/.
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:
- Particle: vanilla particles. Two authoring modes — built-in curated shapes (point / trail / halo / orbit / square) parameterized by particle type + count + radius, OR raw vanilla commands run at the wearer's position with op-level + silent feedback.
- Glow: vanilla GLOWING status effect refreshed each tick. Per-cosmetic outline color via scoreboard team membership (one dex_glow_<formatting> team per Formatting color).
- Snowstorm: Bedrock-format particle burst via Cobblemon's SpawnSnowstormParticlePacket. Throttled by interval_ticks, broadcast within broadcast_radius blocks of the wearer.
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 packResource pack assembly happens at SERVER_STARTING after tag load:
- CosmeticItems.registerAll allocates a CMD per cosmetic + per (skin, item) variant via PolymerResourcePackUtils.requestModel.
- DexCosmetics.buildResourcePack triggers Polymer's RESOURCE_PACK_CREATION_EVENT.
- The event handlers run pipeUserTextures, pipeSnowstormParticles, PackModelGenerator.writeAll, GlowIconGenerator.writeAll, and write the blocks + particles atlas overrides.
- polymer-autohost serves the resulting polymer/resource_pack.zip on subsequent joins.
Making a cosmetic
- Model: in Blockbench, design the cosmetic. Use Java Block/Item project type so the export includes parent and display blocks.
- Texture: export the PNG and drop it under config/dex_cosmetics/textures/<type>/<id>/<id>.png.
- Cosmetic config: write a JSON file under config/dex_cosmetics/cosmetics/<type>/<id>.json (mirror the bundled examples).
- 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.
- Reload: /cosmetics reload or restart the server. Players need to reconnect to re-download the updated pack.
Compatibility
Mod Loaders
Game Versions
Screenshots
Similar Mods
Sharky Tweaks
Misc tweaks to aquatic creatures! Axolotl and Tropical fish bucket variants.
TLRB Artifacts
Adds custom LOTR Based artifacts designed for enhancing roleplay
Progressioned
A mod about making the start of minecraft harder by adding more progression
Retro Vibes
Minor changes to lighting to mimic early versions of the game
Ombre de Bushy
Grows a danger zone that slowly kills players
Centered Inventory
This project centers the inventory even when the Recipe Book is enabled