Astral Realms Documentation Help

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-requirement action, which calls the matching RankRequirement#take and stores the result in the player's PlayerRankData progress map.

  • Category completionRankService#hasCompletedCategory checks 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#updateRequirement marks it completed (PlayerRankData#setCategoryCompleted) and runs that category's rewards action list for the rank.

  • Rank completion — unlocking is triggered by the unlock-rank action; the shipped rank-details menu fires [unlock-rank] %parameters_rank_id% from a button gated by [compare] %parameters_rank_unlockable% == true (backed by RankService#canUnlock, which checks every requirement in the rank against its amount regardless of category). A successful unlock runs the rank's own actions list — 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 broadcasts unlock-broadcast (skippable per-rank via ignore-broadcast in config.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:

type

Class

Amount unit

Backed by

economy

CurrencyRankRequirement

Currency amount (currency id + amount)

Core EconomyService balance/withdraw

job

JobsLevelRankRequirement

Summed job levels (level)

JobsAPI.getTotalLevels(player) (AstralJobs)

experience

ExperienceRankRequirement

Total XP points (amount)

Core ExperienceUtils total-experience read/write

item

ItemRankRequirement

Inventory item count (material + amount)

Scans/removes matching Material stacks from the player's inventory

Commands

Command

Aliases

Description

/ranks

/rangs, /rang, /rank

Opens the ranks list menu (@Default); admin subcommands broadcast, list, reset, reload.

/mission

/missions

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:

  • progressMap<rankId, Map<requirementId, Integer>>, the accumulated amount per requirement per rank.

  • completedCategoriesMap<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, or null if disabled.

Configuration surface

plugins/AstralRanks/ ├── config.yml ← default-group, ignore-broadcast ├── categories.yml ← mission categories: display item + per-rank rewards ├── messages.yml ← message catalogue ├── ranks/ ← one file per rank, id = the rank's own `id:` field │ └── default.yml ← the only file auto-seeded on first run if ranks/ is missing └── menus/ ├── ranks.yml ← menu id `ranks-list` (opened by /ranks) ├── categories.yml ← menu id `rank-details` (opened from a rank tile) └── requirements.yml ← menu id `ranks-requirements` (opened from a category tile)

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 idsMenuService opens menus by id (ranks-list, rank-details, ranks-requirements), not by filename. See Configuration.

Highlights

Area

Summary

Progression chain

Ordered by next-rank links starting at default-group; current rank is inferred, never stored, from group.* permissions.

Missions & categories

Requirements grouped by category; completing a category fires its rewards once, completing every requirement makes a rank unlockable.

Requirement types

Four: economy, job, experience, item.

Menus

Three: ranks-list (/ranks), rank-details (mission overview for a rank), ranks-requirements (one category's requirements).

Rewards & unlock

Category rewards and rank-unlock actions both run through the AstralCore action framework (PaperActionList) — unlock actions are typically a LuckPerms group swap.

Sync

PlayerRankData (progress, completed categories, displayed quest category) persisted under astralranks:data.

Registered extension points

Kind

Id

Purpose

Action

unlock-rank

Unlocks a rank for the executing player.

Action

update-rank-requirement

Advances progress on one requirement.

Action

set-displayed-ranks-quests

Toggles the player's categoryQuestsDisplay scoreboard category.

Requirement

has-completed-category

Gates on a rank/category being fully completed.

Requirement

has-completed-requirement

Gates on one specific requirement being completed.

Placeholder namespace

%ranks_*%

Root namespace: categories, current rank, quest display.

Placeholder namespace

%rank_*%

A RankConfiguration (id, name, item, requirements, availability).

Placeholder namespace

%category_*%

A RequirementCategory (id, item, rewards, requirements).

Placeholder namespace

%requirement_*%

A WrappedRankRequirement (id, item, current/total progress).

Dependencies

Dependency

Required

Notes

AstralCore

Yes (plugin.yml depend)

AstralPaperPlugin base, menus, actions/requirements framework, configuration loading, placeholders.

AstralSync

Yes (plugin.yml depend)

Persists PlayerRankData across servers.

AstralJobs

Yes (plugin.yml depend)

JobsAPI.getTotalLevels backs the job requirement type.

Core EconomyService

Runtime

Backs the economy requirement type (balance read + withdraw).

Core ChatService

Runtime

Broadcasts unlock-broadcast on rank unlock.

Where to go next

Last modified: 25 July 2026