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 |
|---|---|---|
| String | The viewing player's cached balance for |
| String | The same cached balance as a plain |
| Component | The formatted amount (as above) followed by a space and the currency's |
| ItemProvider<EconomyCurrency> | Every currency in |
| EconomyCurrency | Looks up one currency by id ( |
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:
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 |
|---|---|---|
| String |
|
| Component |
|
| Component |
|
| double |
|
| boolean |
|
| boolean |
|
| String? |
|
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 |
|---|---|---|---|
| EconomyCurrency |
| Chain into any |
| MinecraftPlayer (via |
| The affected player — e.g. |
| String |
| The transaction amount, pre-formatted with |
| String |
| The resulting/reported balance, pre-formatted the same way. |
| String |
|
|
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 aPlayer(e.g. resolving in a menu or chat message shown to that player) — resolving against a non-player context (console, another entity) yieldsnull.%economy_currency_<id>%and theformattedbalance variant both returnnullfor an unknown currency id — there is no fallback or default substitution.