Skip to content

Creating Categories

A category is one file in milestones/. Add a file, get a new track with its own icon in the menu’s category row. You need optimalmilestones.admin to reload.

Create plugins/OptimalMilestones/milestones/<id>.yml. The file name is the category id - it is what /milestones <category>, the admin command and the placeholders use. Ids are lowercased.

milestones/mobs.yml
Enabled: true
Display-Name: "Mobs"
Order: 3
Menu:
Slot: 4
Material: ZOMBIE_HEAD
Name: "&c&lMobs Milestone"
Lore:
- "&7Kill mobs to progress this track."
- ""
- "&4 - &cComplete: &a{complete}&8/&c{total}"
- ""
- "&e➥ Click to view!"
Progress:
Type: API
API: MOB_KILL
Milestone-Icons:
Locked: { }
Unclaimed: { }
Claimed: { }
Milestones:
"1":
Enabled: true
Required: 100
Lore:
- "{secondary} - &f3x Pearl Key"
Commands:
- "crates key give {player} pearl 3"

Full field list: milestones reference.

One named source, +1 per matching event. No chance, amount, world or block filters.

Progress:
Type: API
API: BLOCK_BREAK

Sources: BLOCK_BREAK, BLOCK_PLACE, MOB_KILL, PINNAPRISON, EDDUNGEONS, RIVALHARVESTERHOE. Names are case-insensitive and - counts as _. An unknown name fails the load.

Several categories may share a source - each one gets its own +1, so a Blocks track and a Blocks-Prestige track can both count block breaks independently.

API counters live in the plugin’s database, so /milestonesadmin progress can adjust them.

Progress:
Type: PLACEHOLDER
Placeholder: "%statistic_hours_played%"

The placeholder is resolved live every time progress is needed. Any numeric placeholder works, from any expansion. Non-digits are stripped and everything after a decimal point is dropped, so 1,234.7 reads as 1234.

PLACEHOLDER categories store no counter, so /milestonesadmin progress refuses them with CATEGORY-NOT-TRACKED. To change the number, change whatever feeds the placeholder.

Milestone-Icons is required and needs all three states: Locked, Unclaimed, Claimed. Each carries its own Primary and Secondary colors, which fill {primary} and {secondary} across the whole icon - including the milestone’s own reward lore. That is how one lore line recolors per state.

Milestone-Icons:
Unclaimed:
Material: YELLOW_STAINED_GLASS_PANE
Primary: "&e"
Secondary: "&6"
Name: "{primary}&lMilestone {secondary}&l{milestone}"
Lore:
- "{primary}Rewards:"
- "{reward-lore}"
- " "
- "{primary}&lUNCLAIMED"

There is no global icon block - every category defines its own, which is the point: a Blocks track can show {progress}/{required} while a Playtime track shows {progress}h / {required}h.

The {reward-lore} line is an expansion marker: a lore line equal to exactly {reward-lore} is replaced with the milestone’s own Lore list.

Milestones holds keyed entries where the key is the milestone number. Keys must be numeric and 1 or higher.

Milestones:
"1":
Enabled: true
Required: 1000
Lore:
- "{secondary} - &f3x Pearl Key"
Commands:
- "crates key give {player} pearl 3"
"2":
Enabled: true
Required: 2500
Lore:
- "{secondary} - &f3x Orbs Booster &7(1.25x, 10m)"
Commands:
- "booster give {player} orbs 1.25 10"

Required is a cumulative total. Milestone 2 at 2500 means 2,500 overall, not 2,500 on top of milestone 1. Keep them ascending or the track will read strangely.

Every milestone needs at least one command - an empty Commands list fails the load.

/milestonesadmin reload

The category appears in the selector row immediately. Test it with /milestonesadmin progress set <you> mobs 1000, then /milestonesadmin reset <you> mobs.

Two different slot settings are involved, and they live in different files:

Setting Where Controls
Menu.Slot the category file Where this category’s selector icon sits.
Milestone-Slots guis/milestones-menu.yml The paged grid every category shares. Its length is the page size.

Give each category a distinct Menu.Slot outside the milestone grid. The currently-viewed category’s icon glows.

Order is the selector sort key, ascending. The lowest-ordered enabled category is the default one /milestones opens.

  • Disable without deleting: Enabled: false on the category hides it from the menu and stops its progress being tracked. Enabled: false on a single milestone drops it from the track entirely - the numbers around it don’t shift, so a gap is fine.
  • Duplicate ids are impossible (the id is the file name), but two categories sharing an Order fall back to alphabetical order by id.
  • Milestone numbers become Roman numerals in {milestone}; use {number} for the arabic form. The icon’s stack size is the milestone number, capped at 64.
  • The menu opens on the first unclaimed milestone’s page, so long tracks land where the player actually is.
  • A missing Menu, Milestones or Milestone-Icons section fails the load with the category id printed to console. So does a non-numeric milestone key or a milestone with no commands.