Astral Realms Documentation Help

Lore Modifiers

Lore modifiers generate dynamic blocks of lore lines inside an item-stack. Instead of writing a fixed lore: list, you declare named modifiers under lore-modifiers: and reference them from a lore line as a placeholder. Each reference is replaced, in place, by however many lines the modifier produces — zero, one, or many.

Two modifier types are available:

Type

Purpose

conditional

Pick one block of lines out of several, based on requirements.

iterable

Repeat one line template once per entry of a data provider.

Declaring modifiers

The lore-modifiers block lives directly inside item-stack. Each child key is a modifier name, and each modifier must declare its type.

item-stack: material: DIAMOND_SWORD name: "<gold>Heroic Blade" lore: - "<gray>A blade of starlight." - "%lore-modifiers_status%" lore-modifiers: status: type: conditional entries: { }

Field

Type

Required

Description

<name>

object

—

Modifier name, used in the %lore-modifiers_<name>% reference.

<name>.type

String

Yes

conditional or iterable. An unknown value fails the config load.

Referencing a modifier

Reference a modifier from any lore: line with the lore-modifiers namespace:

lore: - "%lore-modifiers_status%"

The placeholder resolves to a list of components, and a lore line that resolves to a list is expanded into one line per element. Surrounding text on the same line is kept on the first produced line only, so a modifier reference is normally the whole line.

Behaviour worth knowing:

  • An empty result removes the line. If a conditional matches no entry, or an iterable gets a null/empty provider, the lore line disappears entirely rather than rendering as a blank line.

  • Modifiers are only registered when lore: is present. A lore-modifiers block on an item without a lore list is inert.

  • Modifiers are re-evaluated on every render, so they follow item refreshes and menu recomputes.

conditional

Evaluates a set of named entries and emits the content of the highest-priority entry whose requirements pass. Only one entry ever wins.

Field

Type

Required

Description

type

String

Yes

conditional.

entries

Map<String, Entry>

Yes

Named candidate blocks. An empty or missing map produces nothing.

entries.<name>.content

List<String>

Yes

The lore lines emitted when this entry wins (MiniMessage, placeholders supported).

entries.<name>.requirements

List<Requirement>

No

Guards for this entry — see Requirements. Omitted means always satisfied.

entries.<name>.priority

int

No

Higher is checked first. Default 0.

Requirements are evaluated against the player viewing the item. A requirement that throws at runtime counts as not satisfied, so a failing entry silently yields to the next one.

Give the fallback entry no requirements and the lowest priority so it wins only when nothing else does:

item-stack: material: PAPER lore: - "%lore-modifiers_rank%" lore-modifiers: rank: type: conditional entries: vip: priority: 10 requirements: - "[permission] myplugin.vip" content: - "<gold>VIP member" - "<gray>Bonus: <yellow>+25%" default: priority: 0 content: - "<gray>Standard member"

iterable

Renders a single line template once per entry of a data provider, producing one lore line per entry.

Field

Type

Required

Description

type

String

Yes

iterable.

provider

String (placeholder)

Yes

Resolves to the data source — same contract as a layout's provider (see Data Providers). A null result produces nothing.

content

String

Yes

One line template, rendered once per entry.

requirements

List<Requirement>

No

Per-entry filter — see Requirements. An entry whose requirements fail is skipped and emits no line. Omitted means every entry is rendered.

maximum-entries

int

No

Caps how many entries are rendered. Only applied when greater than 0; 0 or omitted means every entry.

Inside content, each iteration exposes:

Placeholder

Description

%parameter_index%

Zero-based index of the current entry — only when the item is not rendered inside a layout slot, where the layout's own index wins (see below).

%parameter_position%

1-based position of the current entry (index + 1). Never shadowed by a layout.

%parameter_<namespace>_…%

The entry itself, under its own placeholder namespace.

The namespace of the third form is whatever namespace the provider's entries declare — for a provider of shop offers exposing offer, that is %parameter_offer_price% and so on. Note the singular parameter namespace, which is distinct from the menu-level %parameters_…%.

item-stack: material: CHEST name: "<gold>Contents" lore: - "<gray>This crate contains:" - "%lore-modifiers_rewards%" lore-modifiers: rewards: type: iterable provider: "%parameters_rewards%" maximum-entries: 5 content: "<gray>%parameter_position%. <white>%parameter_reward_name%"

Filtering entries with requirements

requirements runs once per entry, after the entry placeholders are injected, so the guards can read the entry itself — %parameter_index%, %parameter_position%, the entry's own namespace and every inherited parameter value are all resolvable inside the requirement:

item-stack: material: CHEST name: "<gold>Contents" lore: - "<gray>This crate contains:" - "%lore-modifiers_rewards%" lore-modifiers: rewards: type: iterable provider: "%parameters_rewards%" maximum-entries: 5 requirements: - "[compare] %parameter_reward_hidden% == false" content: "<gray>%parameter_position%. <white>%parameter_reward_name%"

Behaviour worth knowing:

  • The cap counts entries examined, not lines emitted. maximum-entries truncates the provider list before requirements run, so a filtered-out entry still consumes one of the allowed slots — with maximum-entries: 5 and two entries failing their requirements, three lines are produced.

  • %parameter_position% follows the provider index, not the output line. Skipped entries leave gaps in the numbering (1., 3., 4.), so it is not a reliable counter of the rendered lines.

  • A requirement that throws skips the entry and logs an error to the server console, rather than aborting the whole modifier.

  • Requirements need a viewing player. They are evaluated against the player the item is rendered for; a render with no player (a console/offline render) cannot satisfy the requirement context. Leave requirements off for items that may be built without a viewer.

  • All entries pass unchanged when requirements is omitted — the field is purely additive.

See also

  • Transformers — the replacement for this block.

  • Menu Items — the item-stack block that hosts lore-modifiers.

  • Requirements — the requirement forms accepted by conditional entries.

  • Menu Layouts — provider types accepted by iterable.

Last modified: 03 September 2026