Developer API
AstralFarmPass exposes its services as getters on the main plugin instance, keeps per-player state in an AstralSync snapshot, fires one custom event, and has one real extension point — the quest-goal registry.
Maven coordinates
Repository: https://maven.astralrealms.fr/repository/maven-public/.
Plugin services
Getter | Type | Use |
|---|---|---|
|
| Look up loaded blueprints, and the load fingerprint. |
|
| The month's quests, the current season id, and recording progress. |
|
| Internal — owns the generated listeners; unloaded on disable. |
|
| Internal — batches same-tick kills into |
|
| The plugin's menus ( |
|
| Zone, salt, |
|
| The reward ladder; |
There is no database and no repository layer — see Seasons & Generation.
QuestService
Method | Returns | Use |
|---|---|---|
|
| The current season id ( |
|
| Every non-expired quest of that type, including the still-locked ones. |
|
| Only the unlocked, non-expired ones. |
|
| Derives an arbitrary month's quests without touching the cached one — useful to preview next month. Returns an empty list if the type has no category or no available blueprint. |
|
| Runs a context against every active quest, recording progress and awarding points. |
The three read methods and progress are synchronized and re-check the month boundary on entry, so a rollover is picked up by the first call that crosses it.
BlueprintService
Method | Returns | Use |
|---|---|---|
|
| Look a blueprint up by id. |
|
| Every blueprint of a type, in sorted id order. |
|
| Every loaded blueprint, in sorted id order. |
|
| 12-character hash of everything that influences generation — see Fingerprint. |
Iteration order is deliberately sorted: generation walks these collections and must do so identically on every server.
PlayerMultiKillEvent
Fully qualified name: com.astralrealms.farmpass.model.event.PlayerMultiKillEvent (extends AstralCore's AbstractEvent). Not cancellable — it is a notification.
Fired by MultiKillService once a player has killed several mobs of the same kind within a single tick, which in practice means a single swing: a sweeping attack, an explosion, a piercing arrow. Deaths are batched per player per tick and flushed on the next one, when the whole swing has resolved; a batch that ends up with a single kill fires nothing. Accessors are fluent (Lombok @Accessors(fluent = true)).
Fields
Field | Type | Description |
|---|---|---|
|
| The killer, resolved from the damage source's causing entity. |
|
| The species killed — one event per species in the batch. |
|
| How many of them died in that tick. Always |
|
| A clone of what the player held in their main hand when the batch opened, so a quest can ask for a specific weapon. |
Example listener
It is consumed internally by the entity-multi-kill goal.
Extending the goal framework
A goal is a @ConfigSerializable class implementing QuestGoal:
handlereceives the adapted event and returns what it made of it.values()is what the quest tooltip lists — the blocks, mobs or biomes the goal watches. An empty collection means "anything counts", which a description says better than a list would. VanillaKeyed/Translatablevalues render client-side translated; see%value_…%.
QuestGoalContext
Component | Type | Populated when |
|---|---|---|
|
| Always — an adapter that cannot find a player drops the event instead. |
|
| Always: the original Bukkit event, which goals pattern-match on. |
|
| Block break/place/harvest, interact, enchant (the table), vault. |
|
| Block place (the held item), craft (the result), enchant (the item), interact, scroll. |
|
| Kill, breed, fertilize-egg (the mother), leash, potion (the player), fish (the catch), loot. |
QuestGoalResult
Factory | Effect |
|---|---|
| The goal does not recognise this event. |
| Adds |
| Adds |
| Raises progress to |
Registering
QuestGoalRegistry and EventAdapterRegistry are both static, immutable maps compiled into the plugin: a new goal type, and the event adapter it needs if that event is not listened to yet, are added by editing those two classes and rebuilding. There is no runtime registration hook — an event missing from EventAdapterRegistry is an event no goal will ever see.
QuestGoalTypeSerializer resolves goal.type through QuestGoalRegistry and then deserializes the rest of the goal node into that class, so a record's components become the block's kebab-cased YAML keys. Serialization back to YAML is deliberately unsupported.
Player data: FarmPassPlayerData
The AstralSync snapshot behind every player's pass, keyed farmpass:data (FarmPassSnapshotAdapter).
Member | Type | Meaning |
|---|---|---|
|
| The month this data belongs to. |
|
| Progress per quest id. |
|
| Distinct keys already counted per quest. |
|
|
|
|
| Season points. |
|
| Current progress on a quest. |
|
| Whether it reached its target. |
|
| Adds progress, capped at the target; returns the new total. |
|
| Raises progress to a value if it beats the current one. |
|
| Records a distinct key; |
|
| Updates the points. |
|
| Re-stamps the season and clears everything else. |
Quests themselves are not stored: every server re-generates them identically, so only what the player did with them travels. That is also why nothing has to be reconciled on a server switch — the adapter's apply only compares the stamped season with the current one, and resets the data when they differ.
Consumed upstream events
EventAdapterRegistry maps 20 event classes to the adapter that pulls a player out of them. Listeners are registered from that map alone, at MONITOR priority, through ReflectionUtils.forceRegisterEvent — a lightweight RegisteredListener per event rather than a reflective @EventHandler per type. Cancelled events never reach a goal.
Source | Events |
|---|---|
Bukkit — blocks |
|
Bukkit — entities |
|
Bukkit — items |
|
Bukkit — players |
|
AstralFarmPass |
|
AstralVote |
|
AstralScrolls |
|
AstralTower-Bridge |
|
AstralShop |
|
Registered action
claim-farmpass-reward — see Rewards. Registered with registerAction, i.e. on the plugin's own registry, so it resolves in AstralFarmPass's configuration only.