Information
OptimalCosmetics gives players a menu of equippable cosmetics - chat colors, tags, name paints, glow, tab icons, join and leave messages - with a player-to-player market and openable cases (crates) placed in the world. Players own cosmetics (there are no per-cosmetic permissions) and equip one per type.
The plugin does not render chat or nametags itself. It exposes every equipped cosmetic through
PlaceholderAPI, and an external chat/nametag plugin (DeluxeChat, that kind of thing) renders
them. The exceptions the plugin handles directly: join/leave messages (it sets the vanilla join/quit
message), glow (it toggles the entity glow flag), and - optionally - chat colors (see
Paint-Chat-Message). See Placeholders below.
- Software: Paper / Folia (and Paper forks).
api-version1.20, Folia-supported. - Minecraft: 1.20+ (tested on 1.21.11)
- Java: 21+ (required)
- Soft dependencies: PlaceholderAPI, Vault, PlayerPoints, RivalCredits, DecentHolograms
Cosmetic types
Section titled “Cosmetic types”One cosmetic can be equipped per type. Each type is one file in cosmetics/ holding many cosmetics.
| Type | File | What it does |
|---|---|---|
| Chat Color | chat-colors.yml |
Colors the player’s chat message (via placeholder, or directly with Paint-Chat-Message). |
| Tag | tags.yml |
A prefix/label exposed for your chat or nametag plugin to render. |
| Name Paint | name-paints.yml |
Colors/gradients the player’s name (via placeholder). |
| Glow | glow.yml |
Makes the player glow. Outline color cycles via a placeholder. |
| Tab Icon | tab-icons.yml |
A symbol exposed for the tab list (via placeholder). |
| Join Message | join-messages.yml |
Replaces the player’s vanilla join message. |
| Leave Message | leave-messages.yml |
Replaces the player’s vanilla quit message. |
How players get cosmetics: an admin give, redeeming a voucher, buying on the
market, or winning one from a case.
Features
Section titled “Features”- Seven cosmetic types, one equipped per type, stored per player (SQLite or MySQL)
- Paginated cosmetics menu with a type filter and sort (Item / Rarity / Alphabetical)
- Player-to-player market: list a cosmetic for sale, buy others’, with escrow, tax, fees and limits
- Cases (crates): a placed block players pay to open, with a spin animation and limited-edition wins
- Vouchers: redeemable items that grant a specific cosmetic
- Fully dynamic rarities (add/remove your own; config order = rank)
- Pluggable economy: Vault, PlayerPoints or RivalCredits
- Every menu is a config file with action-driven items you can re-theme freely
- Full PlaceholderAPI output in MiniMessage or legacy
§form for any chat/nametag plugin - Folia-ready (region schedulers throughout)
Commands
Section titled “Commands”Player - /cosmetics (alias /cosmetic):
/cosmetics- open the cosmetics menu ·optimalcosmetics.use/cosmetics market- open the cosmetics market ·optimalcosmetics.use
Admin - /cosmeticsadmin (alias /cosmeticadmin) · all optimalcosmetics.admin:
/cosmeticsadmin give <player> <cosmetic|all>- grant a cosmetic, orall. Works on offline players. Blocked if the target has that cosmetic listed on the market./cosmeticsadmin remove <player> <cosmetic|all>- revoke a cosmetic, orall. Works offline./cosmeticsadmin givevoucher <player> <cosmetic> [amount]- give redeemable vouchers (online player; the cosmetic needs aVoucherblock)./cosmeticsadmin maxlistings <player> <amount|reset>- set or reset a player’s market listing limit./cosmeticsadmin place <case>- get a case block to place in the world./cosmeticsadmin reload- reload every config file.
Permissions
Section titled “Permissions”optimalcosmetics.use-/cosmeticsand the market (default: everyone)optimalcosmetics.admin- every/cosmeticsadmincommand, plus placing and removing case blocks in the world (default: op)
Cosmetics themselves are ownership-based, not permission-based - there are no per-cosmetic permission nodes. A player either owns a cosmetic or does not.
Placeholders
Section titled “Placeholders”Requires PlaceholderAPI. Identifier optimalcosmetics. Text placeholders return MiniMessage by
default, or legacy § codes when Settings.Placeholder-Format is Legacy - match this to what your
chat/nametag plugin expects.
Equipped cosmetic output:
%optimalcosmetics_tag%- equipped tag%optimalcosmetics_chatcolor%/%optimalcosmetics_chatcolor_suffix%- chat-color prefix / suffix (split around{context})%optimalcosmetics_namepaint%- the player’s name, painted (%..._namepaint_suffix%is always empty)%optimalcosmetics_glow%- the current glow outline color, cycling every 2 seconds%optimalcosmetics_tabicon%- equipped tab icon (with a leading space), or empty
Per type (<type> = chatcolor, tag, namepaint, glow, tabicon, joinmessage, leavemessage):
%optimalcosmetics_<type>_id%- equipped cosmetic id (raw)%optimalcosmetics_<type>_name%- equipped cosmetic display name%optimalcosmetics_<type>_value%- equipped cosmetic value%optimalcosmetics_<type>_count%- number of enabled cosmetics of that type%optimalcosmetics_<type>_owned%- how many of that type the player owns
Totals:
%optimalcosmetics_count%- total enabled cosmetics%optimalcosmetics_owned%- cosmetics the player owns
The market
Section titled “The market”Players sell cosmetics they own to other players for your server currency. Listing a cosmetic puts it
in escrow (it leaves the seller’s collection until it sells or is delisted). A sale charges the
buyer the full price and pays the seller the price minus a configurable sale tax; an optional
listing fee is charged when the item is listed. Prices are bounded by Min-Price/Max-Price,
players are capped by Max-Listings, and listings expire after Expiry-Days. Full guide:
Market; tuning: config.yml → Market.
A case is a block you place in the world that players pay to open. Opening plays a spin animation and awards a random cosmetic from the case’s pool; owning it already gives a voucher instead. Cases can hold limited cosmetics with a fixed number of winners. Setup: Cases; file reference: cases.yml.
Vouchers
Section titled “Vouchers”A voucher is an item a player right-clicks to unlock a specific cosmetic. Admins hand them out
with /cosmeticsadmin givevoucher, and cases give one when a player wins a cosmetic they already own.
A cosmetic is only voucher-giveable if it has a Voucher block (or you set a global fallback in
config.yml). See config.yml → Voucher and
Creating Cosmetics.
Formatting
Section titled “Formatting”Every text field supports legacy & codes, &#RRGGBB hex, MiniMessage (<gradient:a,b,c>,
<rainbow>, <bold>, <#RRGGBB>, <solid:HEX>, …) and PlaceholderAPI %...%. <gradient> accepts
comma-separated hex stops. Join and leave messages also support [center]...[/center] to center the
line in chat. Rarity color tokens {primary} and {secondary} are filled from
Rarity-Colors wherever they appear.
Reference
Section titled “Reference”- Install: Installation
- Add cosmetics: Creating Cosmetics
- Config files: config.yml · cosmetics · cases.yml · menus · messages.yml