Skill Files
A skill file defines a single skill: its identity, execution behavior, parameters, and effects. Skill files are YAML documents stored in plugins/AstralSkill/skills/ (subfolders are scanned recursively) and deserialized into a WrappedSkill record at load time.
Each skill file declares a top-level id field that is the map key — skills are indexed by id, not by filename. Duplicate ids overwrite silently.
Minimal example
Top-level fields
Field | Type | Required | Description |
|---|---|---|---|
| String | Yes | Unique skill identifier (the id field, not the filename). Duplicates overwrite silently. |
| Root enum | Yes | Skill category: |
| Type enum | Yes | Skill implementation: one of six hardcoded types that select runtime behavior (see Cast Types). |
| Set[String] | No | Free-form tags for categorization (e.g., |
| RequirementList | No | Conditions that must pass before the skill can be cast (e.g., |
| YAML Object | Yes | Type-specific parameters (projectile velocity, impact radius, dummy payload, etc.) — full key sets live in Cast Types. |
| Effect[] | No | List of effects applied to the caster when the skill is cast (see Effects). |
| Effect[] | No | List of effects applied to each entity hit/affected by the skill (see Effects). |
skill-root
The skill-root enum is a categorization flag for consumers (e.g., AstralClasses, AstralMobs). It does not affect runtime behavior; instead, it signals intent to systems that subscribe to or trigger skills:
Value | Meaning |
|---|---|
| Skill is cast once on player/entity activation |
| Skill is activated and deactivated by the player (or on timed schedule for mobs) |
| Skill is always active and not directly cast |
| Skill does not fit into any of the other categories |
Example:
type
The type enum selects the concrete Skill implementation and is hardcoded — it determines the runtime behavior and the expected params structure:
Type | Behavior | See |
|---|---|---|
| Inert skill; applies cast/target effects but does not interact with the world | |
| Instant area-of-effect applied at a location; hits all entities within a radius | |
| Launches moving projectile(s) with collision detection, drag, gravity, and visual display | |
| Fires continuous beam with line-of-sight targeting and hit detection (drag and gravity fixed to 0) | |
| Rotates through a sequence of skills, stepping to the next skill on each cast | |
| Periodically self-triggers on a timed schedule (no player cast required per element) |
Example:
id
The id field is the unique skill identifier and is the map key — not the filename. Consumers (AstralClasses, AstralMobs) reference skills by id. Best practice: align filenames with ids for readability (e.g., knight-attack-1-cast.yml for id: "knight-attack-1-cast").
tags
Tags are free-form strings used for categorization and filtering. They have no effect on skill execution; consumers may use them for organizing skills in menus or filtering by category:
Placeholder expressions in params and effects
Most fields inside params and effect params are typed as PlaceholderWrapper<T>, so they accept either a literal value or a placeholder expression string resolved against the PlaceholderContainer supplied at cast time:
The container is built by the caller: if the caster is a Player and no container is passed, AstralCore auto-builds one with player-scoped placeholders (e.g. %player_name%); consumers like AstralClasses or AstralMobs can register additional custom placeholders (e.g. %level%) before casting.
Some example skill files carry a top-level placeholders: map (e.g. level: 1). This key has no corresponding field on WrappedSkill, so it is not parsed or resolved — it currently has no effect on skill behavior.
requirement-list
The requirement-list is an AstralCore PaperRequirementList that gates skill execution. Requirements are evaluated before the skill is cast. If any requirement fails, the cast is aborted and no effects are applied.
Requirements are only enforced for Player casters. Non-player casters (mobs, projectiles) are unaffected.
See AstralCore's requirement system documentation for the full syntax and operators.
params
The params block is a type-specific configuration parsed into the concrete Skill implementation matching the type field. The full key set and shape for each type is documented in Cast Types.
Example (projectile):
Example (impact):
cast-effects and target-effects
cast-effects — list of Effect instances applied to the caster when the skill is cast.
target-effects — list of Effect instances applied to each affected entity (on hit for projectile/laser, on deactivate for impact, etc.).
Both are optional lists of objects with a type and params:
See Effects for the full catalogue of effect types and their parameters.
Skill chaining
Skills can trigger other skills through chaining fields inside params. These fields accept a skill id (string) or list of skill ids:
Type | Field | Behavior |
|---|---|---|
Projectile |
| Triggered when projectile hits an entity |
Projectile |
| Triggered when projectile hits a block |
Projectile |
| Triggered when projectile reaches max-range without hitting |
Laser |
| Triggered when laser hits an entity |
Laser |
| Triggered when laser hits a block |
Impact |
| Triggered when impact hits an entity |
Impact |
| Triggered when impact reaches max-range or other miss condition |
The chained skills are cast at the location of the trigger event (entity hit, block hit, etc.) and inherit the original caster's context.
Chain example
A projectile (mage-attack-1-laser) fires when cast and triggers an impact (mage-attack-1-impact) when it hits an entity:
mage-attack-1-laser.yml:
mage-attack-1-impact.yml:
Composition types
Two skill types exist to compose/sequence other skills:
n_cast — Rotation
The n_cast type rotates through a sequence of skills, stepping to the next one on each cast. It exposes a %n-cast-index% placeholder to track the current position:
Fields:
skills— list of skill ids to rotate throughmax-delay-between-iterations— time (milliseconds) after which the rotation resets to the first skill if no cast occurs
auto_cast — Scheduled sequence
The auto_cast type schedules a timed sequence of skills to fire automatically, repeating at a configured interval:
Fields:
repeat— number of times to repeat the entire sequence (0 = fire once; 1 = fire twice, etc.)elements— list of{skill, delay}pairs, wheredelayis milliseconds from the start of the sequence
Full skeleton
A complete skill file with every top-level key in order:
Validation
The skill loader rejects entries that fail any of these checks:
Missing or empty
id.Missing or invalid
skill-root(must be one ofcast,toggle,passive,misc).Missing or invalid
type(must be one ofdummy,impact,projectile,laser,n_cast,auto_cast).paramsis empty or cannot be parsed for the selectedtype.A
paramsfield references an effect type not registered withEffectFactory— loading fails for that skill.A chaining field (e.g.,
cast-skill-on-entity) references a skill id that does not exist — logged as a warning at runtime; the chained skill simply does not fire.A
requirement-listuses invalid syntax or references placeholders that cannot be resolved.
Errors are logged per skill with the skill id and exception message. A bad skill does not prevent the rest from loading.
Hot reload
/skill reload (permission skill.reload) re-reads all .yml files from the skills/ folder and re-initializes every skill:
All running skill instances are deactivated gracefully.
The skill registry is cleared.
All files are re-parsed and re-initialized.
The shard update loops restart.
Configuration changes take effect immediately. The shard thread count is never changed by reload (requires a server restart).