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
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.
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.
Inner placeholders may be combined with literal segments:
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.
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:
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:
Layout-instance context (when inside an item rendered by a layout)
layouts— per-menu layout instancesvariables— per-menu local variables, falling back to globalvariablesfromconfig.ymlparameters— parameters passed into the open callviewer/player— the player viewing the menu/dialogserver— server-scoped lookupsnumberFormat— number formatting helperPlaceholderAPI 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 |
|---|---|
| In-game name |
| UUID string |
| Network latency in milliseconds |
| Current health (double) |
| Maximum health attribute |
|
|
| Display name as an Adventure component (renders with its formatting) |
| Experience level (int) |
| Progress to the next level, |
| Food level, |
| Saturation level (float) |
| The player's location — requires a sub-key (see Location and world sub-keys) |
| The player's world — requires a sub-key (see Location and world sub-keys) |
| Helmet (resolved as an |
| Chestplate |
| Leggings |
| Boots |
| Main-hand item |
| 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.
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 |
|---|---|
| X coordinate (double) |
| Y coordinate (double) |
| Z coordinate (double) |
| The location's world — continues into the |
world sub-keys (reached via %player_world_*% or %player_location_world_*%):
Placeholder | Description |
|---|---|
| World name |
|
|
| World seed (long) |
| Day time, |
| Absolute world time (long) |
|
|
server_*
Server-side queries. Unmatched keys fall through to PlaceholderAPI as %server_<remaining>%.
Placeholder | Description |
|---|---|
| List of online players (use inside a layout |
| Online player count |
|
|
| Returns the matching player (use as base for further |
| Current wall-clock time as epoch milliseconds ( |
| 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.
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.
Global variable example (from config.yml):
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 |
|---|---|
| Layout identifier |
| Current page index (0-based) |
| Total number of pages |
|
|
|
|
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.
Input | Output |
|---|---|
|
|
|
|
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 |
|---|---|
| String |
| Boolean ( |
| Float |
| String key of the selected option |
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.