AstralRanks Overview
AstralRanks is the permission-driven rank progression / mission system for AstralRealms. Players climb an ordered chain of ranks — Vilain, Roturier, Paysan, Apprenti, … — by completing grouped requirements ("missions"): earn currency, level up AstralJobs professions, accumulate experience, or hand over items. AstralRanks does not maintain its own "current rank" state; it derives a player's rank purely from which group.* permission they hold, and unlocking a rank means running that rank's actions — typically a LuckPerms group swap.
How progression works
Each rank is a RankConfiguration (one YAML file under ranks/) with an id, a permission node, and a next-rank id pointing at the following rank in the chain (null /absent on the last rank). RankService builds the chain by starting at config.yml's default-group and following next-rank pointers (RankService#sortedRanks), stopping if a next-rank points at an id that doesn't exist or a cycle is detected.
Nothing about a player's current rank is stored by the plugin. Instead, RankService#getNextRank (and the matching isNextRank) walk that chain from the front: for each rank in order, if the player has its permission, that becomes the current candidate and the walk continues; the first rank the player does not have permission for stops the walk. The rank after the last one the player holds permission for is their "next rank" — the one whose missions are currently active. If a player holds none of the chain's permissions at all, getNextRank falls back to the configured default-group rank, while isNextRank simply returns false in that case.
This means the permission plugin (LuckPerms) is the actual source of truth for "what rank is this player" — AstralRanks only reads it, via Player#hasPermission, and expects a player's permissions to form a contiguous prefix of the chain starting at default-group.
Missions & categories
A rank's requirements map (keyed by requirement id, e.g. eco, jobs-level, oak_log) groups individual requirements under a category field. Categories themselves are defined separately in categories.yml (RequirementCategory: a display item and a rewards map of PaperActionLists). Progress and completion flow through RankService:
Per-requirement progress is advanced by the
update-rank-requirementaction, which calls the matchingRankRequirement#takeand stores the result in the player'sPlayerRankDataprogress map.Category completion —
RankService#hasCompletedCategorychecks every requirement in the rank sharing that category id against the player's progress. The first time a requirement completion pushes a category to fully-complete,RankService#updateRequirementmarks it completed (PlayerRankData#setCategoryCompleted) and runs that category'srewardsaction list for the rank.Rank completion — unlocking is triggered by the
unlock-rankaction; the shippedrank-detailsmenu fires[unlock-rank] %parameters_rank_id%from a button gated by[compare] %parameters_rank_unlockable% == true(backed byRankService#canUnlock, which checks every requirement in the rank against itsamountregardless of category). A successful unlock runs the rank's ownactionslist — in the shipped ranks this is a pair of[console] lp user %player_name% parent add/remove <group>lines, i.e. a LuckPerms group swap — and broadcastsunlock-broadcast(skippable per-rank viaignore-broadcastinconfig.yml).
See Ranks & Progression and Requirements & Missions for the full YAML shape and category/reward mechanics.
Requirement types
Every requirement resolves to a RankRequirement, selected by its type key:
| Class | Amount unit | Backed by |
|---|---|---|---|
|
| Currency amount ( | Core |
|
| Summed job levels ( |
|
|
| Total XP points ( | Core |
|
| Inventory item count ( | Scans/removes matching |
Commands
Command | Aliases | Description |
|---|---|---|
|
| Opens the ranks list menu ( |
|
| Opens the current (next) rank's mission menus — no-arg opens the rank menu, with a category argument opens that category's requirements menu. |
See Commands for the full subcommand/permission table.
Player data & sync
Progress is persisted through AstralSync as PlayerRankData, registered by RankSnapshotAdapter under snapshot key astralranks:data. It carries:
progress—Map<rankId, Map<requirementId, Integer>>, the accumulated amount per requirement per rank.completedCategories—Map<rankId, Set<categoryId>>, which category/rank pairs have already paid out rewards (guards against re-granting rewards).categoryQuestsDisplay— the category id (or"all") the player has toggled on for the compact quest display placeholder, ornullif disabled.
Configuration surface
Only ranks/default.yml is copied out of the jar automatically when the ranks/ folder doesn't exist yet (RankService#load); every other rank file is loaded if present but nothing else is auto-extracted. The menu filenames don't match their ids — MenuService opens menus by id (ranks-list, rank-details, ranks-requirements), not by filename. See Configuration.
Highlights
Area | Summary |
|---|---|
Progression chain | Ordered by |
Missions & categories | Requirements grouped by |
Requirement types | Four: |
Menus | Three: |
Rewards & unlock | Category rewards and rank-unlock actions both run through the AstralCore action framework ( |
Sync |
|
Registered extension points
Kind | Id | Purpose |
|---|---|---|
Action | Unlocks a rank for the executing player. | |
Action | Advances progress on one requirement. | |
Action | Toggles the player's | |
Requirement | Gates on a rank/category being fully completed. | |
Requirement | Gates on one specific requirement being completed. | |
Placeholder namespace | Root namespace: categories, current rank, quest display. | |
Placeholder namespace | A | |
Placeholder namespace | A | |
Placeholder namespace | A |
Dependencies
Dependency | Required | Notes |
|---|---|---|
AstralCore | Yes ( |
|
AstralSync | Yes ( | Persists |
AstralJobs | Yes ( |
|
Core | Runtime | Backs the |
Core | Runtime | Broadcasts |
Where to go next
Configuration —
config.yml,categories.yml,messages.ymlin full.Commands —
/ranksand/missionsubcommands and permissions.Ranks & Progression — the per-rank YAML shape and the permission chain in detail.
Requirements & Missions — requirement types, categories, and reward flow.
Placeholders — the
ranks/rank/category/requirementnamespaces.Messages — the message-key catalogue.
Developer API —
RanksAPI, registered actions, and requirements.