Astral Realms Documentation Help

Blueprints & Goals

A blueprint is a scroll's goal plus how likely/how big that goal is per rarity. Blueprints live under blueprints/*.yml (see Configuration) and are deserialized by ScrollBlueprintTypeSerializer.

Schema

blueprints: turtle_hunter: goal: type: "kill" entities: - "minecraft:turtle" requirements: common: chance: 70 min: 10 max: 20 uncommon: chance: 30 min: 21 max: 30

YAML key

Java field

Type

Description

(map key, under blueprints:)

id

String

The blueprint's id — matched against by ScrollDataType (PDC persistence) and ScrollService#findById.

goal

goal

ScrollGoal<?>

The goal this blueprint tracks. type selects which goal class deserializes the rest of the node — see Goal types.

requirements

requirements

Map<String, RequirementValues>

Which rarities this blueprint can be rolled for, keyed by rarity id (must match a key under config.yml's rarities). A blueprint with no entry for a given rarity is never picked for scrolls of that rarity.

Each requirements entry is a RequirementValues:

YAML key

Java field

Type

Description

chance

chance

double

Relative weight in a RandomCollection<ScrollBlueprint> draw for this rarity — not a percentage; weights of every blueprint that has an entry for the rarity are summed and one is drawn proportionally.

min

min

int

Lower bound (inclusive) of the random goal target.

max

max

int

Upper bound (inclusive) of the random goal target.

When ScrollService#build rolls a scroll for a rarity, the target (Scroll#total) is ThreadLocalRandom.nextInt(min, max + 1).

Goal types

Registered in GoalService's constructor. The type string under goal: is the documentation id, not the Java class name.

type

Class

Underlying event

Config fields

kill

KillEntitiesGoal

EntityDeathEvent

entities: List<EntityType>

break-block

BreakBlockGoal

BlockBreakEvent

materials: List<Material>

place-block

PlaceBlockGoal

BlockPlaceEvent

materials: List<Material>

craft

CraftGoal

CraftItemEvent

materials: List<Material>

enchant

EnchantGoal

EnchantItemEvent

(none)

travel

TravelGoal

PlayerMoveEvent

(none)

harvest

HarvestGoal

PlayerHarvestBlockEvent

materials: List<Material>

fishing

FishingGoal

PlayerFishEvent

fishes: List<Material>

Every goal advances scroll progress via GoalListener, which listens to all eight events at EventPriority.MONITOR with ignoreCancelled = true and calls ScrollService#update(player, GoalClass, event) — that call is a no-op unless the player's scroll cache currently has an incomplete scroll whose blueprint's goal is exactly that class.

kill

KillEntitiesGoal(List<EntityType> entities). On EntityDeathEvent, adds 1 progress if event.getEntityType() is in entities and the killer (getDamageSource().getCausingEntity()) is a Player.

break-block

BreakBlockGoal(List<Material> materials). On BlockBreakEvent, adds 1 progress per block broken whose material is in materials. Three extra rules:

  • Player-placed guard. GoalListener only forwards a BlockBreakEvent to BreakBlockGoal if BlockService#wasPlacedByPlayer returns false for the broken block — breaking a block a player placed never counts toward a break-block goal.

  • Growth check. For an Ageable block (crops) not fully grown (age < maximumAge), the break is ignored unless the material is one of SWEET_BERRY_BUSH, CACTUS, SUGAR_CANE, or BAMBOO (the stackable-column materials).

  • Column bonus. For those same stackable materials, breaking the bottom block of a column also credits 1 progress for every additional block of the same material stacked directly above it (so breaking the base of a 4-tall sugar cane column adds 4 progress in one break, not 1).

place-block

PlaceBlockGoal(List<Material> materials). On BlockPlaceEvent, adds 1 progress if event.getItemInHand().getType() is in materials.

craft

CraftGoal(List<Material> materials). On CraftItemEvent, adds 1 progress if the recipe's result material (event.getRecipe().getResult().getType()) is in materials.

enchant

EnchantGoal() — no config fields. On EnchantItemEvent, always adds 1 progress (any enchant counts).

travel

TravelGoal() — no config fields. On PlayerMoveEvent, adds (int) from.distance(to) progress — truncated block-distance moved since the last tracked position. GoalListener only forwards the event if hasChangedBlock() is true and at least 500ms have passed since the player's last travel update (per-player debounce, independent of any scroll state).

harvest

HarvestGoal(List<Material> materials). On PlayerHarvestBlockEvent, adds 1 progress if any of event.getItemsHarvested() has a type in materials.

fishing

FishingGoal(List<Material> fishes). On PlayerFishEvent, adds 1 progress if the event state is CAUGHT_FISH, the caught entity is an Item, and its ItemStack material is in fishes.

%scroll_context%/%scroll_type%

Every goal implements name() (a localized label pulled from messages.yml — see Messages) and context() (a Component describing the goal's targets, e.g. a comma-joined, translatable list of materials/entities). Both are exposed as scroll placeholders — %scroll_type% and %scroll_context% respectively — see Placeholders. enchant's context() returns null; travel's returns an empty component.

Last modified: 25 July 2026