Content generated with AI — it may contain mistakes.

Getting started

First steps

The first ten minutes: the menu, what a player already owns, granting a tag, and getting the identity into your chat format.

The plugin is installed and the server is up. Nothing about your chat has changed, no player has been given anything, and the catalogue is sitting there with 180 tags and about 350 colours in it. This is the shortest route from that to a player wearing something and everybody seeing it.

Open the menu

/cc in game. The permission it wants, exyliachatcosmetics.command.cosmetics, is declared default: true in plugin.yml, so every player already has it — an undeclared node is operator-only in Bukkit, which is exactly why the ones a player needs to use the plugin are declared and the ones that decide what they own are not.

The main screen has seven things on it: YOUR CHAT, a live preview of the line the player would send right now; IDENTITY for tags, nick colours and rank colours; MESSAGE for chat colours, shadow colours, fonts and modifiers; FAVORITES; LOADOUTS; YOUR COLLECTION, which counts what they own; and TAKE IT ALL OFF, drawn only when there is something to take off. There is no close button anywhere — a player closes a window the way they close every other one.

Four top-level shortcuts open a browser directly, on the same permission: /tags, /nickcolors, /rankcolors and /chatcolors.

See what a player already owns

Open /cc as somebody with no permissions at all and most rows read Not yours yet. That is the deliberate default: a catalogue entry is owned through the node exyliachatcosmetics.<type>.<id> or through a grant, and nothing else.

Rank colours are the exception, and it is worth understanding before you write a single node. They ship with permission: false — the type's own default, the other way round from every other file — which means the permission node does not decide who owns one. What decides is the entry's groups list, read from LuckPerms.

TabEntriesWho owns them
solid15Everyone. They name no groups and set no node, so every rank may wear them.
metal, gems, gradient, animated54Whoever holds exyliachatcosmetics.rank_color.<id>. These entries set permission: true back on, one by one.
staff8Whoever is in one of the groups the entry names — owner, admin, mod and so on.

So on a server with LuckPerms and nothing else configured, a brand-new player can already open /rankcolors and repaint their rank prefix in any of fifteen flat colours. Everything else waits for you.

The staff tab names Exylia's groups, not yours

The eight staff entries list groups such as owner, admin, mod and helper. If LuckPerms on your server calls them something else, the tab is empty for everybody until you edit the groups lists in cosmetics/rank-colors.yml.

One catalogue tag, event, also ships permission: false. There is no node that grants it — it exists to be handed out and cannot be bought.

Give somebody a tag

/cca give Notch tag:heart
/cca give Notch tag:heart 14d --source PURCHASE --note "October sale"

A cosmetic is always named type:id, and it is tab-completed. No duration means permanent; 14d is fourteen days, in ExyliaLib's duration format (30m, 2h, 14d, 1w, decimals allowed). Without --source the grant is recorded as ADMIN; --source takes PURCHASE, REWARD, EVENT, ACHIEVEMENT or EXTERNAL, and --ref and --note are yours to fill with an order id or a reason.

The target may be offline as long as they have played before. Check what stuck with /cca list Notch for every grant with its row id, source and time left, or /cca check Notch tag:heart for the one answer.

A player may hold several grants for the same cosmetic at once — a permanent one from a rank, a 14-day admin grant, a 30-day purchase — and removing one never touches the others.

Open a whole tab at once

Granting 180 tags one at a time is not the intention. Four shapes of node, from narrowest to widest:

NodeOwns
exyliachatcosmetics.tag.heartthat one cosmetic
exyliachatcosmetics.tag.category.symbolsevery tag in the symbols tab
exyliachatcosmetics.tag.*every tag
exyliachatcosmetics.*everything in the catalogue

The type ids are tag, nick_color, rank_color, chat_color, shadow_color, font and modifier, and the category is the tab id as it is written in the file — so a VIP rank that should get the premium colours and every font is:

/lp group vip permission set exyliachatcosmetics.chat_color.category.premium
/lp group vip permission set exyliachatcosmetics.nick_color.category.premium
/lp group vip permission set exyliachatcosmetics.font.*

Ownership by node is never stored. It is asked live and memoised for the session, so taking the node away takes the cosmetic off without anything having to be cleaned up — and what the player had equipped stays on their row, ready to be drawn again the day the node comes back.

Put the identity into your chat format

The plugin never cancels a chat event and never owns your format. The tag and the coloured name are yours to place, as placeholders, in whatever chat plugin you already run:

%exyliachatcosmetics_tag%%exyliachatcosmetics_nick%<gray>: <white>%message%

%exyliachatcosmetics_tag% is the worn tag with its trailing space already attached, and a custom tag the player made wins over a catalogue one. %exyliachatcosmetics_nick% is their name in their nick colour. %exyliachatcosmetics_identity% is the two together.

Three notations, because chat plugins do not agree on one — pick the suffix your plugin parses:

PlaceholderOutput
%exyliachatcosmetics_tag%MiniMessage, <#ffd700>[MVP]</#ffd700> — the default
%exyliachatcosmetics_tag_legacy%& codes, with &#rrggbb for hex
%exyliachatcosmetics_tag_section%§ codes, with §x§r§r… for hex

The name carries the same three: %exyliachatcosmetics_nick%, %exyliachatcosmetics_nick_legacy% and %exyliachatcosmetics_nick_section%. So the same format for a legacy-string chat plugin reads:

%exyliachatcosmetics_tag_section%%exyliachatcosmetics_nick_section%§7: §f%message%

Getting the wrong one is the single most common mistake here, and it looks like raw <#ffd700> text in chat. Outside ExyliaLib's own text these need PlaceholderAPI installed to resolve.

A player wearing nothing yields an empty string, so a format with %exyliachatcosmetics_tag% in it is safe for everybody from the first day.

Pick the right hook for your chat plugin

That covers the identity. The message body — the chat colour, the shadow, the font, the modifiers — is styled by the hook, and the right mode depends on how your chat plugin reads a message. chat.hook in config.yml:

You runhookWhy
Paper's own chat, or any plugin that renders through AsyncChatEvent / a ChatRendererdecorateThe styled body replaces the decorated message before any chat plugin sees it, and nothing is cancelled. The default, and the right answer for most servers.
A plugin that reads AsyncChatEvent.message() but ignores decorationchat_event, with chat.priority below its own (LOW)The rewrite lands before it reads.
A plugin still on AsyncPlayerChatEventlegacy_event, at a priority below itThe string it reads already carries § colours.
Spigot, with no Paper events at allanythingdecorate and chat_event fall back to legacy_event with a warning at startup.
Your own code, composing the line yourselfoffNothing is touched; use ChatCosmeticsAPI.styleMessage so nothing is styled twice.
Modified messages and secure chat

Any change to a message body — a colour included — marks it "modified" for a vanilla client. It still shows, but a client with Only Show Secure Chat enabled hides it. Every chat-colour plugin has this property; servers that care set enforce-secure-profile=false.

Look at it before anybody else does

/cc preview
/cc preview whatever you like

Draws the line the player's chat would produce right now, into their own chat and nobody else's. Its shape is preview.format in config.yml, %tag%%prefix% %name%%suffix%{letters_black}: %message% by default, so it shows the rank prefix in the rank colour being looked at as well as the tag and the name.

From the console or as an admin, /cca preview <player> [message] sends the target their own line, and /cca render <player> sends the pieces one at a time — the tag, the coloured name, a styled sample — which is what tells you which of the three is wrong when something looks off.

After the first ten minutes

Everything above is the cosmetics half working through the chat you already run. Two directions from here: put more of the catalogue in players' hands, or hand your chat to the plugin as well.

Something missing on this page? Tell us on Discord