Installation
Requirements
Section titled βRequirementsβ- Java 21+ - required. The plugin is compiled to Java 21 bytecode; on Java 17 or older it fails
with
UnsupportedClassVersionError. Check withjava -version. - Paper / Folia (or a Paper fork). Spigot is not supported.
api-versionis1.20. - Minecraft 1.20+, built against 1.21.11. The server must run Java 21.
Optional soft dependencies (hooked only if installed):
- PlaceholderAPI - needed for the
%optimalmilestones_...%placeholders, and required for any category usingProgress.Type: PLACEHOLDER. Without it those categories always read0. - PinnaPrison, EdDungeons, RivalHarvesterHoes - extra
APIprogress sources. Each hook is pure reflection and registers only when its plugin is present.
Milestone rewards are console commands, so whatever plugin grants them needs to be installed - the plugin does not hook it directly.
- Confirm
java -versionreports 21 or higher. - Stop the server.
- Drop
OptimalMilestones.jarintoplugins/. - (Recommended) Add
PlaceholderAPI.jar, plus any of the mining plugins above you want as progress sources. - Start the server. The plugin generates its files and prints a startup banner with the category and milestone counts.
- Run
/plugins-OptimalMilestonesshould be green.
XSeries downloads automatically on first startup via Paperβs library loader, so the first launch
needs internet access and may take a few extra seconds. SQLite is not downloaded - the plugin uses
the sqlite-jdbc driver Paper already bundles.
Each third-party hook that registers logs a line like Hooked PinnaPrison for milestone progress. If
a category uses one of those sources and you donβt see its line, that plugin wasnβt loaded.
Generated files
Section titled βGenerated filesβplugins/OptimalMilestones/ββ config.yml # save/notify intervals, progress bar, temporary icons, soundsββ messages.yml # every messageββ guis/β ββ milestones-menu.yml # the /milestones menu layoutββ milestones/ # one file per category, id = file nameβ ββ blocks.yml # API category, BLOCK_BREAK source, 24 milestonesβ ββ playtime.yml # PLACEHOLDER category, %statistic_hours_played%, 12 milestonesββ data/ ββ data.db # SQLite player data (do not edit by hand)Two example categories ship. They hand out crates, booster, cubes, tokens and dragoneggs
commands - retarget those at your own plugins before going live. The playtime category reads
%statistic_hours_played%, which needs PlaceholderAPIβs Statistic expansion installed
(/papi ecloud download Statistic).
Storage
Section titled βStorageβProgress and claims are stored in SQLite at data/data.db, one row per (player, category)
holding the counter and the claimed-milestone list. There is no MySQL option.
Writes are buffered and flushed on Settings.Save-Interval (default 60 seconds), plus on quit and
shutdown. A claim is flushed immediately, so a crash can never let a player claim the same
milestone twice.
PLACEHOLDER categories store nothing but their claims - the progress number is read live from
PlaceholderAPI each time.
Continue to Creating Categories, or read the Information overview first.
