Astral Realms Documentation Help

Placeholders

AstralEconomy registers two placeholder namespaces with AstralCore: the root economy namespace (EconomyPlaceholders) and the per-currency currency namespace (EconomyCurrency, which is itself a ComplexPlaceholder). Both participate in the standard AstralCore placeholder system%name%, %outer_{inner}%, $e(...).

economy_* (root)

Resolved by EconomyPlaceholders, registered globally via RootPlaceholderContainer on enable — usable anywhere AstralCore evaluates a placeholder (menus, dialogs, messages, action arguments).

Placeholder

Returns

Notes

%economy_balance_<currency>%

String

The viewing player's cached balance for <currency>, formatted with NumberFormatUtils.formatWithSpaces (thousands-grouped with spaces, e.g. 1 200). Requires a Player context — resolves to null otherwise.

%economy_balance_<currency>_raw%

String

The same cached balance as a plain BigDecimal.toPlainString() — no grouping, no symbol.

%economy_balance_<currency>_formatted%

Component

The formatted amount (as above) followed by a space and the currency's %currency_symbol% component. null if <currency> isn't a configured currency id.

%economy_currencies%

ItemProvider<EconomyCurrency>

Every currency in currencies.yml. Pass through to a layout provider: to iterate all currencies in a menu.

%economy_currency_<id>%

EconomyCurrency

Looks up one currency by id (null if unknown) — a chain point into currency_* (e.g. %economy_currency_astralys_symbol%).

All three balance variants read AccountService.cachedBalance(uuid, currency) — the in-memory cache, never the database. See Reads: an in-memory cache, DB on miss: for an online (pinned) player this is warmed on join and reliably fresh; for any account that changed on another server it may lag by up to cache.read-ttl (default 5s, see Configuration) before the local cache re-syncs. These placeholders are display-only — they never gate a transaction. Anything that needs an authoritative figure (a command response, a purchase check) must go through the AccountService/EconomyAPI SPI reads instead, which load from the database on a cache miss. See Developer API.

Example — list every currency's symbol and the viewer's balance in a menu:

layouts: currencies: provider: "%economy_currencies%" taint: "currency"
lore: - "%currency_symbol% %currency_name%" - "Balance: %economy_balance_{currency_id}%"

currency_*

An EconomyCurrency placeholder (namespace currency) — one entry from currencies.yml. Reached via %economy_currency_<id>%, iterating %economy_currencies%, or wherever a currency object is registered directly into a PlaceholderContainer (see below).

Placeholder

Returns

Source field

%currency_id%

String

id

%currency_name%

Component

name (MiniMessage ComponentWrapper)

%currency_symbol%

Component

symbol (MiniMessage ComponentWrapper)

%currency_defaultBalance%

double

defaultBalance — the starting balance granted on account creation.

%currency_transferable%

boolean

transferable — whether /pay will move this currency.

%currency_default%

boolean

default (YAML key default:) — whether this is the network's default currency.

%currency_leaderboardId%

String?

leaderboardIdnull when the currency has no leaderboard configured.

Referencing %currency% with no sub-key (i.e. context.hasNext() false) resolves to the EconomyCurrency object itself, which is useful only as an intermediate chain value, not as a leaf.

Currency supplied by commands and notifications

%currency_*% (and %target_*%, %amount%, %balance%) are not global — they only resolve inside a message that a command or the balance-notification service builds its own PlaceholderContainer for, via registerDirect. The currency object is registered directly (not under economy_currency_<id>), so %currency_symbol%, %currency_name%, etc. resolve straight off the root of that container:

Direct key

Type

Registered by

Notes

currency

EconomyCurrency

/eco (set/add/give/take/balance), /pay, /balance (incl. others), NotificationService

Chain into any currency_* sub-key.

target

MinecraftPlayer (via MinecraftPlayerPlaceholder)

/eco, /pay, /balance others

The affected player — e.g. %target_name%.

amount

String

/eco set/add/take, /pay, NotificationService

The transaction amount, pre-formatted with NumberFormatUtils.formatWithSpaces.

balance

String

/eco balance, /balance (self and others)

The resulting/reported balance, pre-formatted the same way.

reason

String

/eco, /pay (on failure)

MutationResult.Result#label() — the failure enum name lowercased with underscores replaced by spaces, e.g. insufficient funds.

This is why every message that reports a balance or transfer can reference %currency_symbol% and %target_name% directly (no economy_/player_ prefix needed) — e.g. PAY_SUCCESS_SENDER templates as You sent %amount% %currency_symbol% to %target_name%.

Notes

  • %economy_balance_*% requires the placeholder context to be a Player (e.g. resolving in a menu or chat message shown to that player) — resolving against a non-player context (console, another entity) yields null.

  • %economy_currency_<id>% and the formatted balance variant both return null for an unknown currency id — there is no fallback or default substitution.

Last modified: 25 July 2026