Astral Realms Documentation Help

Placeholders

AstralCore's placeholder system is the universal bridge between configuration files and runtime values. The same syntax is used in menus, dialogs, action arguments, requirement values, item names and lore, chat messages, message-config strings — anywhere a string passes through AstralCore's parser.

Syntax

Standard placeholder

%namespace_key_subkey%

Underscores (_) separate namespace tokens. A placeholder is parsed left-to-right: the first token selects a namespace, and each subsequent token narrows the lookup inside that namespace.

title: "<bold>Hello %player_name%" lore: - "<gray>HP: %player_health_rounded%" - "<gray>Helmet: %player_equipment_HEAD%"

Inner placeholders

A placeholder can be nested inside another using curly braces. The inner placeholder is resolved first and its result is substituted into the outer key before the outer lookup runs.

%outer_{inner_placeholder}%
# variables.tab → "weapons", so the resolved key becomes %parameters_weapons% lore: - "<gray>Active tab: %parameters_{variables_tab}%"

Inner placeholders may be combined with literal segments:

- "<gray>Slot: %layouts_{variables_active_layout}_page%"

Expression evaluation

Wrap an arithmetic expression in $e(...) to evaluate it. Placeholders inside the expression are resolved first; the result must be numeric. Returns an integer when the result is a whole number, otherwise a double.

$e(%variables_count%+1) $e((%variables_qty%*%parameters_price%)-5) $e(round(%player_health%, 1))

Supported operators come from the Crunch math library: +, -, *, /, ^, plus parentheses. The custom round(value, precision) function is registered out of the box.

Expressions are commonly used with set-variable:

- "[set-variable] count $e(%variables_count%+1)" - "[set-variable] qty $e(%variables_qty% < 64 ? %variables_qty%+1 : 64)"

Inline functions

For named, multi-argument helpers (clamped arithmetic, number formatting, date formatting, etc.), see Functions — invoked as $name(arg1, arg2, ...).

Resolution Order

When a placeholder is parsed the namespace token is looked up in this order:

  1. Layout-instance context (when inside an item rendered by a layout)

  2. layouts — per-menu layout instances

  3. variables — per-menu local variables, falling back to global variables from config.yml

  4. parameters — parameters passed into the open call

  5. viewer/player — the player viewing the menu/dialog

  6. server — server-scoped lookups

  7. numberFormat — number formatting helper

  8. PlaceholderAPI fallback for any unmatched key

player_*

Properties of the player who has the menu/dialog open. Any key not listed below is forwarded to PlaceholderAPI as %player_<remaining>%, so PAPI expansions still work.

Placeholder

Description

%player_name%

In-game name

%player_uuid%

UUID string

%player_ping%

Network latency in milliseconds

%player_health%

Current health (double)

%player_health_max%

Maximum health attribute

%player_health_rounded%

Math.round(health)

%player_displayName%

Display name as an Adventure component (renders with its formatting)

%player_level%

Experience level (int)

%player_exp%

Progress to the next level, 0.01.0 (float — not total XP)

%player_food%

Food level, 020 (int)

%player_saturation%

Saturation level (float)

%player_location%

The player's location — requires a sub-key (see Location and world sub-keys)

%player_world%

The player's world — requires a sub-key (see Location and world sub-keys)

%player_equipment_HEAD%

Helmet (resolved as an item placeholder, see below)

%player_equipment_CHEST%

Chestplate

%player_equipment_LEGS%

Leggings

%player_equipment_FEET%

Boots

%player_equipment_HAND%

Main-hand item

%player_equipment_OFF_HAND%

Off-hand item

The %player_*% namespace is also exposed under the alias %viewer_*% inside dialogs.

Equipment sub-keys

The equipment placeholder returns an ItemStackPlaceholder instance, so the remaining tokens drill into the item. Available sub-keys: material, name, hover-name, lore, amount, custom-model-data, durability, enchantments.

lore: - "<gray>Helmet: %player_equipment_HEAD_name%" - "<gray>Material: %player_equipment_HEAD_material%"

Location and world sub-keys

%player_location% and %player_world% return chaining objects — a bare %player_location% or %player_world% is not useful on its own; append a sub-key to drill in.

location sub-keys (also reachable via %player_location_world_*%):

Placeholder

Description

%player_location_x%

X coordinate (double)

%player_location_y%

Y coordinate (double)

%player_location_z%

Z coordinate (double)

%player_location_world_<key>%

The location's world — continues into the world sub-keys below

world sub-keys (reached via %player_world_*% or %player_location_world_*%):

Placeholder

Description

%player_world_name%

World name

%player_world_environment%

NORMAL/NETHER/THE_END/CUSTOM

%player_world_seed%

World seed (long)

%player_world_time%

Day time, 024000 (long)

%player_world_fullTime%

Absolute world time (long)

%player_world_difficulty%

PEACEFUL/EASY/NORMAL/HARD

lore: - "<gray>Position: %player_location_x%, %player_location_y%, %player_location_z%" - "<gray>World: %player_world_name% (%player_world_environment%)"

server_*

Server-side queries. Unmatched keys fall through to PlaceholderAPI as %server_<remaining>%.

Placeholder

Description

%server_players%

List of online players (use inside a layout provider)

%server_online%

Online player count

%server_online_<uuid-or-name>%

true if the player is online, false otherwise

%server_player_<uuid-or-name>%

Returns the matching player (use as base for further player_* lookups)

%server_currentTimeMillis%

Current wall-clock time as epoch milliseconds (System.currentTimeMillis())

%server_currentTimeSeconds%

Current wall-clock time as epoch seconds

The two time keys pair naturally with $format-date(...)/%player_timestamp_*% for building countdowns and "time since" displays.

parameters_*

Parameters passed when the menu or dialog was opened.

menus.computeAndOpen(player, "shop", Map.of("tab", "weapons", "page", 2));
title: "<bold>Shop — %parameters_tab%" lore: - "<gray>Page %parameters_page%"

Inside dialogs the same namespace exposes the parameters passed to dialogs().openMenu(...).

variables_*

Mutable per-menu state declared under variables: and updated via set-variable. If a key is not found in the menu's variables, the lookup falls through to the global variables: map defined in config.yml, which means the same namespace covers both local and global variables.

variables: mode: "buy"
name: "<yellow>Mode: %variables_mode%"

Global variable example (from config.yml):

variables: server_display_name: "AstralRealms"
lore: - "<gray>Network: %variables_server_display_name%"

layouts_* and layout-instance keys

%layouts_<id>% returns the live layout instance for <id>. Its keys are then accessed via the standard nested chaining.

Placeholder

Description

%layouts_<id>_id%

Layout identifier

%layouts_<id>_page%

Current page index (0-based)

%layouts_<id>_maxPages%

Total number of pages

%layouts_<id>_hasNextPage%

true when a next page exists

%layouts_<id>_hasPreviousPage%

true when a previous page exists

items: next-page-button: slot: 53 item-stack: material: ARROW name: "<green>Page %layouts_items_page% / $e(%layouts_items_maxPages%-1)" view-requirements: - "[compare] %layouts_items_hasNextPage% == true" actions: LEFT: - "[next-page] items"

numberFormat_*

Formats the resolved value as a localised number. The remaining tokens form the placeholder key whose value should be formatted; dashes (-) in the remaining tokens are converted back to underscores before lookup, so keys with their own underscores can be chained without breaking the parser.

Output uses a space as a thousands separator and up to 2 decimal places.

lore: - "<gray>Balance: %numberFormat_parameters_balance%" - "<gray>Total: %numberFormat_{variables_total}%"

Input

Output

1234567

1 234 567

1234.5678

1 234.57

input_* (dialogs only)

Inside the action list of a dialog button, each input's current value is bound as %input_<input-id>%. The type matches the input:

Input type

Value type

text

String

boolean

Boolean ("true"/"false")

slider

Float

options

String key of the selected option

yes-button: label: "Confirm" actions: - "[console] rename %player_name% %input_username%"

PlaceholderAPI Fallback

When a key is not handled by any registered AstralCore placeholder, the entire %...% string is passed to PlaceholderAPI. All standard PAPI expansions (%vault_eco_balance%, %luckperms_prefix%, etc.) work inside menus and dialogs without any extra configuration.

lore: - "<gold>Coins: %vault_eco_balance%" - "<gray>Rank: %luckperms_prefix%"
Last modified: 25 July 2026