Player appearance (face, hair, body)
Give players their own face, hair, beard and skin from the game's catalog, and handle gender and per-face beards.
On a fresh server everyone is Henry. player.setAppearance
changes that, and the Appearances
catalog lists what you can choose from.
Events.on("playerSpawned", (player) => { player.setAppearance(Appearances.random());});Call it from playerSpawned, not playerConnect, when their client has a body
to apply it to. Appearances.random() is uniform over the catalog, not over
what looks good together, so the result looks recognisably random.
Dress a player in an outfit
Section titled “Dress a player in an outfit”Player.outfitPresets(gender?) lists the game’s clothing presets.
player.setOutfit(nameOrGuid) equips a preset for the player’s gender:
const presets = Player.outfitPresets(player.appearance.gender);const preset = presets[0];if (preset && !player.setOutfit(preset)) { console.log("The outfit was refused. Check inventory space and gender.");}The old clothes are unequipped and stay in the inventory. New clothes are added and worn; weapons and other items stay as they were. Repeated calls can add more clothing. False means the preset is unknown, the gender does not match, the inventory is unavailable or there is no room. The player’s game dresses them after the server inventory changes.
The sample game mode provides /outfit; its presets do not change the
player’s face or body.
What an appearance is
Section titled “What an appearance is”An Appearance is a
gender plus four of the game’s character-component names:
const look: Appearance = player.appearance;// { gender: "male", head: "", hair: "", beard: "", body: "" }| Part | What it is |
|---|---|
head |
The face. |
hair |
The hairstyle, colour included. |
beard |
The beard. Male only. |
body |
The skin: complexion and build. |
An empty string means “leave it to the game”. A body nobody has chosen for reads as all parts empty.
Change one part
Section titled “Change one part”setAppearance takes a partial. An empty string hands that part back:
player.setAppearance({ hair: "m_hair_barber_07" });player.setAppearance({ beard: "" }); // clean-shaven againIt returns true when the request went out; player.appearance changes with
their next update. It returns false for a name not in the catalog, a name
from the other gender’s catalog, a beard that face cannot wear, or no
connection. See Server vs client authority.
Browse the catalog
Section titled “Browse the catalog”Appearances.options("hair"); // male by defaultAppearances.options("head", "female");Appearances.find("hair", "m_hair_barber_07"); // AppearanceOption or nullAppearances.beards("m_head_012"); // beards that face can growAppearances.random("female"); // a complete AppearanceEvery name is also listed in Faces, hair and skins and Beards.
| Tree | Faces | Hairstyles | Beards | Skins |
|---|---|---|---|---|
| male | 212 | 262 | 51 | 47 |
| female | 61 | 71 | 0 | 41 |
The game ships each hairstyle once per colour. Each
AppearanceOption has
a group naming its style, so grouping turns 262 entries into a readable list:
const styles = new Map<string, string[]>();for (const option of Appearances.options("hair")) { const style = option.group ?? option.name; styles.set(style, [...(styles.get(style) ?? []), option.name]);}Check names from players with Appearances.find first, so you can give a
useful error instead of a refused request.
Match beards to faces
Section titled “Match beards to faces”A beard is modelled against particular heads. Generic faces carry 24 each, Henry’s face the 15 the barber offers, and 14 faces carry none. A face and beard pair that was never modelled is refused whole, face included.
Build beard choices from Appearances.beards(head), not options("beard"),
and when changing the face, check the current beard fits. The default
gamemode’s /appearance set head shaves rather than refuses:
function setHead(player: Player, head: string): boolean { const { gender, beard } = player.appearance; const fits = beard === "" || Appearances.beards(head, gender).some((option) => option.name === beard); return player.setAppearance(fits ? { head } : { head, beard: "" });}Appearances.random() draws the beard after the face, so its result always
fits.
Change gender
Section titled “Change gender”Gender lives on the body’s archetype and decides which half of the catalog applies. The halves never share names, so clear the parts with it:
player.setAppearance({ gender: "female", head: "", hair: "", beard: "", body: "" });Copy another player
Section titled “Copy another player”The default gamemode’s /lookalike reads one player’s published look and asks
another client to wear it:
const PARTS = ["head", "hair", "beard", "body"] as const;
function copyLook(player: Player, model: Player): string { const wanted = model.appearance; if (PARTS.every((part) => wanted[part] === "")) { return `${model.nickname} has not chosen a body yet.`; } if (!player.setAppearance(wanted)) { return "Refused. Your own client decides what it can wear."; } return `Asked to look like ${model.nickname}.`;}Clothing is separate: it is inventory, listed in player.equipment. Changing
hair does not disturb a hat. See Items.
Related
Section titled “Related”- Items: give, take and drop, for clothing
- Read health, stats and skills, for everything else on a player
- The default gamemode’s
src/server/commands/appearance.ts, a full chooser with listing, filtering and@playertargeting