Skip to content

Disguises

A DisguiseProfile is the code form of the disguise section of config.yml: the name, skin, hearts and item details a hidden player is shown with.

A zone that sets no disguise uses the one from config.yml, which is usually what you want: server owners tune the look, your plugin decides where and when.

The simplest integration reads the disguise from your own config file, using the same keys server owners already know:

.disguise(getConfig().getConfigurationSection("events.koth.hider"))

Keys the section leaves out fall back to the global disguise, so a server owner can override just the prefix and inherit the rest.

To read a profile without opening a zone:

DisguiseProfile profile = DisguiseProfile.fromSection(section, DisguiseProfile.defaults());
DisguiseProfile profile = DisguiseProfile.builder()
.name(new NameSpec(true, "medieval", "§7Hidden ", ""))
.skin("random")
.health(new HealthSpec(true, List.of("&4")))
.showArmor(false)
.showNbts(false)
.build();
PartTypeControls
nameNameSpecWhether a name shows, and its value, prefix and suffix.
skinStringA source value, described below.
healthHealthSpecWhether hearts show, and in which colour.
showArmorbooleanWhether worn armour is visible.
showFirebooleanWhether flames are visible while burning.
showStuckArrowsbooleanWhether stuck arrows are visible.
showNbtsbooleanWhether item details are visible.

DisguiseProfile.defaults() gives the neutral baseline: a random name and skin, hearts, armour and effects all shown.

NameSpec.value and skin share one grammar, resolved when a player is disguised:

ValueResolves to
"random"A random entry from the default pool.
A pool nameA random entry from that pool.
"%placeholder%"The placeholder resolved on the hidden player.
Anything elseItself: a fixed name, a skins.yml entry key, or a player username.

DisguiseProfile.RANDOM and DisguiseProfile.DEFAULT_POOL hold the two keywords, and isRandom(String) and isPlaceholder(String) classify a value if you need to.

The pools themselves come from usernames.yml and skins.yml. Your plugin cannot add pools at runtime, so a profile built in code refers to pools the server owner has configured.

public record NameSpec(boolean show, String value, String prefix, String suffix) {}
public record HealthSpec(boolean show, List<String> colors) {}

prefix and suffix accept colour codes and placeholders, including relational ones resolved per viewer. Note that they are stored already translated: a profile built from a config section has its & codes converted, while one you build in code keeps whatever string you pass. Pass legacy codes with the section sign if you build it yourself.

HealthSpec.colors takes one entry for a fixed colour, or several to pick one at random per disguise. An empty list falls back to dark red.

A reveal rule can show a matched target under a second disguise instead of their real self. In zones.yml that is the disguise block of a rule. Through the API it is not exposed on ZoneBuilder: a rule that matches reveals the real player.

To get the same effect from code, drive the look from the zone disguise and use placeholders that already differ per player, or define the zone in zones.yml and start it with /sh start from your plugin.