Skip to content

milestones

Every category is one file in milestones/. The file name (lowercased, without .yml) is the category id used by /milestones <category>, the admin command and the placeholders. After adding or editing one, run /milestonesadmin reload.

Two ship by default: blocks.yml (an API category) and playtime.yml (a PLACEHOLDER one). A walkthrough is in Creating Categories; this page is the full reference.

Enabled: true
Display-Name: "Blocks"
Order: 1
Menu: { }
Progress: { }
Milestone-Icons: { }
Milestones: { }
Key Default Description
Enabled true false hides the category from the menu and stops tracking its progress.
Display-Name the id Shown in the menu and messages as {category}.
Order file position Selector sort key, ascending. The lowest-ordered enabled category is what /milestones opens by default. Ties broken by id.
Menu required The selector icon and its slot.
Progress required How progress is measured.
Milestone-Icons required The three state templates.
Milestones required The numbered track.

The category’s icon in the selector row, plus where it sits. The section is both the slot and the item definition.

Menu:
Slot: 2
Material: COBBLESTONE
Name: "&b&lBlocks Milestone"
Lore:
- "&7Complete milestones and receive rewards"
- "&7to help you progress through the game."
- ""
- "&3 - &bComplete: &a{complete}&8/&c{total}"
- ""
- "&e➥ Click to view!"

Slot is a raw menu slot from 0. Give each category a distinct one, outside the milestone grid. The currently-viewed category’s icon gets a glint automatically. Everything else in the section is a standard item definition.

Tokens: {category}, {complete} (milestones claimed), {total}, {reached} (thresholds met, claimed or not), {progress} (comma-grouped), {percent} and {progress-bar}.

Progress:
Type: API
API: BLOCK_BREAK
Progress:
Type: PLACEHOLDER
Placeholder: "%statistic_hours_played%"
Key Description
Type API or PLACEHOLDER, case-insensitive. Defaults to API.
API Required for API. One source name; see below.
Placeholder Required for PLACEHOLDER. Any numeric placeholder. A blank value fails the load.
Name Fires on
BLOCK_BREAK Bukkit BlockBreakEvent, MONITOR priority, cancelled events ignored
BLOCK_PLACE Bukkit BlockPlaceEvent
MOB_KILL A non-player entity dies with a player killer
PINNAPRISON PinnaPrison’s BlockMineEvent
EDDUNGEONS EdDungeons’ EdDungeonsSwingSwordEvent
RIVALHARVESTERHOE RivalHarvesterHoes’ RivalBlockBreakEvent

Parsed case-insensitively with - treated as _. An unknown name fails the load loudly. Each matching event adds exactly +1 - there are no chance, amount, world or block filters. Several categories may share a source; each gets its own +1.

The last three register only when their plugin is installed, and log a severe line if that plugin’s API changed.

The placeholder is resolved live through PlaceholderAPI every time progress is read. Everything from the first . onward is discarded, then every non-digit is stripped:

"1,234" → 1234
"1234.9" → 1234
"58 hours" → 58
"" → 0

Without PlaceholderAPI installed, the value is always 0.

Required, and all three states must be present: Locked, Unclaimed, Claimed.

Milestone-Icons:
Locked:
Material: RED_STAINED_GLASS_PANE
Primary: "&c"
Secondary: "&4"
Name: "{primary}&lMilestone {secondary}&l{milestone}"
Lore:
- "&7You are still working towards"
- "&7this milestone."
- ""
- "{primary}Progress:"
- "{secondary} - &7Required: &a{progress}&8/&c{required}"
- "{secondary} - &7{progress-bar} &7({percent}%)"
- ""
- "{primary}Rewards:"
- "{reward-lore}"
- ""
- "{primary}&lLOCKED"
State Shown when
Locked Progress is below Required.
Unclaimed Threshold met, not yet claimed.
Claimed Already claimed.
Field Default Description
Material required Any material name; resolved through XSeries. An unknown name fails the load.
Primary &f Fills {primary} across the whole icon, including the reward lore.
Secondary &7 Fills {secondary} the same way.
Name none Item display name.
Lore [] The template lore. A line equal to exactly {reward-lore} expands into the milestone’s own Lore.
Custom-Model-Data 0 0 leaves it unset.
Glow false Adds an enchant glint.

The stack size is the milestone number, capped at 64. Italics are stripped automatically.

Token Value
{category} The category’s Display-Name.
{milestone} The milestone number as a Roman numeral (XII).
{number} The milestone number in arabic (12).
{progress} Current progress, comma-grouped.
{required} That milestone’s threshold, comma-grouped.
{progress-bar} The bar from Progress-Bar.
{percent} progress ÷ required as a two-decimal number, no % sign.
{primary} / {secondary} That state’s colors.
{reward-lore} Expansion marker for the milestone’s Lore list.

Because {primary} and {secondary} also resolve inside the expanded reward lore, one lore line written as "{secondary} - &f3x Pearl Key" recolors itself per state.

Keyed entries where the key is the milestone number. Keys must be numeric and 1 or higher; a non-numeric key fails the load.

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"
Key Default Description
Enabled true false drops the milestone from the track entirely. Numbers around it don’t shift, so gaps are fine.
Required 0 Cumulative total progress needed. Negative values are clamped to 0.
Lore [] The reward description. Expanded wherever the state icon has a {reward-lore} line.
Commands required Console commands run on claim, with {player} replaced. An empty list fails the load.

Milestones are sorted by number, not by file order. Required should ascend with the number - the plugin does not enforce it, but a track that goes backwards reads as already-complete.

  1. Progress is checked against Required. Below it: MILESTONE-LOCKED and the Locked flash.
  2. The claim is recorded. Already claimed: ALREADY-CLAIMED and the Already-Claimed flash.
  3. The claim is flushed to the database immediately.
  4. Commands run from console. On Folia they are dispatched on the global thread.
  5. MILESTONE-CLAIMED is sent and the menu repaints.

Nothing is claimed automatically. MILESTONE-UNLOCKED only tells the player something is waiting.

Checked on load and on every reload; these fail loudly rather than being skipped:

  • A category with no Menu, Milestones or Milestone-Icons section
  • A missing Locked / Unclaimed / Claimed icon
  • A non-numeric or below-1 milestone key
  • A milestone with an empty Commands list
  • Type: API with no API source, or an unknown source name
  • Type: PLACEHOLDER with no Placeholder
  • An invalid Material anywhere
  • Two categories resolving to the same id