Skip to content

Creating Cases

Create a case file, place the case block, and set up its rotation, limited cosmetics and hologram.

A case is a block in the world that players pay to open for a random cosmetic. Every case is one file in cases/, and the file name is the case id (cases/winter.yml is the case winter). You need optimalcosmetics.admin to place and remove cases.

Copy the shipped cases/secret.yml to a new name and edit it. The parts you will change first:

Settings:
Display-Name: "&bWinter Case"
Currency: "Vault"
Price: 2500
Show-Count: 27
Reshuffle: true
Pool:
- "type:tags"
- "type:name-paints"
- "Lime"
Limited:
Frostbite: 5
  • Currency is the economy for this case (Vault, PlayerPoints or RivalCredits) and can differ from the market’s. Price is charged in it, and {price} is formatted with that provider’s Currency-Formats entry.
  • Pool is what the case can show: all, type:<type> (a type file name such as tags, or a type key such as TAG) or single cosmetic ids. Disabled cosmetics are skipped.
  • Show-Count is how many cosmetics from the pool are in today’s rotation.

Full field list: cases reference.

/cosmeticsadmin reload
/cosmeticsadmin place winter

You get the case’s Place-Item. Place it like a normal block: it registers as the case and its hologram appears. Players cannot break a case block. To remove it, sneak and left-click it as an admin; the block is removed and the case item goes back to your inventory.

A case block that disappears another way (an explosion, a piston, fire, an entity) is unregistered and loses its hologram, but no item is returned.

  1. A player right-clicks (or left-clicks) the block. The case menu opens, showing today’s rotation in Gui.Cosmetic-Slots and the Open-Item button.
  2. Clicking Open-Item opens the confirm menu (guis/case-confirm.yml).
  3. On confirm, the case checks that its currency is available, that the player can afford it and that at least one cosmetic in the rotation can still be won, then charges the price.
  4. A spin animation plays above the block for about 5 seconds (the Animation.Head item turning inside a ring of Primary-Colour / Secondary-Colour dust), then the Reward-Format-Line is shown for 3 seconds. Only the opener sees it, and the hologram is hidden for them meanwhile.
  5. The reward is unlocked (CASE-WON).

The reward is picked evenly at random from the rotation. Rarity does not change the odds; to make a cosmetic rarer, keep it out of most rotations with a bigger pool or a lower Show-Count.

If the player already owns the reward, or has it listed on the market, they get a voucher for it instead (CASE-WON-VOUCHER), so the opening is never wasted. Without a voucher template the price is refunded. A player who leaves during the animation is refunded.

  • Reshuffle: true - the rotation is re-rolled once a day at 00:00 UTC: Show-Count cosmetics are picked at random from the pool. {reshuffle} counts down to the next roll.
  • Reshuffle: false - the rotation is the first Show-Count cosmetics of the pool, in order, and never changes. {reshuffle} shows the Cosmetic-Format.Never label from messages.yml.

The case menu shows as many rotation cosmetics as Gui.Cosmetic-Slots has slots, so keep Show-Count and the slot count in step.

Limited maps a cosmetic id to a maximum number of winners:

Limited:
Frostbite: 5
Lime: 1

Once that many players have won it, it can no longer be rolled. If the last spot is taken by someone else during your animation, you are refunded (CASE-SOLD-OUT). Winners are recorded in the database per cosmetic, and the 1st, 2nd, 3rd… winner names are listed in the cosmetic’s Limited-Lore through {winners}. A limited win sends CASE-WON-LIMITED, which ships with a screen title.

A limited cosmetic still has to be in the pool and in today’s rotation to be won.

The Hologram block puts floating lines above the case, visible to players within 48 blocks. It is a built-in packet hologram, so no hologram plugin is needed. {item} cycles through the rotation’s cosmetic names, one per Update-Interval, and %...% placeholders resolve per viewer.

Hologram:
Enabled: true
Height: 3.4
Update-Interval: 20
Lines:
- "&b&lWinter Case"
- "&aCost: &f{price}"
- "&aReshuffle: &f{reshuffle}"
- ""
- "{item}"

Height is the height of the top line above the block; the other lines stack downwards, 0.3 blocks apart.

  • Reload picks up edited case files and rebuilds every hologram.
  • Deleting a case file leaves its blocks registered in locations.yml. They stop opening (and can no longer be picked up with sneak + left-click) until a file with that id exists again, but they still cannot be broken. Pick the blocks up before deleting a case file.
  • The case menu is defined inside the case file (Gui), not in guis/. Only the confirm menu is shared, in guis/case-confirm.yml.