Quests & Goals
A quest blueprint is one YAML file under blueprints/: a display item, a goal describing the gameplay trigger that advances it, and a goal-value range the concrete target is rolled in. Generation turns blueprints into QuestInstances for the current month; as players play, EventService routes events into QuestService.progress, which advances every matching active quest and credits points on completion.
See Developer API for adding a goal type.
Blueprint format
One file, one blueprint — sub-folders are walked, so blueprints/daily/wheat.yml and blueprints/weekly/warden.yml are just organisation.
Field | Type | Required | Description |
|---|---|---|---|
| String | Yes | Unique, stable identifier. It feeds the seed that rolls the quest's target, so renaming it re-rolls that quest. Duplicates are skipped with a warning. |
|
| Yes |
|
|
| Yes | The menu item. Standard AstralCore item shape ( |
| Goal object | Yes |
|
|
| No | Inclusive range the target is rolled in. Omitted (or absent) means a target of |
|
| No | Requirements that must pass for an event to count — see below. |
| Season or date | No | First season this quest may be dealt in. |
| Season or date | No | Last season this quest may be dealt in. |
type
QuestType has two values, DAILY and WEEKLY. The type decides which categories entry the quest follows — how many are dealt per batch, how often, how long they live, and how many points completing one awards. It is not a difficulty label: a DAILY blueprint is simply drawn from the daily pool.
goal-value
An inclusive range, not a value: every month each dealt quest rolls its own target inside it, from the generation seed, so every server rolls the same number. maximum <= minimum pins the target to minimum. See Seasons & Generation § Targets for the rounding rule value-step applies.
completion-requirements
An optional PaperRequirementList — the same grammar as anywhere else in AstralCore.
It is evaluated per event, not once at completion: an event whose goal matched is dropped when the list fails, so the quest simply does not advance there. Progress already earned is never rolled back, and the player can advance the same quest later somewhere the requirements pass. The list runs last — after the goal has recognised the event — because running configured requirements is far more expensive than letting the goal reject the event. A failing requirement list logs an error and counts as not satisfied.
available-from/available-until
The window that decides whether a blueprint enters a season's draw at all. Both bounds are inclusive and both are optional (available-until alone retires a quest after that season; available-from alone introduces one).
The window is read a season at a time, against the month being generated — not against today's date. A season deals its quests once, from a pool that has to be identical on every server for the whole month, so a quest cannot join or leave a season halfway through. Accepted forms are a season (2026-09) or a full date (2026-09-01), a date being folded onto the season that contains it. A malformed value throws at load time, naming the blueprint. Both bounds also feed the blueprint fingerprint.
Display placeholders
When a quest's display item is rendered for a viewer, the QuestInstance registers itself in the container, so the blueprint's name/lore can describe that player's copy of the quest:
Placeholder | Resolves to |
|---|---|
| The viewer's current progress on this quest. |
| The quest's rolled target. |
| Any quest sub-key — |
%required%/%total% are the short names the blueprint files have always used; they are the same two numbers as %quest_progress% and %quest_requiredAmount%.
Progress
EventService registers one listener per entry of EventAdapterRegistry at MONITOR priority. An event that is Cancellable and cancelled is dropped. The matching adapter pulls the acting player — and, when the event carries them, the block, item stack or entity — into a QuestGoalContext; an adapter returning null (no player behind the event) drops it too.
QuestService.progress then walks every quest of the month and, for each one that is active and not already completed, hands the context to its goal. A goal returns a QuestGoalResult in one of four shapes:
Result | Meaning |
|---|---|
| The goal does not recognise this event. Nothing happens. |
| Adds |
| Adds |
| Raises progress to |
When progress reaches the target, the quest type's reward points are credited and quest-completed is sent. Completion is derived from progress, so there is no separate "claimed quest" state: a completed quest just sits at its target.
Goal catalogue
Twenty-four goal types, registered in QuestGoalRegistry. A type that is not in this list fails the blueprint file with Unknown QuestGoal type.
In every goal below, an empty or omitted filter list accepts everything.
Block goals
block-break
Breaking blocks. Counts blocks, not swings.
Field | Type | Description |
|---|---|---|
|
| The blocks that count; empty for any. |
Two checks keep it from being farmed: a block AstralCore's BlockService reports as wasPlacedByPlayer never counts, and an Ageable block only counts at maximum age — so replanted or unripe crops are ignored. The exception is the column crops (CACTUS, SUGAR_CANE, BAMBOO, SWEET_BERRY_BUSH), which are broken mid-growth by design: for those the whole column counts, walking upward from the broken block and adding every consecutive block of the same material in one go.
block-break-distinct
Breaking a number of different kinds of blocks. A thousand stone blocks only ever count once.
Field | Type | Description |
|---|---|---|
|
| The blocks that count; empty for any. |
Same player-placed and maturity checks as block-break. The distinct key is the block's material.
block-place
Placing blocks.
Field | Type | Description |
|---|---|---|
|
| The blocks that count; empty for any. |
The held item and the block it becomes often differ (seeds become wheat, a water bucket becomes water), so the filter matches if either side matches.
block-harvest
Harvesting a block without breaking it — right-clicking a grown sweet berry bush, a cave vine, …
Field | Type | Description |
|---|---|---|
|
| The harvested block that counts; empty for any. |
The filter is matched on the block, not on what dropped out of it: a quest names the plant to look for, and the same item can come from more than one. Progress counts the items the block gave, not the number of harvests — picking six berries at once is worth six.
block-brush
Brushing suspicious sand or gravel.
Field | Type | Description |
|---|---|---|
|
| The brushable blocks that count; empty for any. |
Requires a main-hand right click with a BRUSH on a block whose block data is Brushable. Worth 1.
Entity goals
entity-kill
Killing mobs.
Field | Type | Description |
|---|---|---|
|
| The mobs that count; empty for any. |
| boolean |
|
The kill must be credited to the player: the damage source's causing entity, so a bow or a thrown potion counts as the shooter's kill.
entity-kill-distinct
Killing a number of different species. Farming zombies only ever counts once.
Field | Type | Description |
|---|---|---|
|
| The mobs that count; empty for any. |
The distinct key is the entity type.
entity-multi-kill
Killing several mobs of the same kind in a single swing.
Field | Type | Description |
|---|---|---|
|
| The mobs that count; empty for any. |
|
| What the player must be holding in their main hand; empty for anything. |
Driven by PlayerMultiKillEvent, which MultiKillService raises when a player kills several mobs of one type within a single tick — a sweeping attack, an explosion, a piercing arrow. The target is how many mobs the swing has to take down, so progress keeps the best swing so far: three swings of four do not add up to a swing of twelve.
entity-breed
Breeding animals. Worth 1 per breeding.
Field | Type | Description |
|---|---|---|
|
| The animals that count; empty for any. |
Only breedings a player caused count — villagers and animals fed by a dispenser have no breeder.
entity-breed-distinct
Breeding a number of different species. A cow farm only ever counts once.
Field | Type | Description |
|---|---|---|
|
| The animals that count; empty for any. |
entity-leash
Putting a lead on an entity. Worth 1.
Field | Type | Description |
|---|---|---|
|
| The entities that count; empty for any. |
entity-fertilize-egg
Breeding egg-laying animals — turtles, sniffers. They lay an egg instead of spawning a baby and therefore never fire the ordinary breed event, which is why they need their own goal.
Field | Type | Description |
|---|---|---|
|
| Matched against the mother; empty for any. |
Item goals
item-craft
Crafting items.
Field | Type | Description |
|---|---|---|
|
| The crafting results that count; empty for any. |
Counts items, not clicks: shift-clicking crafts the recipe as many times as the smallest ingredient stack allows, and all of it counts.
item-enchant
Enchanting an item at an enchantment table.
Field | Type | Description |
|---|---|---|
|
| The items that count; empty for any. |
|
| The enchantments that count; empty for any. |
| int | The level a matching enchantment must reach. |
Worth 1 when at least one enchantment being applied matches the filter and reaches minimum-level. The values shown on the tooltip are the enchantments when the list is set, otherwise the materials — the enchantment is what the quest is about, the item only narrows it down.
item-fish
Fishing something up.
Field | Type | Description |
|---|---|---|
|
| The catches that count; empty for any. |
Only a CAUGHT_FISH catch counts, and progress is the caught stack's amount.
Player goals
player-travel
Travelling a distance in blocks, on foot.
Field | Type | Description |
|---|---|---|
| boolean | Whether flying and gliding count. Default |
Only actual position changes count, and a change of world (a teleport) never does. Fractions of a block are carried over per player, so a hundred tiny steps still credit their blocks; that remainder is runtime state, held per goal instance and expiring ten minutes after it was last touched.
player-biome
Exploring a number of different biomes.
Field | Type | Description |
|---|---|---|
|
| The biomes that count; empty for any. |
Only checked when the player crosses a block boundary. The distinct key is the biome's namespaced key, so walking back and forth across the same one counts once.
player-potion
Holding a set of potion effects at the same time, each at least at the given level.
Field | Type | Description |
|---|---|---|
|
| Effect → the level it must reach, |
Checked whenever an effect is added to the player. The effect being added is read off the event — it is not applied to the player yet at that point — and every other required effect off the player. Worth 1 each time the whole set is satisfied.
player-vote
Voting for the server. Worth 1 per vote; no fields.
player-loot
Opening a generated loot container — a dungeon chest, a shipwreck, …
Field | Type | Description |
|---|---|---|
|
| Namespaced loot-table keys that count; empty for any. |
Loot generated by a plugin never counts. Worth 1.
player-vault
Unlocking a trial chamber vault.
Field | Type | Description |
|---|---|---|
| boolean | Which kind of vault counts. Matched exactly — |
Counted the moment the vault enters its UNLOCKING state. Worth 1.
player-scroll
Completing an AstralScrolls scroll.
Field | Type | Description |
|---|---|---|
|
| Scroll rarity ids that count; empty for any. |
Worth 1.
player-tower
Getting through the AstralTower tower.
Field | Type | Description |
|---|---|---|
| int | The room the run has to reach for it to count. A finished run below it is ignored. |
Worth 1 per qualifying run.
Shop goals
shop-sell
Selling items to the AstralShop server shop.
Field | Type | Description |
|---|---|---|
|
| Shop ids that count; empty for any. |
|
| Shop item ids that count; empty for any. |
Progress counts items, not sales: selling a stack of sixty-four is worth sixty-four.
Further reading
Seasons & Generation — how blueprints become the month's quests.
Placeholders — everything a quest exposes to a menu.
Developer API — the goal framework and the events consumed.