English
Native Script System
The native script system covers the global settings, how to write a skill's script block, which phases exist, which actions you can write, and how targets and conditions work
Besides handing effects to MythicMobs, EmakiSkills ships its own native script system. The benefit: no external plugin is required, and you define effect logic directly in skill configuration
Global script engine configuration
The global settings live in config.yml under script_engine:
yaml
script_engine:
enabled: true
# Mode used when a skill does not declare one
default_mode: "native"
# Whether a failed action stops the current phase
stop_on_failure: true
# Maximum lines per phase; values below 1 are treated as 1
max_lines_per_phase: 64
# Maximum targets per action; values below 1 are treated as 1
max_targets_per_action: 16
debug: false| Field | Type | Required | Default | Values | Description |
|---|---|---|---|---|---|
script_engine.enabled | boolean | No | true | true / false | Whether native skill scripts are enabled. When off, every skill's script block is ignored and only the MythicMobs flow remains |
script_engine.default_mode | string | No | "native" | native / mythic / hybrid | Mode used when a skill declares no script.mode; blank falls back to native |
script_engine.stop_on_failure | boolean | No | true | true / false | Whether later actions in the same phase stop after a failed action; a skill may override it with script.stop_on_failure |
script_engine.max_lines_per_phase | integer | No | 64 | ≥ 1, values below 1 become 1 | Maximum action lines in one phase |
script_engine.max_targets_per_action | integer | No | 16 | ≥ 1, values below 1 become 1 | Maximum targets one action may process |
script_engine.debug | boolean | No | false | true / false | Whether script debug output is enabled |
These limits exist to keep a single cast from processing too many actions or targets. For large area skills, cap the target count and test visuals, damage, and messages separately
The script block inside a skill
yaml
script:
enabled: true
mode: native
stop_on_failure: true
actions:
cast:
- 'self | play_sound sound=ENTITY_BLAZE_SHOOT volume=1 pitch=1.5'
hit:
- 'trigger | ignite duration=3s'
conditions:
hit:
- "%level% >= 3"| Field | Type | Required | Default | Values | Description |
|---|---|---|---|---|---|
script.enabled | boolean | No | true when actions has any phase, otherwise false | true / false | When explicitly disabled, the skill's script is not compiled or executed |
script.mode | string | No | script_engine.default_mode | native, mythic (alias mythicmobs), hybrid (alias both) | How the skill runs. An unrecognized value falls back to native |
script.stop_on_failure | boolean | No | script_engine.stop_on_failure | true / false | Whether later actions in the same phase stop after a failed action |
script.actions.<phase> | list<\string> | No | [] | Action pipeline lines | Action lines run in that phase |
script.conditions.<phase> | list<\string> | No | [] | Condition expressions | Preconditions for that phase; the phase only runs when all pass, otherwise it reports skill.script_phase_condition_failed and counts as skipped |
Script modes
| Mode | Alias | Description |
|---|---|---|
native | — | Run only built-in script actions |
mythic | mythicmobs | Run only the MythicMobs skill from mythic_skill |
hybrid | both | Run both the native script and the MythicMobs skill; a failed native phase skips the MythicMobs part |
If you write no script block, or the script is disabled, the skill goes straight down the MythicMobs path; if there is no mythic_skill either, the cast fails with skill.mythic_not_configured
Phases
Each phase has its own conditions and actions lists:
| Phase | When it runs |
|---|---|
cast | When the skill is cast |
hit | When the skill hits a target |
miss | When the skill misses |
fail | When casting fails (conditions unmet, resources short, and so on) |
Keep to the names above for phase keys; prefixed forms such as on_cast are not supported. hit and miss are chosen by whether the target flow forwarded from the previous phase is empty
Example
yaml
id: flame_strike
trigger_type: active
display_name: '<red>Flame Strike'
script:
mode: native
stop_on_failure: true
actions:
cast:
- 'self | play_sound sound=ENTITY_BLAZE_SHOOT volume=1 pitch=1.5'
- 'trigger | spawn_particle particle=FLAME count=20'
- 'trigger | damage amount=%var.fire_damage%'
hit:
- 'trigger | ignite duration=3s'
- 'self | send_message text="<red>Burning!"'
fail:
- 'self | send_message text="<gray>Skill failed."'Context variables
Script execution injects the variables below; you reference them in action lines, phase conditions, and text as %var.<name>%:
| Variable | Description |
|---|---|
%var.level% | Current skill level |
%var.skill_id% | Skill id |
%var.trigger_id% | Trigger id |
%var.has_target% | Whether there is a target (0 or 1) |
%var.<skill variable>% | Variables defined in the skill's variables, see Variable types |
Five synonyms for MythicMobs are injected as well, visible in scripts as %var.emaki_skill_id% and so on: emaki_skill_id, emaki_skill_level, emaki_trigger_id, emaki_is_passive, and emaki_has_target
Expressions inside a variables block can additionally read %max_level%, %target_level%, %is_passive%, %player_level%, %player_health%, %player_max_health%, and %sneaking%. These take part in variable evaluation only; they are not injected as script-line placeholders
Script actions
Every script line you write is compiled and executed by CoreLib's action engine, so the available action stages are exactly those in the CoreLib registry plus the skill stages EmakiSkills registers. EmakiSkills has no separate private action IDs
- The full list of CoreLib's own stages and their parameters is in CoreLib Actions
- The stages EmakiSkills adds (
cast_skill,cast_mythic_skill, level/slot/cooldown/unlock) are in CoreLib Actions
Use the registered stage IDs
A stage ID must match its registered name exactly. A line with a wrong ID is dropped at compile time and recorded as a diagnostic; it does not fail at runtime. Common mistakes:
| Wrong | Correct |
|---|---|
message | send_message |
sound | play_sound |
particle | spawn_particle |
mythic | cast_mythic_skill |
Also note: ray and aoe_damage are not registered stages and have no equivalent
Targets are not written as an action parameter but with the pipeline's source | stage syntax, see CoreLib Actions
Only the stages most commonly used in skill scripts are listed below; the registry is authoritative for parameters
damage
Deal damage to a target
| Parameter | Required | Default | Description |
|---|---|---|---|
amount | Yes | — | Health removed |
heal
Heal a target
| Parameter | Required | Default | Description |
|---|---|---|---|
amount | Yes | — | Health restored |
ignite
Set a target on fire
| Parameter | Required | Default | Description |
|---|---|---|---|
duration | No | 5s | Burn duration; accepts ms, s, and t suffixes |
send_message
Send MiniMessage chat text
| Parameter | Required | Default | Description |
|---|---|---|---|
text | Yes | — | Message text |
play_sound
Play a sound
| Parameter | Required | Default | Description |
|---|---|---|---|
sound | Yes | — | Bukkit Sound name |
volume | No | — | Volume |
pitch | No | — | Pitch |
spawn_particle
Spawn particles
| Parameter | Required | Default | Description |
|---|---|---|---|
particle | Yes | — | Particle type |
count | No | — | Particle count |
offset_x / offset_y / offset_z | No | — | Per-axis spread offsets |
extra | No | — | Extra particle data (speed for most particles) |
projectile
Launch a custom projectile with tick-by-tick simulation. Sets the context target entity on hit
| Parameter | Required | Default | Description |
|---|---|---|---|
speed | No | 1.5 | Blocks per tick |
gravity | No | 0.05 | Gravity per tick |
lifetime | No | 60 | Max lifetime in ticks |
hit_radius | No | 0.5 | Hit detection radius |
pierce | No | 0 | Number of entities to pierce through |
homing | No | false | Enable homing toward the target |
homing_strength | No | 0.1 | Homing turn strength |
particle | No | FLAME | Trail particle type |
damage | No | 0 | Damage on hit (0 = no damage) |
direction | No | look | Initial direction: look (view direction) or target (toward the target) |
Target resolution
Targets are written in the source stage left of the pipe, not as an action parameter. The sources you will use most in skill scripts:
| Source | Resolves to |
|---|---|
self | The caster. Also the default when the source is omitted |
trigger | The entity named by the trigger context (the crosshair target of an active skill, the event entity of a passive skill) |
inherited / keep | The target flow carried across phases; keep records the current targets and inherited reads what the upstream recorded |
looking_at | The entity under the caster's crosshair; accepts range= and width= |
nearby / nearby_players | Nearby entities or players; accepts radius=, limit=, and type= |
player_by_name | A player by name |
The full source list and parameters are in CoreLib Actions
Conditions, chance, and delay
Conditions, chance rolls, and delays are gate stages; they sit between pipes and are not written as line-leading @ prefixes:
yaml
actions:
cast:
- 'trigger | where %var.has_target%==1 | damage amount=20'
- 'trigger | chance 30% | ignite duration=5s'
- 'self | after 20t | send_message text="<gray>Fires one second later."'| Gate | Description |
|---|---|
where <condition> | Clears the target stream when the condition is false, so later stages do not run |
if <condition> [ ... ] | Runs the piped stages in brackets when the condition is true |
chance <n>% | Passes with the given probability |
after <time> | Delays the following stages. Accepts ms, s, and t suffixes |
The @ prefix form is obsolete
The old line-leading @if=, @chance= and @delay= prefixes are no longer parsed; replace them as follows: @chance=25% → chance 25%, @delay=20t → after 20t, and @if=<condition> → an if <condition> [ ... ] branch or where <condition>. @ignore_failure has no equivalent. Full syntax is in CoreLib Actions
Built-in JavaScript stages
The native script system also ships three GraalVM JavaScript stages, letting you do lightweight computation or read entity or location state inside a pipeline. Note that their return value only lands in the action result's script_result; it does not write back to variables, does not create placeholders, and does not filter or replace targets. When a value must feed later computation, use an expression variable instead
| Stage | Bindings | Description |
|---|---|---|
js_compute | context (plus player when the current target is a player) | Pure computation, no target needed. context can read var.* variables |
js_entity | player, context | Operates on an existing player target; non-player targets are skipped silently |
js_location | location, context (plus a read-only player when one is associated) | Reads a location target |
Every stage requires code; timeout is in milliseconds, defaults to 5000, and also falls back to 5000 when <= 0