Astral Realms Documentation Help

Configuration

AstralRanks' configuration is split across <plugin-data-folder>/config.yml, categories.yml, messages.yml, a ranks/ folder holding one file per rank, and a menus/ folder holding the three menu blueprints the plugin renders through AstralCore's MenuContainer. All of it — the top-level files, every rank file, and every menu blueprint — is reloaded in one pass by /ranks reload.

File layout

plugins/AstralRanks/ ├── config.yml ├── categories.yml ├── messages.yml ├── ranks/ │ ├── default.yml │ └── ... └── menus/ ├── ranks.yml ├── categories.yml └── requirements.yml
  • ranks/ is created on first start if it doesn't exist yet, and seeded with a single default.yml copied from the plugin jar (configurationManager().copyResource(...), resource ranks/default.yml). Every other .yml/.yaml file placed in the folder afterwards is picked up automatically on load — the file name is irrelevant, each file's own id field determines the rank's identity. See Ranks & Progression for the full RankConfiguration shape.

  • menus/ holds the three fixed menu blueprints AstralRanks opens by id — ranks.yml, categories.yml, requirements.yml. See Menus below.

config.yml

Field

Type

Description

default-group

String

The id of the starting rank every player begins on. RankService#load() looks this up right after loading all rank files and throws IllegalStateException("Default rank not found: <id>") if no rank with that id exists — this also aborts building the sorted rank chain used to compute a player's "next rank" and to populate the ranks menu.

ignore-broadcast

Set<String>

Rank ids whose unlock does not trigger the network-wide UNLOCK_BROADCAST message. Checked in RankService#unlock() immediately before broadcasting: if (ignoreBroadcast().contains(rank.id())) return;.

default-group: "default" ignore-broadcast: - "default"

This is the shipped default: the starting rank (ranks/default.yml, id: "default") is both the default-group and listed in ignore-broadcast, so reaching it — which every player already has — never spams a network broadcast.

categories.yml

A single categories map, keyed by category id, deserialised through CategoryConfiguration (Map<String, RequirementCategory>). Each entry is resolved by CategoryTypeSerializer:

  • the map key becomes the category's id (read from node.key()), not a separate id: field;

  • the rest of the entry is read directly as an ItemStackWrapper (material, name, lore, item-flags, …) — this is the icon shown for the category in the rank-details menu;

  • a rewards node holds the rewards to grant on completion, see rewards below.

categories: eco: material: GOLD_INGOT name: "<gold>Economy" lore: - "<requirements>" - "<yellow>Click to open!" rewards: default: - "[console] give %player_name% diamond 5"

Categories are referenced from rank files by id — each requirements.<key>.category entry in a ranks/*.yml file must name one of these ids. See Requirements & Missions.

rewards

rewards is a Map<String, PaperActionList> keyed by rank id, not a plain action list. When a player finishes every requirement in a category for a given rank, RankService#updateRequirement() looks the reward list up by that rank's id — category.rewards().get(rank.id()) — and runs it:

rewards: default: - "[console] give %player_name% diamond 5"

Here default is the id of the rank (ranks/default.yml) the reward applies to; completing this category while on a different rank looks up that rank's own key instead, and runs nothing if the key is absent.

MenuService wraps an AstralCore MenuContainer rooted at <plugin-data-folder>/menus/. On load, the container walks that folder (configurationManager().loadFolder(...)) and registers every blueprint it finds under the id declared inside the file — not the filename. AstralRanks opens three fixed ids:

Menu id

File

Opened via

ranks-list

menus/ranks.yml

/ranks with no subcommand (MainCommand's @Default, MenuService#openMainMenu).

rank-details

menus/categories.yml

Clicking an unlocked rank in ranks-list; /mission with no args (MenuService#openRankMenu).

ranks-requirements

menus/requirements.yml

Clicking a category in rank-details; /mission <category> (MenuService#openRequirementsMenu).

Rename or restructure these files freely as long as each still declares its matching id — the lookups above are by id, not path.

Reloading

/ranks reload (permission astralranks.reload) calls AstralRanks#loadConfiguration(), which reloads, in order:

  1. config.ymlMainConfiguration

  2. categories.ymlCategoryConfiguration

  3. messages.ymlRanksMessages (loadEnum)

  4. every file under ranks/ (RankService#load())

  5. every blueprint under menus/ (MenuService#loadConfiguration()MenuContainer#load())

See Commands for the full /ranks command reference.

Type serializers

Registered once in AstralRanks#onEnable(), before loadConfiguration() runs, so every YAML node described above (and the rank-file requirement blocks) maps straight onto these models:

Model

Serializer

RequirementCategory

CategoryTypeSerializer — one categories.yml entry, see categories.yml.

WrappedRankRequirement

WrappedRankRequirementTypeSerializer — one requirements.<key> entry inside a ranks/*.yml file.

RankRequirement

RankRequirementTypeSerializer, registered registerExact — the requirement: block inside a WrappedRankRequirement, dispatched by its type field.

Both requirement serializers back the ranks/*.yml requirement blocks; see Requirements & Missions for their full shape.

See also

  • Ranks & Progression — the ranks/*.yml file shape (RankConfiguration), rank ordering, and unlock rules.

  • Requirements & Missions — the requirements block inside a rank file and the RankRequirement types.

  • Commands — the full /ranks and /mission command reference.

  • Messagesmessages.yml.

Last modified: 25 July 2026