Astral Realms Documentation Help

Pipeline Chain Links

Chain links sit between the head and the tails. Each link receives the current PipelineContext, mutates it, and returns it for the next link. Links execute in YAML insertion order.

A failing requirement on a link skips that link but lets the rest of the pipeline continue. An exception thrown by a link aborts the rest of that pipeline run (it is logged but not rethrown).

Some links extend EventBoundedPipelineChainLink<E> — they assert that context.event() is an instance of their bound event type. If the binding doesn't match the link silently no-ops (it does not abort the pipeline). These are marked event-bound in the sections below.

take-durability

Damages the item by amount. Honours the blueprint's metadata.destroyable:

  • destroyable = true → the item is consumed when durability hits zero (via player.damageItemStack).

  • destroyable = false (default) → damage is capped at maxDurability - 1; the item never breaks.

links: durability: type: take-durability amount: 1

Field

Type

Description

amount

PlaceholderWrapper<Integer>

Damage points to subtract. Supports placeholders.

Silently no-ops if the item is not Damageable.

repair

Event-bound: InventoryClickEvent. Designed to pair with a drag-and-drop head — repairs the cursor item (the damaged tool the player dropped onto the repair orb) by resetting its damage to zero. Cancels the click event in both success and failure cases.

links: repair: type: repair

No configurable fields. No-op if the cursor has no ItemInstance, no damage, or already has zero damage — in the no-damage case the click is still cancelled so the orb isn't consumed pointlessly.

Typical pairing:

head: type: drag-and-drop links: repair: type: repair consume: type: remove-cursor

unbreakable

Event-bound: InventoryClickEvent. Same shape as repair — designed for a drag-and-drop head. Sets the cursor item's damage to zero and marks it Unbreakable. If the item is already unbreakable, the click is cancelled and the link no-ops so the consumable isn't wasted.

links: apply-unbreakable: type: unbreakable

No configurable fields.

Actions

execute-actions

Runs an AstralCore PaperActionList with the player as the target. The pipeline context is passed as the placeholder source, so every context placeholder (%item_*%, %player_*%, %entity_*%, %instance_data_*%, …) resolves.

links: buff: type: execute-actions actions: - "[message] <gold>Critical hit!</gold>" - "[sound] minecraft:entity.player.levelup" - "[player] particles celebrate"

Field

Type

Description

actions

PaperActionList

List of AstralCore action strings — see Actions.

execute-random-actions

Picks one weighted entry from a map and runs its actions. Useful for randomised drops, randomised buffs, …

links: random-buff: type: execute-random-actions actions: crit: chance: 10 actions: - "[message] <red>CRIT!</red>" lucky: chance: 90 actions: - "[message] <gray>nothing happened</gray>"

Field

Type

Description

actions

Map<String, { chance: PlaceholderWrapper<Double>, actions: PaperActionList }>

Weighted entries. The map key is a free-form id; the value is the weight (chance) and the action list.

Weights are interpreted by RandomCollection — they do not have to sum to 100; pick is proportional.

Drops & experience

multiply-drops

Duplicates everything currently in context.drops() by multiplier. Optional chance (0–100 roll) gates the link.

links: loot-burst: type: multiply-drops multiplier: 2 chance: 25

Field

Type

Description

multiplier

PlaceholderWrapper<Integer>

Total copies of the drop list to leave in context (drops × multiplier).

chance

PlaceholderWrapper<Integer>

Optional. 0–100 inclusive; the link is skipped on a failed roll.

multiply-exp

Same idea as multiply-drops but for context.experience().

links: xp-burst: type: multiply-exp multiplier: 3 chance: 50

Field

Type

Description

multiplier

PlaceholderWrapper<Integer>

Multiplier applied to the captured vanilla XP.

chance

PlaceholderWrapper<Integer>

Optional. 0–100 roll.

remove-item

Removes amount copies of context.itemStack() from the player's inventory via InventoryUtils.removeItems. Useful for consumable items.

links: consume: type: remove-item amount: 1

Field

Type

Description

amount

PlaceholderWrapper<Integer>

Number of copies to remove. Supports placeholders.

remove-cursor

Clears the player's cursor stack. Requires the event to be an InventoryClickEvent — throws if used outside that context. Designed to pair with a drag-and-drop head: the cursor is the consumable that was just applied to the slot item.

links: consume-orb: type: remove-cursor

No configurable fields.

Item data

scalable

Levelling system: accumulates XP on the item's ScalableItemData until a threshold, then increments the level and (optionally) evolves the item into another blueprint.

links: xp: type: scalable needed-experience: 100 experience-gain: 1 next-item: "abyss:hammer_t2" # optional — replace the stack with this blueprint on level-up level-up-actions: - "[message] <gold>Your hammer reached level %instance_data_scalable_level%!</gold>" - "[sound] minecraft:entity.player.levelup"

Field

Type

Description

needed-experience

PlaceholderWrapper<Integer>

XP required to reach the next level.

experience-gain

PlaceholderWrapper<Integer>

XP added to the item each pipeline run.

next-item

PlaceholderWrapper<Key>

Optional. Blueprint key to evolve into on level-up. Enchantments and item data (except scalable) are transferred to the new instance.

level-up-actions

PaperActionList

Optional. Action list executed when a level-up occurs.

whitelist

Set<Material>

Optional. If non-empty, XP is gained only when the broken block is listed.

blacklist

Set<Material>

Optional. If the broken block is listed, the link is skipped (no XP).

allowed-tags

List<Tag<Material>>

Optional. If set, XP is gained only when the broken block matches at least one tag. See Material tags.

The link runs only when the triggering item is in the player's main hand (off-hand triggers are ignored). Setting context.dirty(true) and (on evolve) context.replaceItemStack(true) is handled automatically.

set-stored-material

Event-bound: InventoryClickEvent. Designed for a drag-and-drop head — writes the cursor item's Material onto the slot item's StoredMaterialItemData. Cancels the click event.

links: set-material: type: set-stored-material material: "%extra-context_drag-and-drop_cursor_material%" whitelist: - WHEAT_SEEDS - POTATO - CARROT blacklist: []

Field

Type

Description

material

PlaceholderWrapper<Material>

Material to store. Usually a placeholder reading the cursor through the drag-and-drop extra context.

whitelist

List<Material>

If non-empty, only these materials can be stored.

blacklist

List<Material>

Materials that are explicitly rejected.

The slot item's StoredMaterialItemData must already exist (either created by default-data or by a prior pipeline). Sets context.dirty(true) so the listener persists the change.

set-item-model

Sets the live item's item_model component (Minecraft 1.21.4+) to a namespaced key — e.g. to reskin an item as it levels up.

links: reskin: type: set-item-model model: "myserver:hammer_lvl_%instance_data_scalable_level%"

Field

Type

Description

model

PlaceholderWrapper<Key>

Item-model key (namespace:path). Placeholders resolve against the pipeline context.

store-entity

Serialises the captured entity onto the item's StoredEntityItemData (key astralitems:entity) and removes it from the world — a "capture" mechanic (mob catcher, pet wand, …). Any previously stored entity is released first. Sets context.dirty(true).

Requires context.entity() — pair it with an entity-populating head (interact-entity, entity-damage, bucket-entity, fish, shear-entity, entity-kill); it throws if no entity was captured.

head: type: interact-entity links: capture: type: store-entity

No configurable fields.

release-entity

Deserialises the stored entity and spawns it at the player's location, then clears the StoredEntityItemData. No-ops when nothing is stored. Sets context.dirty(true).

links: release: type: release-entity

No configurable fields.

These read the captured event state (block, location, player) and apply specialised side effects.

melt

Replaces every drop in context.drops() with the result of its furnace recipe. Drops without a furnace recipe are left untouched. Recipes are cached after first lookup.

links: smelt: type: melt blacklist: [STONE]

Field

Type

Description

blacklist

List<Material>

Drop materials skipped by the melt step.

The resulting amount equals the original stack's amount — one ore in produces one ingot out per stack unit, scaled by the input stack size.

hammer

Event-bound: BlockBreakEvent. Area-of-effect block breaking — uses the player's look direction to compute the affected plane.

links: hammer: type: hammer radius: 1 depth: 0 blacklist: [BEDROCK] whitelist: [STONE, IRON_ORE]

Field

Type

Description

radius

int

Half-extent of the AoE plane on the face perpendicular to the player's look. radius = 1 gives a 3×3 footprint.

depth

int

Extra layers in the direction the player is looking. depth = 0 breaks only the face plane; depth = 1 adds one extra layer behind it.

blacklist

List<Material>

Block types skipped by the AoE step.

whitelist

List<Material>

If non-empty, only listed materials are broken by the AoE.

allowed-tags

List<Tag<Material>>

Optional. When present, only blocks matching at least one tag are broken. Omit the key to disable — an explicit empty list breaks nothing. See Material tags.

For each affected block the link fires a virtual BlockBreakEvent through EventService.fireVirtualEvent so other plugins (protection, logging, claim systems) get a chance to cancel the break.

infinite-bucket

Event-bound: PlayerInteractEvent. Bucket-like behaviour — fill or drain water / lava / powder snow without consuming the item. Handles waterloggable blocks, cauldrons (empty, water, lava, powder-snow), and adjacent fluid placement / removal.

links: water-bucket: type: infinite-bucket fluid-type: WATER drain: false

Field

Type

Description

fluid-type

Material

One of WATER, LAVA, or POWDER_SNOW.

drain

boolean

If true, the link drains a fluid block / cauldron / waterlog instead of placing one.

When draining, the adjacent-block sweep also clears powder snow and bubble columns in addition to water and lava (bubble_column is only a drain target — it is not a valid fluid-type). Every fill / drain fires a virtual PlayerBucketFillEvent/PlayerBucketEmptyEvent, so protection plugins can veto the change (anti-grief).

break-leaves

Raytraces forward from the player's eye position and breaks every leaf block in a beam around the ray. Drops the broken leaves into context.drops() so a tail (magnet/drop) can grant them.

links: chop-leaves: type: break-leaves range: 15 beam-radius: 1

Field

Type

Description

range

PlaceholderWrapper<Integer>

Forward distance in blocks.

beam-radius

PlaceholderWrapper<Integer>

Per-step cube radius checked around the ray. 1 checks a 3×3×3 cube each step.

The leaves tag is built from every Bukkit material whose name ends in LEAVES, plus NETHER_WART_BLOCK and WARPED_WART_BLOCK. For each break the link fires a virtual BlockBreakEvent so other plugins can veto.

build-wand

Event-bound: PlayerInteractEvent. Places up to length blocks of the player's stored material in the direction of the clicked face, consuming matching blocks from the player's inventory. Stops on out-of-bounds, occupied blocks, or empty inventory.

links: builder: type: build-wand length: 3

Field

Type

Description

length

PlaceholderWrapper<Integer>

Maximum number of blocks to place.

The stored material is resolved via StoredMaterialItemData. Each placement fires a virtual BlockPlaceEvent so claim plugins can veto. Cancels the underlying interact event after running.

fell-tree

Event-bound: BlockBreakEvent. Walks upward from the broken block as long as the block above is a log (via MaterialSetTag.LOGS), breaks every log encountered, accumulates drops + XP. For each break the link fires a virtual BlockBreakEvent so other plugins can veto.

links: fell-tree: type: fell-tree range: 20

Field

Type

Description

range

PlaceholderWrapper<Integer>

Max vertical distance to scan.

firework-boost

Boosts a gliding player as if they had used a firework rocket — emits no actual firework. Sends not-gliding to the player when not currently gliding.

links: boost: type: firework-boost power: 2

Field

Type

Description

power

PlaceholderWrapper<Integer>

Firework power (1–3 typical). Defaults to 1.

plant-crops

Event-bound: PlayerInteractEvent (right-click block only). Plants compatible seeds from the player's inventory in an n × n square around the clicked block. Recognised seed → crop pairs (when the clicked block is farmland) include wheat seeds, potato, carrot, melon seeds, pumpkin seeds, beetroot seeds; soul sand is paired with nether wart. Unused seeds are refunded.

links: plant: type: plant-crops range: 1 # 3×3 area centred on the clicked block

Field

Type

Description

range

PlaceholderWrapper<Integer>

Half-extent of the planting area. 0 plants only on the clicked block.

replant-crops

Event-bound: BlockBreakEvent. When a fully-grown Ageable crop is broken, scans the surrounding n × n square, harvests every fully-grown crop in range (drops + XP added to context), and resets each broken crop's age to 0 so it regrows. The original event is cancelled.

links: replant: type: replant-crops range: 1 whitelist: [WHEAT, CARROTS, POTATOES, BEETROOTS] blacklist: []

Field

Type

Description

range

PlaceholderWrapper<Integer>

Half-extent of the harvest area.

whitelist

List<Material>

If non-empty, only these crop materials are processed.

blacklist

List<Material>

Crop materials that are skipped.

Each replant fires a virtual BlockPlaceEvent (if a protection plugin cancels it, the crop is reverted to its grown state and that block is skipped) and a virtual BlockBreakEvent for the harvest, so claim and logging plugins can veto.

spade-grass

Converts every DIRT/GRASS_BLOCK in an n × n area around context.block() to FARMLAND. No virtual event is fired — bypass claim plugins by design (use sparingly).

links: spade: type: spade-grass range: 1

Field

Type

Description

range

PlaceholderWrapper<Integer>

Half-extent of the area to till.

Diagnostics

debug-context

Logs the current PipelineContext summary to the server console: slot, player name, drops list, vanilla experience, dirty, and replaceItemStack flags. No configurable fields. Useful while authoring a new pipeline — remove it before going live (every fired event logs).

links: debug: type: debug-context
Last modified: 25 July 2026