Astral Realms Documentation Help

Commands

AstralStats registers a single ACF alias, /stats, split across three command classes that share it: StatsCommand (base subcommands), ModifiersCommand (the modifiers group), and ResourceCommand (the resource group). Each class carries its own class-level @CommandPermission, so the permission required for a subcommand depends on which class declares it — see the tables below. Every subcommand that mutates state (rather than just reporting a value) has its success message suppressed when silent-command-success is true in config.yml (see Configuration).

/stats

Class-level permission: stats.command.

Subcommand

Syntax

Completion

Description

value

/stats value <player> <statType>

@players @statTypes

Prints the computed stat value for a player.

set

/stats set <player> <statType> <value>

@players @statTypes <value>

Sets the stat's base value.

reset

/stats reset <player> <statType>

@players @statTypes

Resets the base value to the blueprint default.

reload

/stats reload

Reloads the plugin configuration.

/stats value <player> <statType>

Prints StatService.statValue(target, statType) — the fully computed value (base plus every active modifier, clamped to the blueprint's bounds; see Modifier computation) — to the sender as Stat value for <player> (<statType>): <value>. If <statType> has no loaded blueprint for that player, the computed value is -1.0 (see Value lookup); this always prints, regardless of silent-command-success.

/stats set <player> <statType> <value>

Calls StatService.setStatBaseValue(target, statType, value), which overwrites the stat's stored baseValue and immediately re-applies its handler (no need to wait for the next update tick). If <statType> has no matching StatInstance for the player, the call is a silent no-op. Success message: Set stat <statType> for <player> to <value> (suppressed by silent-command-success).

/stats reset <player> <statType>

Calls StatService.resetStatBaseValue(target, statType), which restores the stat's baseValue to its blueprint's base field and re-applies it immediately. Also a silent no-op if the stat isn't loaded for the player. Success message: Reset stat <statType> for <player> to its base value (suppressed by silent-command-success).

/stats reload

Sends the reloading message, calls AstralStats#loadConfiguration() (reloads config.yml, resources.yml, blueprints, and messages.yml — see Configuration), then sends reloaded on success or reload-failed on exception. This subcommand is not gated by silent-command-success — the reload messages always send. On failure the exception is logged to the server console.

/stats modifiers

Class-level permission: stats.command.modifiers.

Subcommand

Syntax

Completion

Description

add

/stats modifiers add <player> <modifierKey> <statType> <type> <value>

@players @nothing @statTypes @statModifierTypes @nothing

Creates and permanently attaches a StatModifier.

addtimed (alias addtemp)

/stats modifiers addtimed <player> <modifierKey> <statType> <type> <value> <durationMs>

@players @nothing @statTypes @statModifierTypes @nothing @nothing

Creates a StatModifier that auto-expires after durationMs.

remove

/stats modifiers remove <player> <modifierKey>

@players @statModifiers

Removes every modifier on the player keyed <modifierKey>.

<type> is a ModifierType: FLAT, RELATIVE, or PERCENTAGE (see Modifier computation for how each is folded into the stat's value).

/stats modifiers add <player> <modifierKey> <statType> <type> <value>

Builds a StatModifier(modifierKey, statType, ModifierSource.OTHER, EquipmentSlot.SADDLE, value, modifierType) and adds it via StatService.addModifier(...). Command-created modifiers always use ModifierSource.OTHER and a fixed EquipmentSlot.SADDLE — they aren't tied to any equipment slot the way item/armor-granted modifiers are. The modifier is permanent until removed with /stats modifiers remove or by code. Success message (modifier-added, suppressed by silent-command-success): You gave <player> a <type> <value> <stat> modifier with key <key>.

/stats modifiers addtimed <player> <modifierKey> <statType> <type> <value> <durationMs>

Aliases: addtimed, addtemp. Same modifier shape as add (ModifierSource.OTHER, EquipmentSlot.SADDLE), but routed through TemporaryEffectService.addTimedStatModifier(...) instead of being added directly — it auto-expires and is removed after durationMs milliseconds, and survives the target disconnecting and reconnecting before it expires (re-applied on join; see Modifier model). Validated before creating the modifier:

Check

Rejection message

durationMs <= 0

Duration must be greater than 0 milliseconds.

!Double.isFinite(value)

Modifier value must be a finite number.

Success message (inline, not from messages.yml, suppressed by silent-command-success): Added timed modifier <key> to <player> for <duration>ms.

/stats modifiers remove <player> <modifierKey>

Calls StatService.removeModifier(target, modifierKey), which iterates every stat on the player's StatContainer and removes any modifier whose own key equals <modifierKey> — a single key removes it from every stat it was attached to, not just one. The @statModifiers completion lists only the target player's currently active modifier keys (via ModifierCompletionHandler, which reads the OnlinePlayer context value resolved earlier in the same command). Success message (modifier-removed, suppressed by silent-command-success): You removed the <key> modifier from <player>.

/stats resource

Class-level permission: stats.command.resource.

Subcommand

Syntax

Completion

Description

list

/stats resource list <player>

@players

Lists the player's resources with current/max amounts.

add

/stats resource add <player> <resourceType> <amount>

@players @resourceTypes <amount>

Adds a delta to a resource's current amount.

timed (alias temp)

/stats resource timed <player> <resourceType> <amount> <durationMs>

@players @resourceTypes <amount> <durationMs>

Applies a delta that reverses after durationMs.

<resourceType> is a ResourceType name: HEALTH, MANA, STAMINA, SHIELD, or CHARGE (see Resources).

/stats resource list <player>

If the player has a loaded ResourceContainer, prints one line per resource: <TYPE>: <amount> / <max>, where <max> is StatService.statValue(target, resource.blueprint().maxStat()) — the resource's configured max-value stat, both formatted to two decimal places. If the player has no resource container loaded, replies No resources found for player <player> instead. Always prints — not gated by silent-command-success.

/stats resource add <player> <resourceType> <amount>

HEALTH is special-cased to the player's vanilla health rather than AstralStats' resource tracking: the command adds amount to target.getHealth() directly, capping the result at the player's Attribute.MAX_HEALTH value. No lower bound is applied on this path — a sufficiently negative amount is passed straight to Player#setHealth, which throws if the result is below 0. Every other ResourceType goes through ResourceService.resourceValue(target, resourceType, d -> d + amount), adding the delta to the stored resource amount (see Resources for clamping behavior). Success message (inline, suppressed by silent-command-success): Added <amount> of resource <resourceType> to player <player>.

/stats resource timed <player> <resourceType> <amount> <durationMs>

Aliases: timed, temp. Applies amount to the resource now and schedules the exact inverse (-amount) to run when the effect expires, via TemporaryEffectService.addTimedResourceEffect(...). Like timed modifiers, a timed resource effect survives the target going offline: the apply/reverse operators only run against an online player, and pending effects are re-applied on reconnect (or discarded if they expired while offline). Validated before scheduling:

Check

Rejection message

durationMs <= 0

Duration must be greater than 0 milliseconds.

!Double.isFinite(amount)

Amount must be a finite number.

resourceType == HEALTH

Timed effects on HEALTH are not supported. Use resource types managed by AstralStats.

Success message (inline, suppressed by silent-command-success): Applied timed resource effect to <player>: <+/-amount> <resourceType> for <duration>ms.

Argument resolution

  • <statType> resolves to an Adventure Key through the custom KeyContextResolver, registered with registerContext(Key.class, ...) in AstralStats#onEnable. It pops the raw argument and calls Key.key(input) directly — any string Key.key accepts is allowed syntactically, but a stat only exists for a player once a matching blueprint is loaded, so in practice <statType> should be a fully namespaced blueprint key such as astralstats:attack_damage (see Stat catalog). An unparsable key ("Invalid key: <input> ") is rejected before the command method runs.

  • <resourceType> and modifier <type> resolve via ACF's built-in enum context handling, against ResourceType and ModifierType respectively — neither has a custom context resolver registered.

  • <player> resolves to ACF's OnlinePlayer context — the target must be online; the command fails before the method runs if they aren't.

Registered completions

Registered in AstralStats#onEnable alongside the commands:

Completion

Handler

Source

@statTypes

StatTypeCompletionHandler

Every loaded blueprint's key (BlueprintService.blueprints()), sorted.

@statModifiers

ModifierCompletionHandler

The target player's currently active modifier keys, across all of their stats. Requires the OnlinePlayer argument to have resolved first.

@statModifierTypes

ModifierTypeCompletionHandler

The ModifierType enum constants (FLAT, RELATIVE, PERCENTAGE).

@players and @resourceTypes are not custom handlers: @players is ACF's built-in online-player completion, and @resourceTypes resolves automatically from the ResourceType enum via ACF's enum completion support.

Last modified: 25 July 2026