Astral Realms Documentation Help

Developer API

AstralItems exposes its services through AstralItems.get() and persists item identity directly on the ItemStack via PDC. Other plugins can build items, resolve items back to their blueprint, register custom item data, listen to HandEquipEvent/AnvilResultEvent, or open the custom anvil for a player.

Maven coordinates

<dependency> <groupId>com.astralrealms</groupId> <artifactId>items</artifactId> <version>2.0-SNAPSHOT</version> <scope>provided</scope> </dependency>

Repository: https://maven.astralrealms.fr/repository/maven-public/.

Accessing services

import com.astralrealms.items.AstralItems; AstralItems plugin = AstralItems.get(); RarityService rarities = plugin.rarities(); BlueprintService blueprints = plugin.blueprints(); PipelineService pipelines = plugin.pipelines(); EventService events = plugin.events(); AnvilService anvil = plugin.anvil(); ItemService items = plugin.items(); MenuContainer menus = plugin.menus();

Getter

Type

Use

plugin.rarities()

RarityService

Look up rarities, list all loaded rarities.

plugin.blueprints()

BlueprintService

Look up blueprints by Key, list by rarity, list every loaded blueprint.

plugin.pipelines()

PipelineService

Look up the class behind a type: string.

plugin.events()

EventService

Fire a virtual event through the dispatcher (advanced).

plugin.anvil()

AnvilService

Open the custom anvil for a player.

plugin.items()

ItemService

Read / write item PDC, test for custom items, upgrade outdated stacks.

plugin.menus()

MenuContainer

AstralCore menu container — opens the plugin's menus/*.yml.

RarityService

Method

Returns

Use

findByNamespace(String id)

Optional<ItemRarity>

Resolve a rarity by id. (Method name is a hold-over — id is the actual lookup key.)

all()

Collection<ItemRarity>

Iterate every loaded rarity (read-only).

load()

void

Re-scan rarities/ from disk.

BlueprintService

Method

Returns

Use

findByKey(Key key)

Optional<ItemBlueprint>

Resolve a blueprint by its composite Key (<rarity-id>:<id>).

findByRarity(String id)

List<ItemBlueprint>

Every blueprint registered under a given rarity id.

keys()

Collection<Key>

Every blueprint key currently registered.

all()

Set<ItemBlueprint>

Every loaded blueprint (read-only).

load()

void

Re-scan blueprints/ from disk and call PipelineService.initialize().

import net.kyori.adventure.key.Key; plugin.blueprints().findByKey(Key.key("abyss", "hammer")) .ifPresent(bp -> getLogger().info("Found " + bp.id()));

PipelineService

Method

Returns

Use

findComponentTypeById(String id)

Optional<Class<? extends PipelineComponent>>

Resolve a pipeline type: string to the implementing class.

initialize()

void

Unregister every dummy listener and rewire all pipelines. Called automatically by BlueprintService.load.

ItemService

Method

Returns

Use

fromItemStack(ItemStack stack)

Optional<ItemInstance>

Read the astralrealms:item PDC value off any item.

updateItemStack(ItemStack stack, ItemInstance instance)

boolean

Re-write the PDC with a new instance and refresh the lore. Returns false if the stack is air or has no meta.

updateLore(ItemStack stack, ItemInstance instance)

boolean

Re-render the lore using the blueprint's lore template + current instance state (enchantments, unbreakable, repairable status).

isCustomItem(ItemStack stack)

boolean

Cheap PDC presence check.

cannotBeUsed(ItemStack stack)

boolean

true when a non-destroyable custom item is one tick away from breaking — used by DurabilityListener to short-circuit interactions.

upgrade(ItemStack stack)

Optional<ItemStack>

Rebuild the stack from the current blueprint if its stored version is older. Preserves UUID, damage, unbreakable, amount, and whitelisted enchantments.

upgradeInventory(Inventory inv)

boolean

Calls upgrade on every slot. Returns true if any slot was replaced.

plugin.items().fromItemStack(player.getInventory().getItemInMainHand()) .ifPresent(instance -> { getLogger().info(instance.uniqueId() + " -- " + instance.blueprint().id() + " v" + instance.version()); });

The PDC key is exposed as ItemService.ITEM_KEY for callers that need to write the container directly (useful from PersistentDataType implementations):

ItemService.ITEM_KEY; // namespace = "astralrealms", key = "item"

AnvilService

Method

Returns

Use

open(Player player)

void

Open the custom packet-level anvil window for the given player.

See Anvil for the recompute pipeline and the AnvilResultEvent hook.

Item upgrade

ItemService.upgrade(ItemStack) is the centrepiece of the version-bump migration story: when a player handles a stack whose stored blueprint version is older than the current blueprint version, upgrade rebuilds the display ItemStack from the new blueprint and transfers:

  • The ItemInstance UUID and item data bag.

  • Enchantments — clamped against metadata.available-enchantments.

  • Damage value.

  • Unbreakable flag.

  • Stack amount.

The UpgradeListener invokes it on PlayerDataLoadedEvent (from AstralSync), InventoryOpenEvent, and ChunkLoadEvent (for item frames, containers, and shelves in newly loaded chunks).

Plugins that move items between worlds (e.g. cross-server transfer, bank withdraw) can call upgrade explicitly to ensure the item is refreshed before it lands in the destination inventory.

Creating an item

ItemFactory is a static utility that produces a ready-to-use ItemStack from a blueprint or an explicit ItemInstance. Use it to grant items from custom commands, loot tables, quests, etc.

import com.astralrealms.items.factory.ItemFactory; import com.astralrealms.items.model.blueprint.ItemBlueprint; import net.kyori.adventure.key.Key; ItemBlueprint blueprint = plugin.blueprints() .findByKey(Key.key("abyss", "hammer")) .orElseThrow(); ItemStack stack = ItemFactory.make(blueprint); player.getInventory().addItem(stack);

ItemFactory.make(blueprint) generates a fresh UUID, copies the blueprint's version onto the instance, copies the blueprint's default-data into the instance, builds the display ItemStack via the blueprint's ItemStackWrapper, applies metadata.maxStackSize (when > 0), serialises the ItemInstance into the PDC, and refreshes the lore.

For more control — for example, restoring an item with an explicit UUID or pre-populated data — use the explicit form:

import com.astralrealms.items.model.item.ItemInstance; import com.astralrealms.items.model.data.ScalableItemData; import com.astralrealms.items.model.data.adapter.ScalableItemDataAdapter; import java.util.HashMap; import java.util.UUID; ItemInstance instance = new ItemInstance(UUID.randomUUID(), blueprint, blueprint.version(), new HashMap<>()); instance.setData(ScalableItemDataAdapter.KEY, new ScalableItemData(5, 0)); // start at level 5 ItemStack stack = ItemFactory.make(instance);

ItemFactory.makeInstance(blueprint) builds an ItemInstance without serialising it to an ItemStack — useful when the caller has its own ItemStack to attach the PDC to.

ItemStack PDC layout

Every AstralItems item carries one PDC entry:

Key

Type

Value

astralrealms:item

ItemInstanceDataType

ItemInstance record

ItemInstanceDataType serialises into a nested PersistentDataContainer with five sub-keys:

Sub-key

Type

Value

astralitems:unique_id

UUIDDataType

Per-item UUID.

astralitems:blueprint

ItemBlueprintDataType

Blueprint Key (string Key.asMinimalString()). On read, looked up through BlueprintService.findByKey.

astralitems:version

ItemVersionDataType

Semver string major.minor.patch. On read, parsed by ItemVersion.parse.

astralitems:data

nested PDC

Typed item-data bag — each entry serialised by its registered ItemDataAdapter.

astralitems:stats

BYTE_ARRAY

Rolled item stats, written only when the item has stats.

CraftEngine stack supplier

The plugin registers itself as a CraftEngine stack supplier under the namespace astralitems:

CommonRegistries.itemStackSuppliers().register("astralitems", new AstralItemsStackSupplier(this));

That means any AstralCore call site that accepts a ce:/craftengine: key also accepts an astralitems: key. The key format is astralitems:<rarity-id>/<blueprint-id>. The supplier:

  • get(String key) — builds an ItemStack from the blueprint behind the key.

  • completions() — every blueprint key, for tab completion.

  • keyOf(ItemStack) — extracts the blueprint Key from a stack's PDC. Lets other plugins normalise an AstralItems stack back to a registry key.

# anywhere an item supplier key is accepted actions: - "[give-item] astralitems:abyss/hammer"

Reacting to events

The plugin fires four custom events — see Events:

For most reactive behaviour, prefer authoring a pipeline on the blueprint rather than writing a Bukkit listener.

Firing a virtual event

EventService.fireVirtualEvent(Event) reroutes an event through the dispatcher without going through Bukkit's listener pipeline. It returns true if any hooked listener cancelled the event.

This is the mechanism the hammer, fell-tree, replant-crops, break-leaves, and build-wand links use to ask other plugins (claim, logging, protection) about every block they would break or place in their AoE. Only use it when you need that "ask before acting" semantics — calling Bukkit's normal dispatcher is the right choice everywhere else.

BlockBreakEvent virtual = new BlockBreakEvent(block, player); boolean cancelled = plugin.events().fireVirtualEvent(virtual); if (!cancelled) { // proceed with the block break }

Registering custom item data

Custom item data adapters extend the typed bag stored alongside each instance. See Item Data for the ItemDataAdapter<T> contract and registration walkthrough.

Last modified: 25 July 2026