Astral Realms Documentation Help

AstralItems Overview

AstralItems is the custom-item framework for the AstralRealms network. Server operators define items in YAML — appearance, rarity, version, optional metadata, optional default item data, and one or more behaviour pipelines — and the plugin attaches those behaviours to live Bukkit events without writing a single line of Java.

A pipeline reads like a small program: a head captures a Bukkit event, a chain of links transforms the captured state (drops, XP, durability, the player's inventory, the item's own data bag), and one or more tails apply the side effects (drop on the ground, magnet to inventory, log to console).

What it does

  • Blueprints describe an item: a display, a rarity, a semver version, optional metadata, optional default-data, and a list of pipelines.

  • Rarities are top-level objects with their own id and display. The id becomes the namespace of every blueprint that references them — rarity.id() + ":" + blueprint.id is the item's Key.

  • Pipelines are declarative event handlers. Heads, chain links, and tails are all looked up by type ID in a central registry — adding a new behaviour means adding a new YAML node, not a new plugin.

  • Item data is a pluggable typed bag persisted alongside the item — built-in adapters cover XP/level (scalable), a stored block material (stored-material), and a stored entity (stored-entity). Plugins can register their own adapters via ItemDataRegistry.

  • Item stats (experimental) — a blueprint can declare min/max numeric stats that roll once per item and persist on the stack; see Item Stats. Player application through AstralStats is not yet wired up.

  • Item instances carry a UUID, a blueprint reference, the version at creation time, and the data bag, all persisted in the ItemStack PDC under astralrealms:item.

  • Hot upgrade — when the blueprint version bumps, items already in the world rebuild themselves on the next handle (inventory open, chunk load, data load), preserving UUID / damage / unbreakable / enchantments.

  • Custom anvil/items anvil opens a packet-level anvil that fires AnvilResultEvent for every recompute. The plugin's listener uses it to apply enchanted books while honouring the blueprint's available-enchantments whitelist.

  • CraftEngine integration — items are registered as a CraftEngine stack supplier under the astralitems namespace, so any system that reads a CraftEngine key (recipes, shops, menus) will find AstralItems items.

  • Event hijacking — the plugin re-registers existing listeners through its own dispatcher so it can route events to the correct item's pipeline based on the ItemStack involved.

Requirements

Dependency

Required

Notes

Paper 1.21+

Yes

api-version: 1.21

AstralCore

Yes

Plugin framework, registries, item wrappers, menus, actions, requirements, placeholders

AstralSync

Yes

UpgradeListener listens for PlayerDataLoadedEvent to rebuild outdated items on login

CraftEngine

Yes

Item registry, reload events

PacketEvents

Yes

Used by AnvilService for the custom anvil's window protocol

AstralStats

Yes

Player stat framework — declared for the (experimental) item stats system

Java 25

Yes

Compile target — server must run a matching JDK

Architecture at a glance

plugins/AstralItems/ ├── blueprints/ ← YAML item definitions (sub-folders scanned) ├── rarities/ ← YAML rarity definitions ├── menus/ ← AstralCore menus, including the built-in `items-rarities` menu ├── messages.yml ├── config.yml ← plugin config (e.g. physics-ignored) └── duplication.yml ← duplication-watchdog config
Bukkit event ──► EventService dummy listener │ ▼ EventProcessor │ ┌─────┴────────┐ ▼ ▼ preChecks postChecks (by blueprint key) │ ▼ EventContextAdapter builds PipelineContext (+ extras) │ ▼ Head ─► ChainLink ─► ChainLink ─► … ─► Tail ─► Tail │ ▼ Persist instance / replace stack if dirty / replaceItemStack

Service

Responsibility

RarityService

Loads rarities/*.yml, indexes by id.

BlueprintService

Loads blueprints/**/*.yml, indexes by Key, calls PipelineService.initialize() on every reload.

PipelineService

Type-ID registry for heads / links / tails; wires every blueprint pipeline to the right Bukkit event.

EventService

Owns one dummy listener per (EventPriority, Event) pair; dispatches into the right EventNode. Exposes fireVirtualEvent(Event) for AoE plugins.

ItemService

Reads / writes the item PDC; exposes fromItemStack, isCustomItem, upgrade, upgradeInventory, updateLore.

AnvilService

Owns the packet-level custom anvil window; fires AnvilResultEvent.

DuplicationService

Scans inventories for duplicated unique items / over-threshold stackables and alerts via a Discord webhook (production only). See Duplication detection.

ItemFactory

Static utility that builds an ItemStack from a blueprint or an ItemInstance.

AstralItemsStackSupplier

Registers the astralitems namespace with CraftEngine's item registry.

MenuContainer (AstralCore)

Loads menus/*.yml; the built-in items-rarities menu is opened by /items.

Listener

Trigger

CraftEngineListener

Reloads blueprints when CraftEngine reloads.

HandListener

Fires the custom HandEquipEvent on hand swaps, item-frame / armour-stand interaction, and quit.

ArmorListener

Fires ArmorEquipEvent/ArmorUnEquipEvent off Paper's PlayerArmorChangeEvent.

DurabilityListener

Caps damage at max - 1 for blueprints flagged destroyable: false.

DuplicationWatchDogListener

Runs the duplication scan on PlayerDataLoadedEvent and InventoryOpenEvent.

InventoryListener

Blocks vanilla enchanting / smithing / grindstone / loom recipes from operating on custom items.

UpgradeListener

Rebuilds outdated items on PlayerDataLoadedEvent, InventoryOpenEvent, and ChunkLoadEvent.

AnvilListener

Intercepts vanilla anvil right-clicks and reroutes to AnvilService; layers enchanted-book and over-level rules onto AnvilResultEvent.

AnvilPacketListener

PacketEvents listener routing anvil window clicks back into AnvilService.

Item data is persisted directly on the ItemStack via ItemInstanceDataType — see Developer API for the PDC layout and Item Data for the typed data bag.

Duplication detection

On production servers, DuplicationService watches for item duplication and posts a Discord alert — it is a detection / alerting tool and does not remove or block anything. It scans when a player's data loads and when they open an inventory (AstralCore menu inventories are skipped), flagging:

  • the same unique custom-item UUID appearing in more than one stack, and

  • configured stackable items whose total quantity crosses a threshold.

It runs only when the server environment is PRODUCTION, and players with the duplication.bypass permission are skipped.

Configure it in duplication.yml:

# duplication.yml webhook-url: "https://discord.com/api/webhooks/..." # alerts post here — override per deployment items-warnings: "crates:end": 20 # alert when a player holds 20+ of this item

Key

Type

Description

webhook-url

String

Discord webhook the alerts post to.

items-warnings

Map<Key, Integer>

Per-item quantity thresholds.

duplication.yml is re-read by /items reload.

Last modified: 25 July 2026