Astral Realms Documentation Help

Placeholders

AstralItems registers a root items placeholder for global lookups and exposes per-context placeholders through PipelineContext, ItemInstance, and the item data adapters. Every placeholder participates in the standard AstralCore placeholder system — %name%, %outer_{inner}%, $e(...).

Global

These resolve through RootPlaceholderContainer — usable anywhere AstralCore evaluates a placeholder (menus, dialogs, action arguments, lore templates).

Placeholder

Returns

Notes

%items_rarities%

Iterable of every loaded ItemRarity

Wrapped in an ItemProvider — pass through to a layout provider: to list rarities in a menu.

%items_blueprints%

Iterable of every loaded ItemBlueprint

Wrapped in an ItemProvider.

%items_skins%

Iterable of every loaded SkinBlueprint

Wrapped in an ItemProvider.

items_rarities, items_blueprints, and items_skins are the only keys the root items placeholder answers.

Example — populate a menu layout with every rarity:

layouts: rarities: provider: "%items_rarities%" taint: "rarity"

Rarity

A rarity is itself a ComplexPlaceholder (namespace rarity). It is most often reached through a menu parameter or via the iterable above.

Placeholder

Returns

%rarity_id%

The rarity id.

%rarity_display%

The display ItemStack.

%rarity_blueprints%

Iterable of every blueprint registered under this rarity.

Blueprint

A blueprint is a ComplexPlaceholder (namespace blueprint).

Placeholder

Returns

%blueprint_id%

The blueprint's composite Key (<rarity-id>:<id>).

%blueprint_item%

The blueprint's display ItemStack, resolved against the current placeholder context.

%blueprint_version%

The blueprint's version as "major.minor.patch".

%blueprint_metadata%

The blueprint's ItemMetadata — chain into it, see metadata.

%blueprint_rarity%

The blueprint's ItemRarity.

%blueprint_stats%

Iterable of the blueprint's stat templates, wrapped in an ItemProvider. Iterate to read %stat_key%/%stat_min%/%stat_max%.

Blueprint metadata

ItemMetadata is itself a ComplexPlaceholder (namespace metadata), reached through %blueprint_metadata_*% — the authoring surface for lore lines that used to be hard-coded status messages. Sub-key casing is inconsistent by design; use it exactly as listed.

Placeholder

Returns

%blueprint_metadata_maxStackSize%

The max-stack-size override (0 = vanilla default). camelCase.

%blueprint_metadata_repairable%

The repairable flag (boolean).

%blueprint_metadata_destroyable%

The destroyable flag (boolean).

%blueprint_metadata_tags%

The tags list.

%blueprint_metadata_available-enchantments%

Iterable of the whitelisted enchantments, wrapped in an ItemProvider — each element an EnchantmentInstancePlaceholder carrying its blueprint cap. kebab-case.

Each element of available-enchantments resolves under the enchantment namespace, with the cap exposed as %enchantment_level% on top of Bukkit's own enchantment fields (%enchantment_key%, %enchantment_name%, %enchantment_max-level%, %enchantment_anvil-cost%, …):

layouts: enchants: provider: "%blueprint_metadata_available-enchantments%" taint: "enchant-line"

Skin

A skin is a ComplexPlaceholder (namespace skin). Reach one through %items_skins% iteration or through the %instance_data_skin_blueprint_*% chain.

Placeholder

Returns

%skin_id%

The skin id.

%skin_model%

The model-key Key.

%skin_armorAsset%

The optional armor-asset-key Key — empty when unset. The sub-key is camelCase, not kebab-case.

%skin_item%

The skin's display ItemStack, resolved against the current placeholder context.

Item instance

Inside a pipeline run, instance_* resolves the ItemInstance of the triggering custom item.

Placeholder

Returns

%instance_id%

The per-item UUID.

%instance_blueprint%

The blueprint (chain into blueprint_* fields).

%instance_version%

The version captured when the item was created.

%instance_data%

The typed item-data bag (chain into per-key namespaces).

%instance_stats%

Iterable of the item's rolled stats.

%instance_stat_<key>%

Direct lookup of one rolled stat's value (double). Everything after stat_ is rejoined with _ to form the key. Resolves to nothing when the item carries no stat under that key.

%instance_lore-pages_current%

The lore page the item is on, 1-based.

%instance_lore-pages_total%

Total lore-page count (lore-pages size + 1).

The data bag is reached as %instance_data_<key>_<subkey>% — the <key> is whichever string the data class returns from ComplexPlaceholder.namespace(). Built-in keys:

Chain

Resolves to

%instance_data_scalable_level%

Current level on a scalable item.

%instance_data_scalable_experience%

Accumulated XP on a scalable item.

%instance_data_stored-material%

Stored Material (or AIR).

%instance_data_stored-material_name%

Translatable display name of the stored material. Resolves to nothing when no material is stored — render a fallback yourself.

%instance_data_stored-material_sprite%

Inline sprite component for the stored material.

%instance_data_skin_id%

Id of the applied skin, if any.

%instance_data_skin_model%

The applied skin's model Key.

%instance_data_skin_hasSkin%

true when a skin is applied (camelCase sub-key).

%instance_data_skin_blueprint_*%

Chains into the SkinBlueprint behind the stored id — both classes use the skin namespace, hence the double hop (%instance_data_skin_blueprint_item%).

Pipeline context

PipelineContext itself is a Function<String, Object> — any placeholder accepted by the underlying container resolves against it. The container is pre-populated with:

  • player_* (AstralCore + PAPI fallback) for the triggering player.

  • item_* for context.itemStack() via ItemStackPlaceholder.

  • instance_* for context.instance().

  • location_* for context.location() if any was captured.

  • extra-context_* for adapter-supplied extras.

That means component config can reference any of these in placeholder fields:

links: durability: type: take-durability amount: "%instance_data_scalable_level% / 5"

Extra context

Every entry added to PipelineContext.extraContext() that implements ComplexPlaceholder is reachable through the extra-context_<namespace>_… chain. This is how heads expose event-specific data without polluting the main context.

Extra

Namespace

Placeholders

DragAndDropContext

drag-and-drop

%extra-context_drag-and-drop_cursor_material%, %extra-context_drag-and-drop_cursor% (full ItemStack placeholder), %extra-context_drag-and-drop_instance_*% (cursor's ItemInstance if any).

AgeableBlockContext

ageable

%extra-context_ageable_age% (int), %extra-context_ageable_maximum-age% (int), %extra-context_ageable_grown% (boolean, age >= maximum-age). Bare %extra-context_ageable% returns the object.

AgeableBlockContext is not attached by an event context adapter: the PipelineContext constructor adds it whenever the context captured a block whose BlockData is Ageable (crops, nether wart, cocoa, beetroots, sweet-berry bushes, …) and no such context is present yet. Any head that captures a block — block-break, harvest-block, shear-block, interact — therefore gets it for free.

Example — read the cursor material into a set-stored-material link:

head: type: drag-and-drop links: store: type: set-stored-material material: "%extra-context_drag-and-drop_cursor_material%"

Lore-template placeholders

ItemService.applyLore exposes one extra placeholder that is only meaningful inside a blueprint's display.lore template (and inside its lore pages, which resolve through the same path):

Placeholder

Returns

%enchantments%

A list of <enchant> <roman current>/<roman max> lines, one per enchantment defined in metadata.available-enchantments. The /<max> half is omitted when the item is already at the cap. Empty when the blueprint declares no whitelist.

Use it inline:

display: lore: - "%enchantments%" - "" - "<gray>Breaks blocks in a 3×3 area."
Last modified: 03 September 2026