Astral Realms Documentation Help

Rewards

A reward tier is a point-gated entry in rewards.yml that a player can claim once their season points reach its required-points threshold. Every tier carries two independent claims — a free one and a premium one — each with its own action list and its own claimed/unclaimed state, so a premium player and a free player progress through the same tier list but receive different rewards (or none, if a side is left empty).

rewards.yml format

rewards.yml is loaded into a RewardsConfiguration — a map of reward id → RewardBlueprint (RewardBlueprintTypeSerializer). The map key itself becomes the blueprint's id; there is no separate id: field inside the entry.

Field

Type

Description

required-points

int

Point threshold (FarmPassData.points()) a player must reach to unlock this tier. Defaults to 0 if omitted.

default

PaperActionList

Optional. Actions run when a player claims the free side of this tier.

premium

PaperActionList

Optional. Actions run when a player claims the premium side of this tier.

display

ItemStackWrapper

Optional. Icon shown for the free side (%reward_display%). Standard AstralCore item template — see Menu Items.

premium-display

ItemStackWrapper

Optional. Icon shown for the premium side (%reward_premiumDisplay%).

If default/premium is omitted (or empty), that side has nothing to run on claim, but claiming it is still tracked — see Claim tracking below.

Example

# rewards.yml rewards: welcome_bonus: required-points: 10 default: - "[message] Welcome to the server! You have received 10 bonus points." premium: - "[message] Thank you for purchasing the Battle Pass Premium! You have received 20 bonus points." display: material: gold_ingot name: "Welcome Bonus" lore: - "Receive bonus points upon joining the server." - "Available for all players." premium-display: material: diamond name: "Premium Welcome Bonus" lore: - "Receive extra bonus points for purchasing the Battle Pass Premium." - "Exclusive to premium players."

RewardType and claim tracking

RewardType is a two-value enum, FREE and PREMIUM (RewardType.parse accepts either case, throwing on anything else). A reward tier's free and premium sides are claimed independently and tracked in FarmPassData.claimedRewards() — a Set<String> of keys built as "<reward-id>_<free|premium>" (e.g. welcome_bonus_free, welcome_bonus_premium). Claiming one side never marks the other as claimed.

claim-farmpass-reward

Registered via registerAction("claim-farmpass-reward", ClaimRewardAction.class). Claims one side of a reward tier for the executing player.

Arg

Type

Description

id

String placeholder (single token)

Required. The reward tier's id — the map key under rewards: in rewards.yml.

type

String placeholder

Required. free or premium (case-insensitive, parsed by RewardType.parse).

- "[claim-farmpass-reward] welcome_bonus free" - "[claim-farmpass-reward] welcome_bonus premium"

Execution:

  1. Resolves the reward blueprint via plugin.rewards().findById(id). Throws if no such tier exists.

  2. Looks up the executing player's FarmPassData via SyncAPI.findData. Throws if no synced data exists.

  3. Builds the claim key "<id>_<type>" and checks it against FarmPassData.claimedRewards(). If already present, sends the reward-already-claimed message (FarmPassMessages.REWARD_ALREADY_CLAIMED, default text: "You have already claimed your reward for this quest.") and stops — nothing further runs.

  4. Otherwise, adds the claim key to claimedRewards() before running any actions.

  5. Runs the tier's default action list for free, or its premium action list for premium. If that side has no action list configured (null), the claim is still recorded but nothing executes.

Availability logic

RewardBlueprint is itself a ComplexPlaceholder (namespace reward) exposing claimed/available sub-keys that require a next token (free/premium) and a Player context:

  • claimedtrue if FarmPassData.claimedRewards() contains "<id>_<type>" for the requested type; false if the player has no synced FarmPassData yet.

  • availabletrue only when the requested type is not yet claimed and the player's points() are >= requiredPoints. Unlike claimed, this throws IllegalStateException if the player has no synced FarmPassData, rather than defaulting to false.

These surface as %reward_claimed_free%, %reward_claimed_premium%, %reward_available_free%, and %reward_available_premium% — see Placeholders for the full reward_* reference, including %reward_display%/%reward_premiumDisplay%/%reward_hasDefault%/%reward_hasPremium%.

%farmpass_rewards% exposes every loaded RewardBlueprint as an ItemProvider, meant to back a menu layout's provider: the same way %farmpass_quests% backs the quest grid in farmpass-main (see Configuration for that layout). Iterating it renders one item per tier; inside that item's template, %reward_claimed_free%/%reward_available_free% (or the _premium variants) pick which icon, lore, or action to show, and a claim button fires claim-farmpass-reward with that tier's id and the relevant type. See Placeholders ("Usage: the main menu") for the exact %parameter_reward_...% chaining mechanics.

Earning and adjusting points

Points are earned automatically by completing quests: QuestService.tryProgress credits the completed quest's category rewarded-points (daily: 10, weekly: 50 by default) to FarmPassData.points() — see Seasons & Categories → Categories. Staff can also adjust a player's balance directly with /farmpass points add|take|set, independent of quest completion.

Further reading

  • Overview — how rewards fit alongside seasons, quests, and points.

  • Seasons & Categoriesrewarded-points per category.

  • Commands/farmpass points add|take|set.

  • Placeholders — full reward_* placeholder reference.

  • Developer APIFarmPassData.claimedRewards() and using the action from other plugins.

Last modified: 25 July 2026