πŸ”₯Join our Discord for support, updates, and custom commissions.
Polaroid Studio Logo
PolaroidSTUDIO
DiscordLog In

🎨 Appearance

Two files, split by what they answer:

  • menus.yml β€” where things sit. Titles, rows, slots, dialog labels.
  • items.yml β€” how things look. Material, name, lore.

Every button and every item takes the same fields, so learn them once.

Item fields

send-mail:
  slot: 48
  item: FEATHER
  name: "<#f2c42f>Send mail"
  lore:
    - "<#E9FDFB>Write a letter and attach items."
  amount: 1
  glow: false
FieldNotes
itemA material, or a custom-item id β€” see Custom Items. material: is an alias
name / loreMiniMessage or legacy codes
amountStack size
glowEnchant shimmer without the enchantment
item-modelVanilla item model override
flagsItem flags to hide
hide-tooltipHide the tooltip entirely

menus.yml

Inbox

inbox:
  title: "<dark_gray><b>Mail"
  inspect-title: "<dark_gray><b>%player%"   # /mail admin
  rows: 6
  filler-item: BLACK_STAINED_GLASS_PANE
  buttons:
    send-mail:   { slot: 48, ... }
    claim-all:   { slot: 49, ... }   # %count%
    clear-mail:  { slot: 50, ... }
    prev-page:   { slot: 45, ... }   # %page% %pages%
    next-page:   { slot: 53, ... }

rows is the whole screen. mail.inbox-rows-per-page from config.yml decides how many of them hold mail; the last one is always the control bar.

Compose

compose:
  title: "<dark_gray><b>New mail"
  admin-title: "<dark_gray><b>Server mail"
  rows: 5
  item-slots: [12, 13, 14, 21, 22, 23, 30, 31, 32]
  filler-item: BLACK_STAINED_GLASS_PANE
  write-letter-button: { slot: 40, ... }

item-slots must hold exactly mail.max-items-per-letter entries. Only these slots accept items; everything else is locked, including drags and shift-clicks that would land outside them.

Dialogs

dialogs:
  compose:
    title: "<#f2c42f><b>Write a letter"
    fields:
      recipient: { label: "Player" }
      subject:   { label: "Subject" }
      message:   { label: "Message", multiline: true }
      money:     { label: "Money" }
      anonymous: { label: "Send anonymously" }
    buttons:
      confirm: "<#95d027>Send"
      cancel:  "<#eb4b30>Cancel"

Three dialogs: compose, compose-admin (no recipient, no anonymous β€” the audience came from the command) and read-letter.

read-letter is what opens when a player right-clicks a letter item, with %subject%, %sender% and %message%.

items.yml

Inbox entries

The record shown inside the inbox. It never leaves the menu.

EntryUsed for
pending / claimedPlayer mail
pending-server / claimed-serverServer mail
pending-<name> / claimed-<name>A server-mail entry that names <name> with mail-item

A missing variant falls back to the plain pair, so you never have to define all of them.

Placeholders

Available in every name and lore:

%subject%  %sender%  %sent%  %claimed%  %expires%  %money%

%sender% reads Anonymous for an anonymous mail β€” except in /mail admin, where it reads Anonymous (Steve). Both wordings are yours:

text:
  sender-anonymous: "Anonymous"
  sender-anonymous-admin: "Anonymous (%player%)"

%contents% is special. On its own lore line it expands to one row per attachment:

lore:
  - "<#E9FDFB>Contents"
  - "%contents%"

Item names are rendered by the client, not the server. A vanilla item's name is a translation key rather than a word, and it is passed through untouched β€” so a player running the game in Spanish reads Diamante and one running it in Russian reads Алмаз, from the same config line.

The rows themselves are configurable:

contents:
  item:   "<#f3842c> ⚐ β€’ <#b6c1ec>%item%"
  letter: "<#289bd0> βœ‰ β€’ <#b6c1ec>A letter"
  money:  "<#95d027> ⛃ β€’ <#b6c1ec>%amount%"

Other entries

SectionWhat
text"Anonymous", "Never", and the %expires% units (d, h, m, s)
inspect-entryLore used in /mail admin, with %state% and %recipient%
letter-itemThe item handed over when letter-type: ITEM
letter-bookThe book written when letter-type: BOOK