Astral Realms Documentation Help

Configuration

AstralCrates reads its configuration through AstralCore's Configurate-backed configuration manager: a single config.yml toggle, a crates/ folder of per-crate definitions, and a messages.yml for the handful of strings the plugin sends. Everything is reloaded together with /crate reload — see Commands.

Installation

  1. Drop AstralCrates-<version>.jar into plugins/.

  2. Install its two hard dependencies — both are declared in plugin.yml under depend, so the server refuses to start AstralCrates without them:

    Dependency

    Why

    AstralCore

    Configuration/menu framework, action & requirement lists, placeholders, the crates item-supplier namespace, ACF command registration.

    AstralHologram

    AstralHologramAPI renders and unregisters the text hologram shown above every crate location.

  3. Start the server once to generate plugins/AstralCrates/config.yml, messages.yml, and a crates/ folder pre-seeded with example.yml.

See Overview for the Paper-1.21+ Vault-block requirement.

config.yml

The entire file is one key:

crates-enabled: true

YAML key

Java field

Type

Default

Description

crates-enabled

cratesEnabled

boolean

true

Global switch for the whole crate system. Deserializes into the MainConfiguration record.

crates-enabled is read in two places at startup and on every reload:

  • AstralCrates#onEnable only registers CrateListener (the block-interaction listener that opens crates) when cratesEnabled() is true. KeyListener (which blocks placing keys as blocks) is unaffected by the flag and always registers.

  • CrateService only touches holograms when the flag is true: load() unregisters and clears the tracked holograms before reloading crates, and createHolograms() returns immediately, doing nothing at all, when the flag is false.

Because the hologram-clearing step in CrateService#load() is itself gated behind cratesEnabled(), flipping crates-enabled from true to false and reloading does not remove holograms that were already registered from a previous enabled state — they stay tracked in memory and are only cleared the next time the flag is true when load() runs again.

With crates-enabled: false, Vault blocks behave like vanilla Vaults again for right-click purposes (no listener intercepts the interaction), but the plugin still loads crate definitions and keeps the crates:<id> item-supplier namespace active.

crates/ folder

One YAML file per crate; the plugin ships a single example, crates/example.yml. The filename doesn't matter — each file deserializes to a CrateConfiguration record whose own id field (not the filename) is what commands, the item-supplier namespace, and CrateService#findById match against.

Loading happens through AstralCore's folder loader:

Set<CrateConfiguration> crates = this.plugin.configurationManager() .loadFolder("crates", CrateConfiguration.class);

CrateService#load() walks every *.yml/*.yaml file directly under plugins/AstralCrates/crates/, deserializes each into a CrateConfiguration, and (when crates-enabled is true) registers a hologram per configured location. This runs once at onEnable and again on every /crate reload, at which point load():

  1. Unregisters and clears every previously-tracked hologram (only if crates-enabled is true).

  2. Clears the in-memory crate set.

  3. Re-reads every file under crates/ and rebuilds both the crate set and the holograms.

See Crate Files for the full per-file YAML shape (key, locations, menu, hologram, rewards, open/win actions).

Reward nodes

Each entry under a crate's rewards map deserializes as a CrateReward through a dedicated Configurate TypeSerializer, CrateRewardTypeSerializer, registered once in onEnable:

this.registerTypeSerializer(CrateReward.class, new CrateRewardTypeSerializer());

The serializer reads the item fields (material, name, lore, …) directly off the reward's own node as an ItemStackWrapper, then pulls chance (double), actions (PaperActionList), and the optional requirements (PaperRequirementList) from sibling keys on that same node — which is why a reward entry in example.yml mixes item fields and chance/actions flatly in one mapping rather than nesting the item under its own key. Serialization (writing a CrateReward back out) is intentionally unsupported and throws.

messages.yml

Every player-facing string is a case of the CratesMessages enum, loaded from messages.yml one YAML key per enum constant (kebab-cased, e.g. KEY_NEEDEDkey-needed):

Key

Shipped text

Placeholders

Sent when

key-needed

<warning>Vous devez avoir une <#26d971>%item_name% <#ffd60a>pour ouvrir cette caisse !

%item_name% — the crate's key item name

Player right-clicks a crate block without holding a valid key for it (CrateListener#onInteract).

no-rewards

<error>Il n'y a pas récompense défini. Veuillez réessayer plus tard.

none

The reward-picker (CrateOpenMenu) has no eligible reward to award — its onWin callback fires with null, and CrateListener sends this message and hands the crate's key back to the player instead of leaving it consumed.

key-given

<success>Vous avez donné une <#26d971>%item_name% <#80ed99>au joueur <#26d971>%target_name%<#80ed99>.

%item_name%, %target_name%

Defined and loaded, but no code path in the current AstralCrates source sends it — there is no built-in "give key" command (keys are dispensed through AstralCore's /give and the crates:<id> item-supplier namespace instead; see Overview).

%item_name% on key-needed comes from an ItemStackPlaceholder registered over the crate's key ItemStack at send time; it is not a globally-registered placeholder namespace. See Placeholders for the placeholders that are available for use inside crate configs (%crate_*%, %reward_*%).

Load order & reloading

AstralCrates#loadConfiguration() runs once at onEnable and again on every /crate reload (crates.command.reload), always in this order:

  1. config.ymlMainConfiguration.

  2. crates/CrateService#load() (clears and rebuilds the crate set and holograms, as described above).

  3. MenusMenuContainer#load().

  4. messages.yml → the CratesMessages enum.

/crate reload wraps this call and reports success or failure back to the command sender; see Commands for the full command reference.

Last modified: 25 July 2026