Astral Realms Documentation Help

Blueprint YAML Reference

A blueprint defines a single custom item: its identifier, version, rarity, display appearance, optional metadata, pipelines, and optional default item data.

Blueprints live in plugins/AstralItems/blueprints/ (sub-folders are scanned recursively). The file name is irrelevant; the id field inside combined with the referenced rarity's id forms the item's Key.

Minimal example

id: "hammer" rarity: abyss version: "2.0.3" display: copy-from: "%stacksuppliers_ce_items:abyss-hammer%" name: "<gradient:#00353D:#11767D><bold>Marteau des Abîmes" lore: - "%enchantments%" - "" - "<gray>Breaks blocks in a 3×3 area." lore-pages: 0: - "<gray>Level: <white>%instance_data_scalable_level%" metadata: max-stack-size: 1 repairable: true destroyable: false available-enchantments: efficiency: 7 fortune: 3 mending: 1 pipelines: mine: head: type: "block-break" links: hammer: type: hammer radius: 3 depth: 1 durability: type: take-durability amount: 1 tails: magnet: type: magnet

Top-level fields

Field

Type

Required

Description

id

String

Yes

Blueprint identifier. Combined with the rarity id to produce the item's Key: <rarity-id>:<id>.

rarity

String

Yes

Id of an existing rarity in rarities/. Loading fails if it does not exist.

version

String

No

Semver major.minor.patch. Defaults to 1.0.0 when omitted. Stored in the item PDC at creation; bumping it triggers a live re-build the next time the player handles the item (see Item upgrade).

display

ItemStackWrapper

Yes

Standard AstralCore item template — material, name, lore, enchantments, item-flags, durability, glow, … See Menu Items.

metadata

ItemMetadata

No

Behavioural metadata (see metadata below).

pipelines

Map<String, Pipeline>

No

Map of pipeline-id → pipeline. Pipeline ids are unique per blueprint, not globally.

default-data

Map<Key, Object>

No

Default values for the item data registered to the blueprint. Each key resolves through ItemDataRegistry to its ItemDataAdapter, which deserialises the value.

stats

Map

No

Per-item numeric stats rolled once at creation (experimental). See Item Stats.

lore-pages

Map<int, List<String>>

No

Extra lore pages the holder cycles through with a swap-offhand click. See Lore Pages.

metadata

Field

Type

Default

Description

max-stack-size

int

0

Override Minecraft's default stack size. 0 keeps the vanilla default; any positive value is applied via ItemMeta.setMaxStackSize.

repairable

boolean

false

Declarative flag exposed to lore templates as %blueprint_metadata_repairable%. AstralItems no longer renders a status line for it itself — author the line in display.lore from that placeholder.

destroyable

boolean

false

If true, the item is consumed when durability hits zero. If false, take-durability caps damage at maxDurability - 1 so the item never breaks; the DurabilityListener prevents vanilla break attempts.

tags

List<String>

[]

Free-form tags used to filter drag-and-drop heads — only cursor items whose blueprint has at least one matching tag are accepted.

available-enchantments

Map<Enchantment, int>

{}

Whitelist + per-enchantment level cap honoured by the custom anvil: books containing other enchantments are rejected, and a combine that would exceed a cap is rejected outright rather than clamped. Caps may exceed vanilla's natural maxima (efficiency: 7). Also drives the %enchantments% lore placeholder and the %blueprint_metadata_available-enchantments% iterable.

default-data

default-data pre-populates the item data bag every time a new instance is created from the blueprint. Keys must be registered in ItemDataRegistry; values are deserialised by the registered ItemDataAdapter.

default-data: "astralitems:stored-material": material: AIR "astralitems:scalable": level: 1 experience: 0

The first key matches StoredMaterialItemDataAdapter (used by tools like the spade and mallet to remember the block the player loaded onto them). The second matches ScalableItemDataAdapter (used by levelling items).

When an adapter cannot deserialise the value written under a key, the loader falls back to that adapter's default value before giving up: only a key whose adapter has no default (null) fails the blueprint with a Failed to deserialize item data value for item blueprint: <id>, key: <key> error. Of the built-ins only StoredEntityItemData declares one — the empty entry — so declaring it under default-data with any value yields an empty capture slot rather than a load failure.

stats

stats declares numeric stats that are rolled once when the item is created and persisted on the instance. Each entry has a key, a min/max roll range, and an optional context:

stats: attack: # decorative id key: "astralstats:attack_damage" min: 5 max: 10

See Item Stats for the roll rules, persistence, placeholders, and the current (experimental) status of the feature.

lore-pages

lore-pages declares extra tooltip pages the holder cycles through with a swap-offhand click (F). Keys are 0-based and supply the pages after display.lore, which is always page 1:

lore-pages: 0: - "%enchantments%" 1: - "<gray>Level: <white>%instance_data_scalable_level%"

See Lore Pages for the cycling rules, rendering caveats, persistence, and the %instance_lore-pages_*% counters.

version

The blueprint version is captured by the item at creation and persisted in PDC. When the player handles an item whose stored version is older than the blueprint's current version, the UpgradeListener calls ItemService.upgrade(stack) — it rebuilds the display from the new blueprint while preserving the item's UUID, enchantments, damage, amount, and unbreakable flag. See Developer API.

version: "2.0.3"

Map-form (major: 2, minor: 0, patch: 3) is also accepted by the deserialiser, but the string form is preferred.

pipelines

The pipelines block is a map of pipeline id → pipeline definition. Every pipeline has the same three sections:

pipelines: <pipeline-id>: head: # exactly one head — captures a Bukkit event type: "<head-type>" …head-specific fields requirements: # optional, AstralCore PaperRequirementList - … links: # optional map of <link-id> → chain link <link-id>: type: "<link-type>" …link-specific fields tails: # optional map of <tail-id> → terminal step <tail-id>: type: "<tail-type>" …tail-specific fields

Inside links and tails the map key is a free-form id used only for ordering and config tooling. Order follows the YAML insertion order — chain links run top-to-bottom, then tails run top-to-bottom.

A component that takes no configuration can be collapsed to its bare type id — head: "hold-item", tails: { log: "debug" } — see Compact component form for when that is and is not allowed.

A blueprint may declare multiple pipelines — for example a spade that has one pipeline for drag-and-drop (to store the seed loaded by the player), one for interact → plant-crops, and a third for interact → spade-grass.

See:

Per-component requirements

Every wrapped pipeline component (head, link, or tail) can optionally carry a requirements block evaluated against the player and the current PipelineContext (which exposes item, location, block, entity, drop, and extra-context placeholders):

links: durability: type: take-durability amount: 1 requirements: - "permission:items.use-hammer" - "stat:level >= 5"

Requirements use AstralCore's PaperRequirementList. When a head's requirements fail the event is cancelled and the rest of the pipeline is skipped; when a link or tail's requirements fail the component is silently skipped and the next one runs.

has-tag

On top of AstralCore's built-in requirements, AstralItems registers has-tag globally — it works in any requirement list on the server, not just in pipelines: menu view-requirements, clicks-requirements, dialog gating, and so on.

It passes when the given ItemStack is a custom item whose blueprint declares the given tag in metadata.tags. A vanilla item, or an item whose blueprint has no matching tag, fails.

Argument

Type

Description

item

Placeholder resolving to an ItemStack

The item to test.

tag

String (placeholder)

The tag to look for in the blueprint's metadata.tags.

requirements: # inside a pipeline — %item% is the item that triggered it - "[has-tag] %item% upgrade-orb"
# inside a menu — test the item a parameter carries view-requirements: - "[has-tag] %parameters_item% quest-key"

Tags come from the blueprint's metadata.tags list — the same list the drag-and-drop head's tags field filters on.

Validation

The blueprint loader rejects entries that fail any of these checks:

  • Missing or empty id — file is logged and skipped.

  • Missing or empty rarity, or a rarity that is not registered.

  • display cannot be parsed as an ItemStackWrapper.

  • A pipeline references a type that is not registered with PipelineService — see Pipeline Heads / Links / Tails for the registry.

  • A default-data key is not registered in ItemDataRegistry.

  • Two blueprints resolve to the same Key (rarity:id) — the duplicate is logged as a warning and skipped.

A bad blueprint does not prevent the rest from loading.

Hot reload

/items reload clears the blueprint registry, re-reads every file from blueprints/, and calls PipelineService.initialize() which:

  1. Unregisters every dummy listener previously registered with Bukkit.

  2. Walks every blueprint's pipelines.

  3. Registers a fresh listener per (EventPriority, Event) pair and inserts the freshly deserialised pipelines into the right EventNode.

CraftEngine triggers the same reload path automatically when it fires CraftEngineReloadEvent (which is also the trigger for the very first blueprint load on server boot).

Item upgrade

When a player handles a stack whose stored blueprint version is older than the current blueprint version, ItemService.upgrade(stack) rebuilds the ItemStack from the new blueprint and transfers:

  • The ItemInstance UUID.

  • Enchantments — capped against metadata.available-enchantments.

  • Damage value.

  • unbreakable flag.

  • Stack amount.

Upgrades fire on PlayerDataLoadedEvent (from AstralSync), InventoryOpenEvent, and ChunkLoadEvent (for item frames, containers, and shelves in newly loaded chunks).

Last modified: 03 September 2026