Astral Realms Documentation Help

Placeholders

AstralJobs registers one root namespace, jobs, with AstralCore (JobsPlaceholders, registered on enable via RootPlaceholderContainer#registerPlaceholder). Everything else — job_*, action_*, reward_*, booster_* — is a chain point reached by walking through jobs_*, or a namespace that other AstralJobs code registers directly into a PlaceholderContainer when it sends a message or resolves an item (for example, booster-activation messages in Messages register a BoosterEntity and its %booster_*% keys become available there). For the placeholder syntax itself (%a_b_c%, %a_{b_c}%, $e(...)) see Placeholders.

Several placeholders below require the placeholder context to be a Player (a menu/dialog opened for a player, or a message sent to one) — these are marked player-only and resolve to null (or, in one case, false) outside that context.

jobs_* (root)

Placeholder

Type

Description

%jobs_job_<id>%

Job?

Looks up a loaded job by its id (JobService#findById). null if no job has that id. Chain further tokens into job_* — e.g. %jobs_job_farmer_name%.

%jobs_jobs%

ItemProvider\<Job\>

Every loaded job. Use as a layout provider to list all jobs.

%jobs_modifier_<jobId>_<scope>[_<sub>]%

double?

Player-only. The player's combined modifier for <jobId>/<scope>. See Modifiers below.

%jobs_boosters_global%

ItemProvider\<BoosterEntity\>

Every currently active global booster. No player context required.

%jobs_boosters_global_<TYPE>%

BoosterEntity

The first active global booster of <TYPE> (EXPERIENCE, MONEY, or BOTH), or BoosterEntity.EMPTY if none is active. No player context required.

%jobs_boosters_player%

ItemProvider\<BoosterEntity\>?

Player-only. Every booster currently active for the player.

%jobs_boosters_player_<TYPE>%

BoosterEntity?

Player-only. The first active booster of <TYPE> for the player, or BoosterEntity.EMPTY if none is active.

Modifiers — jobs_modifier_<jobId>_<scope>_<sub>

Reads the player's active JobModifiers (PlayerJobModifiers, populated from booster activations and the permissions-boosters map in config.yml) and folds them into two running totals: RELATIVE modifiers are combined multiplicatively into a multiplier (starting at 1.0), ABSOLUTE modifiers are summed into a flat total (starting at 0.0). A modifier counts toward the query when:

  • its scope is GLOBAL (always counts, regardless of the queried scope), or its scope matches <scope> exactly, and

  • it has no jobId (applies to every job) or its jobId equals <jobId>.

<scope> must be one of EXPERIENCE, MONEY, GLOBAL (case-insensitive) — anything else resolves to null. <sub> is optional and defaults to percent:

<sub>

Returns

percent, bonus

(multiplier - 1.0) * 100 — the combined RELATIVE contribution as a signed percentage.

multiplier

The raw combined multiplicative factor (1.0 = no relative modifier).

flat

The summed ABSOLUTE contribution.

anything else

null.

lore: - "<gray>XP bonus: <green>+%jobs_modifier_miner_experience_percent%%" - "<gray>Money multiplier: <green>x%jobs_modifier_miner_money_multiplier%"

job_*

A Job — reached via %jobs_job_<id>%, or from any placeholder container a job has been registered into directly. A bare %job_x% where x isn't one of the keys below (and isn't menu or player, which need a further sub-key) resolves to null; a bare %job% (no further token) resolves to the Job itself.

Placeholder

Type

Description

%job_id%

String

The job's id (from its YAML file, e.g. farmer).

%job_name%

Component

The job's display-name.

%job_actions%

ItemProvider\<JobActionPlaceholder\>

Every material/entity key in the job's actions map. Chain into action_*.

%job_rewards%

ItemProvider\<JobRewardPlaceholder\>

Every level in the job's rewards map. Chain into reward_*.

%job_menu_title%

Component

The job's menu-title, resolved against the current context.

%job_menu_icon%

ItemStack

The job's menu-icon, resolved against the current context.

%job_menu_secondary-icon%

ItemStack

The job's menu-secondary-icon, resolved against the current context.

%job_player_level%

int

Player-only, and needs a further sub-key. The player's level for this job (LevelService#level), or 0 if they have no level entry.

%job_player_experience%

double

Player-only. The player's accumulated experience for this job, or 0.0 if they have no level entry.

action_*

A JobActionPlaceholder — one per material/entity key in a job's actions map (e.g. the sugar_cane entry under farmer's actions, which itself carries both a block-break and a block-place reward/experience pair).

Placeholder

Type

Description

%action_name%

TranslatableComponent

The material/entity's translatable name, computed once from the first action-type entry under this key (JobActionType#translatable) — in practice this is the same regardless of which action type looks it up, since it just wraps the block/item/entity's own translation key.

%action_item%

ItemStack

A representative icon ItemStack for the key (JobActionType#buildItem), with attributes, "placed on", and the additional tooltip hidden.

%action_computed%

List\<Component\>?

Player-only. One rendered action-display block per action-type entry under this key — see below.

%action_computed% loops every action-type entry (e.g. block-break, block-place) defined for the key, looks up its localized label from action-type-displays in config.yml (skipping — with a warning logged — any entry with no matching label), and renders the action-display template once per entry with four extra placeholders scoped to that render:

Placeholder

Description

%experience%

The entry's experience value, run through the job's leveling equations and the player's active modifiers (ModifierService#computeWithLevel) — the actual XP the player would earn right now.

%money%

The entry's reward value, computed the same way for the MONEY scope.

%formattedName%

The action type's localized label from action-type-displays (e.g. Casser for block-break).

%operation%

The entry's operation (UP/DOWN/NONE) rendered as a bold colored arrow: green, red, - gray.

# config.yml action-display: - " <red>Experience: <green>%experience%" - " <red>Money: <green>%money%" action-type-displays: block-break: "Casser" block-place: "Placer"

reward_*

A JobRewardPlaceholder — one per level in a job's rewards map.

Placeholder

Type

Description

%reward_level%

int

The reward's level key.

%reward_description%

ComponentWrapperList

The reward's description lines, unresolved (as configured in the job's YAML).

%reward_claimed%

Boolean

Whether the viewing player has already claimed this reward (JobsPlayerData#hasClaimedReward). Outside a player context this resolves to false (not null); if the player has no synced JobsPlayerData at all it resolves to null.

%reward_claimable%

Boolean?

Whether the player can claim it right now — not yet claimed and their current level (LevelService#level, 0 if absent) is >= the reward's level. Player-only — resolves to null outside a player context (note the asymmetry with claimed above, which resolves to false instead).

booster_* (blueprint)

A BoosterBlueprint — one per file under boosters/ (see Boosters). Registered into a placeholder container wherever plugin code hands a blueprint off directly (for example, when activating a booster the blueprint is registered alongside the resulting BoosterEntity).

Placeholder

Type

Description

%booster_type%

BoosterType

EXPERIENCE, MONEY, or BOTH.

%booster_scope%

BoosterScope

INDIVIDUAL or GLOBAL.

%booster_duration%

Duration

The configured duration, as a raw java.time.Duration — not directly print-friendly; use formattedDuration below.

%booster_formattedDuration%

String

The duration formatted for display, e.g. 1h 5m.

%booster_multiplier%

double

The configured multiplier (e.g. 1.15 for +15%).

%booster_item%

ItemStack

The blueprint's configured item, resolved against the current context — chain into item_* sub-keys.

booster_* (active)

A BoosterEntity — an activated (or queued) booster instance, registered into a placeholder container by BoosterService whenever it sends an activation/expiry message (see the *-booster-activated/*-booster-expired keys in Messages) or resolved via %jobs_boosters_global_<TYPE>%/%jobs_boosters_player_<TYPE>% above. Shares the registered namespace booster with the blueprint above, but exposes a different set of keys:

Placeholder

Type

Description

%booster_id%

UUID

The active booster instance's id (not the blueprint id).

%booster_owner%

MinecraftPlayerPlaceholder

The owning player — chain into player_* sub-keys.

%booster_type%

BoosterType

EXPERIENCE, MONEY, or BOTH.

%booster_formattedType%

Component

The type's localized label — the type-experience/type-money/type-global message.

%booster_scope%

BoosterScope

INDIVIDUAL or GLOBAL.

%booster_duration%

long

The configured duration in milliseconds — a raw long, not a Duration (no formattedDuration on the active entity).

%booster_remainingTime%

long

Milliseconds remaining until expiry, clamped to 0 (never negative). No formatted variant exists — as shipped, messages.yml renders this raw millisecond count directly (%booster_remainingTime%).

%booster_multiplier%

double

The multiplier this instance was activated with.

%booster_expiresAt%

long

Epoch milliseconds when the booster expires.

%booster_activatesAt%

long

Epoch milliseconds when the booster starts counting down (in the future for a queued global booster stacked behind another).

# messages.yml personal-booster-activated: "<success>Your %booster_formattedType% <#80ed99>activated for <secondary_color>%booster_remainingTime%<#80ed99>!"
Last modified: 25 July 2026