Astral Realms Documentation Help

Developer API

AstralCollections exposes its services through AstralCollections.get() and persists player progress as an AstralSync data holder. Other plugins can hook in to add custom triggers, read progress, or grant collection entries programmatically.

Maven coordinates

<dependency> <groupId>com.astralrealms</groupId> <artifactId>collections</artifactId> <version>1.0-SNAPSHOT</version> <scope>provided</scope> </dependency>

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

Accessing services

import com.astralrealms.collections.AstralCollections; AstralCollections plugin = AstralCollections.get(); BlueprintService blueprints = plugin.blueprints(); CollectionService collections = plugin.collections();

BlueprintService

Method

Returns

Use

findById(String id)

Optional<CollectionBlueprint>

Look up a blueprint by its YAML id.

findByItem(ItemStack item)

Optional<CollectionEntry>

Resolve an item to the entry it belongs to.

all()

Collection<CollectionBlueprint>

Iterate every loaded blueprint (read-only).

load()

void

Re-scan blueprints/ from disk.

plugin.blueprints().findById("starter") .ifPresent(bp -> getLogger().info("Starter has " + bp.entries().size() + " entries."));

CollectionService

Method

Returns

Use

findByItem(ItemStack)

Optional<CollectionEntry>

Same as BlueprintService.findByItem (convenience).

markDiscovered(Player, CollectionEntry)

void

Force a discovery — sends the entry-discovered message and fires completion actions if appropriate.

CollectionEntry entry = plugin.collections().findByItem(item).orElse(null); if (entry != null) { plugin.collections().markDiscovered(player, entry); }

markDiscovered is idempotent — calling it twice for the same entry only triggers the message and completion logic on the first call.

Reading player progress

Progress is persisted by AstralSync under the collections:playerdata key. Pull it via SyncAPI:

import com.astralrealms.collections.storage.CollectionPlayerData; import com.astralrealms.sync.SyncAPI; SyncAPI.findData(player.getUniqueId(), CollectionPlayerData.class) .ifPresent(data -> { int progress = data.progress("starter"); boolean completed = data.completedCollections().contains("starter"); });

CollectionPlayerData

Field

Type

Description

completedEntries

Multimap<String, String>

collection ID → set of discovered entry IDs

completedCollections

Collection<String>

IDs of fully completed collections

Method

Returns

Description

progress(String collectionId)

int

Number of entries discovered in that collection.

addEntry(String collectionId, String entryId)

boolean

Add an entry; returns true only if it was new.

Defining a custom discovery trigger

If your plugin grants items in a way AstralCollections doesn't already see (custom event, gameplay mechanic, etc.), wire it up like this:

public class TreasureChestListener implements Listener { private final AstralCollections collections; public TreasureChestListener(AstralCollections collections) { this.collections = collections; } @EventHandler public void onLoot(MyTreasureLootEvent event) { for (ItemStack stack : event.getLoot()) { collections.collections() .findByItem(stack) .ifPresent(entry -> collections.collections().markDiscovered(event.getPlayer(), entry)); } } }

Placeholders

CollectionBlueprint and CollectionEntry both implement ComplexPlaceholder, so they slot directly into any AstralCore placeholder container. See Placeholders for the available keys.

To use a blueprint as a placeholder root manually:

PlaceholderContainer container = AstralPaperAPI.createPlaceholderContainer(player); container.registerDirect("collection", plugin.blueprints().findById("starter").orElseThrow()); String resolved = AstralPaperAPI.replacePlaceholder( "Progress: %collection_progress% / %collection_total%", container );
Last modified: 25 July 2026