Content generated with AI — it may contain mistakes.

Reference

Placeholders

The identifier, the three notations, every name it answers to, and what happens to a head on the way out.

Placeholders are registered through ExyliaLib's placeholder module, so they work in every ExyliaLib text on their own, and in every other plugin as soon as PlaceholderAPI is installed. There is one identifier, and every name below hangs off it:

%exyliachatcosmetics_<name>%

The three notations

Some placeholders return a drawn thing rather than a word, and a drawn thing has to become text before a chat format can carry it. Which text depends on who is asking, so each of them comes in three spellings from the same component — a colour is never rendered twice.

SuffixOutputUse it when
(none)MiniMessage — <#ffd700>[MVP]</#ffd700>your chat plugin parses MiniMessage. The default.
_legacy& codes, with &#rrggbb for hexyour chat plugin still reads & codes
_section§ codes, with the §x§r§r… hex formyour chat plugin sends the string straight to the client

The legacy serialisers here are built with hex support on purpose. The stock ones downsample a hex colour to the nearest of the sixteen named colours, which turns a gradient into a flat &6.

A head only survives the MiniMessage notation

A tag drawn from a head skin — a flag, a face somebody made — is an object component carrying a profile property, and neither legacy notation has anywhere to put one. In _legacy and _section the head is simply not there; whatever else the tag draws still is.

In the MiniMessage notation it survives, written as <ecc_head:'…'> — a tag this plugin adds to MiniMessage for exactly this reason and reads back on the way in. The one case it cannot survive is a head that reaches the serialiser with its skin already lost: MiniMessage would write it as a bare <head>, which draws a default face for whoever reads it, so it is stripped out instead. A stranger's face beside somebody's name is worse than no face at all.

Rendered text

Each of these draws a component, so each exists in all three notations, and each of the three is a placeholder in its own right:

PlaceholderValue
%exyliachatcosmetics_tag%the worn tag, with the format around it — usually a trailing space. A custom tag wins over a catalogue one.
%exyliachatcosmetics_tag_legacy%the same tag, written in & codes
%exyliachatcosmetics_tag_section%the same tag, written in § codes
%exyliachatcosmetics_customtag%only a tag the player wrote for themselves; empty if what they wear came from the catalogue
%exyliachatcosmetics_customtag_legacy%the same tag, written in & codes
%exyliachatcosmetics_customtag_section%the same tag, written in § codes
%exyliachatcosmetics_nick%the player's name in its nick colour
%exyliachatcosmetics_nick_legacy%the same name, written in & codes
%exyliachatcosmetics_nick_section%the same name, written in § codes
%exyliachatcosmetics_identity%the tag followed by the name
%exyliachatcosmetics_identity_legacy%the same pair, written in & codes
%exyliachatcosmetics_identity_section%the same pair, written in § codes
%exyliachatcosmetics_rank_prefix%the rank's prefix, repainted in the worn rank colour
%exyliachatcosmetics_rank_prefix_legacy%the same prefix, written in & codes
%exyliachatcosmetics_rank_prefix_section%the same prefix, written in § codes
%exyliachatcosmetics_rank_suffix%the rank's suffix, repainted in the worn rank colour
%exyliachatcosmetics_rank_suffix_legacy%the same suffix, written in & codes
%exyliachatcosmetics_rank_suffix_section%the same suffix, written in § codes

Each is empty when nothing is worn, which means the value of placeholders.none — empty by default — or whatever fallback you write.

Values

These are plain words and numbers, with no notations.

PlaceholderValue
%exyliachatcosmetics_tag_id%the id of the worn tag
%exyliachatcosmetics_tag_name%the display name of the worn tag
%exyliachatcosmetics_nick_color%the effective name colour, as #rrggbb or #a:#b:#c
%exyliachatcosmetics_rank_color%the colour the prefix and suffix are painted in
%exyliachatcosmetics_rank_id%the id of the worn catalogue rank colour
%exyliachatcosmetics_chat_color%the effective message colour: a custom colour, else a chat colour, else chat.default-color
%exyliachatcosmetics_chat_color_id%the id of whichever of those it came from
%exyliachatcosmetics_font%the worn font's id
%exyliachatcosmetics_font_name%the worn font's display name
%exyliachatcosmetics_modifiers%the worn modifier ids, comma-separated
%exyliachatcosmetics_favorites_count%how many cosmetics they have starred
%exyliachatcosmetics_loadout%the name of the last loadout they applied

Values that take an argument

Four of them are written with something of yours in the middle — a type, or a type:id key.

PlaceholderValueWritten out
%exyliachatcosmetics_equipped_<type>%the id worn of that type%exyliachatcosmetics_equipped_chat_color%
%exyliachatcosmetics_tokens_<type>_<kind>%a token balance%exyliachatcosmetics_tokens_customtag_create%, %exyliachatcosmetics_tokens_customcolor_edit%
%exyliachatcosmetics_owns_<type:id>%true or false%exyliachatcosmetics_owns_tag:mvp%
%exyliachatcosmetics_expires_<type:id>%permanent, the time left in compact form (13d 4h), or placeholders.none if they do not own it%exyliachatcosmetics_expires_tag:mvp%

A name that nothing answers to yields placeholders.unknown, ? by default. Both that and placeholders.none are yours to change in config.yml.

Underscores in an argument

Both a type (chat_color) and an id (my_tag) may contain an underscore, and the library splits arguments on underscores. They are joined back together before they are read, so %exyliachatcosmetics_equipped_chat_color% and %exyliachatcosmetics_owns_tag:my_tag% mean what they look like.

Fallbacks

ExyliaLib's fallback syntax works throughout: everything after the | is what the placeholder renders when it has no value.

%exyliachatcosmetics_tag|%          nothing at all when no tag is worn
%exyliachatcosmetics_loadout|none%  the word "none" when no loadout was applied

ExyliaLib's format suffixes — :upper and the rest — work on the value placeholders.

In a chat format

A renderer-based chat plugin, reading MiniMessage:

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

A chat plugin that still composes a legacy string:

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

In both, %message% stays whatever your chat plugin puts there. The message body is coloured by the chat hook, not by a placeholder — a placeholder cannot reach inside a string somebody else already built. If you would rather the plugin composed the whole line itself, that is what the chat module is.

Threads

Every resolver is registered async-safe and reads only cached state: nothing here touches the Bukkit API beyond the player handed in, so they can be asked from the chat thread without a hop to the main one. A player whose profile has not finished loading answers as if wearing nothing, rather than blocking to wait for it.

Something missing on this page? Tell us on Discord