Skip to content

Installation

Install OptimalIndex and OptimalLibrary on your Paper or Folia server.

  • OptimalLibrary - required. It is a separate, free plugin that every Optimal plugin runs on (text, menus, storage and more). OptimalIndex will not enable without it.
  • Paper / Folia (or a Paper fork). Spigot is not supported. Supported versions are 1.21.11, 26.1.1, 26.1.2, 26.2 and 26.3.
  • Java 21 for 1.21.11, Java 25 for the 26.x versions. Check with java -version.

Optional soft dependency:

  • PlaceholderAPI - registers the %optimalindex_...% placeholders (see Placeholders) and resolves %...% placeholders from other plugins inside messages, menu items and menu action arguments.
  1. Confirm java -version matches your server version (21 for 1.21.11, 25 for 26.x).
  2. Stop the server.
  3. Drop OptimalLibrary.jar and OptimalIndex.jar into plugins/.
  4. (Optional) Add PlaceholderAPI.jar.
  5. Start the server. The plugin generates its files and prints a startup banner with the number of categories and unique items it loaded.
  6. Run /plugins - OptimalLibrary and OptimalIndex should both be green.

OptimalLibrary downloads its own libraries (the SQLite and MySQL drivers, HikariCP and XSeries) through Paper’s library loader on first start, so the first launch needs internet access and may take a few extra seconds.

plugins/OptimalIndex/
├─ config.yml # storage, discovery, leaderboard, sounds
├─ messages.yml # every message
├─ categories/ # one file per category
│ ├─ building.yml
│ ├─ colorful.yml
│ ├─ combat.yml
│ ├─ food.yml
│ ├─ functional.yml
│ ├─ ingredients.yml
│ ├─ natural.yml
│ ├─ potions.yml
│ ├─ redstone.yml
│ └─ tools.yml
├─ guis/
│ ├─ main-menu.yml # the /index main menu
│ └─ category-menu.yml # the paged category view
└─ data/
└─ data.db # SQLite player data (do not edit by hand)

Player data is two tables:

Table Holds
index_discoveries One row per discovered entry per player, with the time it was discovered.
index_players One row per player: name, discovered count and last update. Used for /index <player> lookups and the leaderboard.

SQLite (the default) stores both in data/data.db. MySQL is selected with Settings.Storage.Type: MYSQL in config.yml; the tables are created automatically in the configured database.

Every write is queued and runs off the main thread the moment it happens (there is no save interval), and the queue is flushed on shutdown. A player’s data is read when they join, after any of their writes still queued, so a quick rejoin never reads stale data.

Continue to Creating Categories, or read the Information overview first.