Skill Definitions
Skill definition files are stored in the skills/ directory, with each file defining one skill.
Full YAML Format
# skills/example_fireball.yml
# Skill unique identifier
id: "fireball"
# Display name (supports MiniMessage)
display_name: "<red>火球术"
# Skill description
description:
- "<gray>向前方发射一颗火球"
- "<gray>造成范围伤害"
# Icon material displayed in GUI
icon_material: "FIRE_CHARGE"
# Corresponding MythicMobs skill ID
mythic_skill: "Fireball"
# Skill cooldown (ticks, 20 ticks = 1 second)
cooldown_ticks: 100
# Global cooldown (ticks) — shared cooldown for all skills after casting this one
global_cooldown_ticks: 20
# Lore aliases — used to match and unlock this skill from equipment Lore
lore_aliases:
- "火球术"
- "Fireball"
# GUI category tag
ui_category: "攻击"
# GUI sort weight
sort_order: 1
# Skill activation type: active (default) / passive
trigger_type: "active"
# Whether enabled
enabled: true
# ============================================================
# Skill Parameters
# Define numeric parameters that scale with level and inject into MythicMobs
# ============================================================
skill_parameters:
# Number parameter: calculated by formula, {level} is replaced with current skill level
damage:
type: "expression"
expression: "{base_damage} + {level_bonus}"
variables:
base_damage:
type: "constant"
value: 18
level_bonus:
type: "expression"
expression: "({level} - 1) * 4"
decimals: 1 # Decimal places
min: 0 # Minimum value
radius:
type: "expression"
expression: "2 + floor(({level} - 1) / 3) * 0.5"
decimals: 2
min: 1
ignite_ticks:
type: "expression"
expression: "40 + ({level} - 1) * 6"
decimals: 0
min: 20
# String parameter: passes text directly
element:
type: "string"
value: "fire"
# String parameter with variable substitution
element_label:
type: "string"
value: "fire_lv_{level}"
# Boolean parameter: supports comparison expressions
empowered:
type: "boolean"
expression: "{level} >= 5 && {has_target} == 1"
default: false
# Random text parameter: randomly selects from candidate lines
random_bonus_lines:
type: "random_text"
rolls: "{bonus_rolls}"
allow_duplicates: false
variables:
bonus_rolls:
type: "constant"
value: 2
phys_atk:
type: "range"
min: 2
max: 6
phys_def:
type: "uniform"
min: 1
max: 4
lines:
- "Physical Attack: +{phys_atk}"
- "Physical Defense: +{phys_def}"
# ============================================================
# Upgrade Configuration
# Define upgrade rules, costs, and success rates
# ============================================================
upgrade:
enabled: true
max_level: 10
failure_penalty: "none" # none = no downgrade on failure; downgrade = lose one level
economy:
enabled: true
currencies:
- provider: "vault"
base_cost: 1200
cost_formula: "{base_cost} * {target_level}"
display_name: "<gold>Coins</gold>"
success_rates:
2: 100.0
3: 95.0
5: 80.0
8: 60.0
10: 40.0
levels:
5:
materials:
- item: "minecraft-blaze_rod"
amount: 1
success_actions:
- "sendmessage text=<yellow>Fireball reached Level V!"
10:
economy:
enabled: true
currencies:
- provider: "vault"
base_cost: 50000
cost_formula: "{base_cost}"
display_name: "<gold>Coins</gold>"
materials:
- item: "minecraft-nether_star"
amount: 1
# ============================================================
# Resource Costs
# List of resources checked and consumed before casting
# ============================================================
resource_costs:
# Local resource consumption
- type: "local-resource"
target_id: "mana"
amount: 30
operation: "CONSUME" # CONSUME = check and deduct, CHECK = check only
failure_message: "<red>法力不足!需要 30 点法力。"
# EmakiAttribute resource consumption (requires EA soft dependency)
- type: "ea-resource"
target_id: "mp"
amount: 20
operation: "CONSUME"
failure_message: "<red>MP 不足!"
# EmakiAttribute attribute check (check only, no consumption)
- type: "ea-attribute-check"
target_id: "intelligence"
amount: 50
operation: "CHECK"
failure_message: "<red>智力不足!需要 50 点智力。"Resource Cost Types
| Type | Description |
|---|---|
local-resource | Local resource (managed by Skills itself, e.g., mana) |
ea-resource | EmakiAttribute resource (e.g., MP, SP) |
ea-attribute-check | EmakiAttribute attribute check (read-only, no consumption) |
Operation Types
| Operation | Description |
|---|---|
CONSUME | Check if the resource is sufficient; if so, deduct it |
CHECK | Only check if the resource is sufficient; do not deduct |
Local Resource Definitions
Local resource definition files are stored in the resources/ directory, defining resources managed by Skills itself (e.g., mana).
# resources/mana.yml
# Resource unique identifier
id: "mana"
# Display name
display_name: "<blue>法力"
# Maximum value
max: 100
# Default current value
default_current: 100
# Natural regeneration amount
regen_amount: 5
# Regeneration interval (ticks)
regen_interval_ticks: 40
# Minimum value clamp
clamp_min: 0
# Maximum value clamp (-1 = use max)
clamp_max: -1Field Descriptions
| Field | Type | Description |
|---|---|---|
id | string | Resource unique identifier |
display_name | string | Display name |
max | double | Maximum value |
default_current | double | Initial current value |
regen_amount | double | Amount regenerated each time |
regen_interval_ticks | int | Regeneration interval (ticks) |
clamp_min | double | Minimum value floor |
clamp_max | double | Maximum value ceiling (-1 = use max) |
Default Skills
| Skill ID | Name | Type | MythicMobs Skill | Cooldown | Cost |
|---|---|---|---|---|---|
fireball | Fireball | Active | Fireball | 5 seconds | 30 mana |
attack_passive | Echo Strike | Passive | ExampleAttackPassive | 2 seconds | None |
Passive Skill Definitions
Passive skills are marked with trigger_type: "passive" and declare trigger events via the passive_triggers list. They don't require cast mode, don't use slots, and are automatically triggered by game events.
# skills/example_attack_passive.yml
id: attack_passive
display_name: "<gradient:#FFD166:#EF476F>命中回响</gradient>"
description:
- "<gray>Passive skill example: auto-triggers on entity hit</gray>"
- "<gray>Players cannot modify this skill's triggers in GUI</gray>"
icon_material: "ECHO_SHARD"
mythic_skill: "ExampleAttackPassive"
trigger_type: "passive"
passive_triggers:
- "attack"
cooldown_ticks: 40
global_cooldown_ticks: 0
lore_aliases:
- "命中回响"
ui_category: "passive"
sort_order: 100
enabled: true
resource_costs: []Active vs Passive Comparison
| Aspect | Active Skill | Passive Skill |
|---|---|---|
trigger_type | active (default) | passive |
passive_triggers | None | Must declare trigger ID list |
| Trigger method | Player presses key in cast mode | Game events auto-trigger |
| Cast mode | Required | Not required |
| Slot binding | Must equip to slot + bind trigger | No slots used |
| GUI display | Appears in skill pool, equippable | Not shown in skill pool |
| Trigger selection | Player chooses in GUI | Fixed in YAML, not modifiable |
| Cooldown/resource check | ✅ | ✅ (same as active) |
Passive Trigger ID List
| Trigger ID | Description | MythicMobs target |
|---|---|---|
attack | Attack hits entity | Attacked entity |
damaged_by_entity | Damaged by entity | Attacker |
damaged | Any damage received | None |
death | Player death | None |
kill_entity | Kill non-player entity | Killed entity |
kill_player | Kill player | Killed player |
shoot_bow | Shoot bow | None |
arrow_hit | Arrow hits entity | Hit entity |
arrow_land | Arrow hits block | None (passes landing location) |
shoot_trident | Throw trident | None |
trident_hit | Trident hits entity | Hit entity |
trident_land | Trident hits block | None (passes landing location) |
break_block | Break block | None (passes block location) |
place_block | Place block | None (passes block location) |
drop_item | Drop item (not sneaking) | Dropped item entity |
shift_drop_item | Shift+drop item | Dropped item entity |
swap_items | Swap hand items | None |
shift_swap_items | Shift+swap hand items | None |
login | Player login | None |
sneak | Start sneaking | None |
teleport | Player teleport | None (passes target location) |
timer | Periodic check | None |
The timer trigger interval is configured via passive_trigger_settings.timer_interval_ticks, default 20 ticks (1 second).
MythicMobs Target Passing
When a passive skill triggers, the event's target entity and location are passed to MythicMobs. For example, the attack trigger passes the attacked entity as @target. Triggers without a target entity (like timer, death) use the player as caster without passing additional targets.
Skill Parameter System
Skill parameters let you define numeric values for skills (like damage, radius, duration) in YAML. These values automatically scale with skill level and are passed to MythicMobs when the skill is cast.
In short: you write a formula in the skill definition, the system calculates the actual value based on the player's skill level, and MythicMobs can use that value directly.
Parameter Types
| Type | YAML Value | Description |
|---|---|---|
| Number | number (default) | Calculated by math formula, supports min/max limits and decimal control |
| Expression | expression or expr or formula | Equivalent to number, explicitly declares expression evaluation |
| String | string or text | Passes text directly, supports {variable} replacement |
| Boolean | boolean or bool | True/false value, supports comparison expressions (e.g., {level} >= 3) |
| Random Text | random_text or random_text_lines or random_lines | Randomly selects text lines from a candidate list, ideal for random affix generation |
Parameter Field Reference
| Field | Required | Type | Default | Description |
|---|---|---|---|---|
type | No | string | "number" | Parameter type |
formula | No | string | — | Math formula, takes priority over value. Can use {level} etc. |
expression | No | string | — | Equivalent to formula, recommended field name when using type: expression |
value | No | string | — | Static value. Used when formula/expression is empty |
decimals | No | int | 0 | Decimal places (only for number/expression type, 0 = round to integer) |
min | No | double | — | Minimum value limit (only for number/expression type) |
max | No | double | — | Maximum value limit (only for number/expression type) |
default | No | string | "" | Fallback value when both formula and value are empty |
variables | No | map | — | Nested variable definitions, each supporting numeric config types (constant/range/expression etc.) |
random_text Specific Fields
| Field | Required | Type | Default | Description |
|---|---|---|---|---|
rolls | No | numeric config | 1 | Number of draws, supports constant, range, expression, etc. |
allow_duplicates | No | boolean | false | Whether the same line can be drawn more than once |
lines | Yes | list | — | Candidate text line list (aliases: values, options, texts) |
variables | No | map | — | Local variable definitions |
separator | No | string | \n | Separator for joining multiple lines |
Variables Available in Formulas
| Variable | Description |
|---|---|
{level} | Player's current skill level (most commonly used) |
{max_level} | Skill's maximum level |
{target_level} | Upgrade target level (used in upgrade preview) |
{player_level} | Player's Minecraft experience level |
{player_health} | Player's current health |
{player_max_health} | Player's maximum health |
{sneaking} | Whether sneaking (0 or 1) |
{has_target} | Whether there's a target entity (0 or 1) |
{skill_id} | Skill ID |
Formulas support basic math operators (+, -, *, /) and functions like floor().
Shorthand Form
If a parameter is just a fixed string value, you can write it as a single line:
skill_parameters:
element: "fire" # Equivalent to type: string, value: "fire"How Parameters Are Passed to MythicMobs
When a skill is cast, all parameters are automatically injected into MythicMobs skill variables. Use <skill.var.parameter_name> in MythicMobs skill configs to reference them:
# MythicMobs skill configuration
ExampleFireball:
Skills:
- damage{amount=<skill.var.damage>} @target
- particles{particle=flame;amount=20;radius=<skill.var.radius>} @selfThe system also auto-injects these built-in variables (you don't need to define them):
| Variable | Description |
|---|---|
<skill.var.emaki_skill_id> | Skill ID |
<skill.var.emaki_skill_level> | Current skill level |
<skill.var.emaki_trigger_id> | Trigger ID |
<skill.var.emaki_is_passive> | Whether passive skill (0 or 1) |
<skill.var.emaki_has_target> | Whether there's a target entity (0 or 1) |
Note
Parameter IDs cannot start with emaki_ — this prefix is reserved for the system. Parameters with this prefix will be skipped during loading.
Nested Variables
expression type parameters support nested variable definitions via the variables field. Each nested variable is itself a numeric configuration object, supporting constant, range, uniform, expression, etc.:
damage:
type: "expression"
expression: "{base_damage} + {level_bonus}"
variables:
base_damage:
type: "constant"
value: 18
level_bonus:
type: "expression"
expression: "({level} - 1) * 4"Nested variables are resolved to numeric values before the main expression is evaluated, then substituted in. This lets you break complex formulas into more readable parts.
random_text Parameter Type
The random_text type randomly selects text lines from a candidate list, ideal for generating random affixes, descriptions, etc. The result is passed to MythicMobs as a string.
random_bonus_lines:
type: "random_text"
rolls: "{bonus_rolls}" # Draw count (supports numeric config)
allow_duplicates: false # No duplicates
variables:
bonus_rolls:
type: "constant"
value: 2
phys_atk:
type: "range"
min: 2
max: 6
lines:
- "Physical Attack: +{phys_atk}"
- "Physical Defense: +{phys_def}"The evaluation result of a random_text parameter is a string of multiple lines joined by a separator (default \n). Variables defined in variables are substituted into each text line.
For detailed field descriptions, see Expression Engine — Random Text.
Skill Upgrade System
Skill upgrades let players spend coins and materials to increase their skill level. Higher levels mean stronger parameters.
Upgrade Configuration Fields
| Field | Required | Type | Default | Description |
|---|---|---|---|---|
enabled | No | boolean | false | Whether upgrade is enabled |
max_level | No | int | 1 | Maximum level. Set to 1 means not upgradeable |
failure_penalty | No | string | "none" | Failure penalty: none = no downgrade; downgrade = lose one level |
Economy Cost Configuration
upgrade:
economy:
enabled: true
currencies:
- provider: "vault" # Economy provider: vault / excellenteconomy / auto
currency_id: "" # Currency ID (leave empty for Vault)
base_cost: 1200 # Base cost
cost_formula: "{base_cost} * {target_level}" # Cost formula
display_name: "<gold>Coins</gold>" # Display namecost_formula supports the same variables as skill parameter formulas ({level}, {target_level}, {base_cost}, etc.).
Success Rate Configuration
upgrade:
success_rates:
2: 100.0 # Upgrade to level 2: 100% success
5: 80.0 # Upgrade to level 5: 80% success
10: 40.0 # Upgrade to level 10: 40% successKeys are target levels, values are success rate percentages. Levels without a configured rate default to 100%.
Per-Level Configuration
You can set additional material requirements, cost overrides, parameter overrides, and actions for specific milestone levels:
upgrade:
levels:
5:
# Extra materials needed to reach level 5
materials:
- item: "minecraft-blaze_rod" # Item source (same format as action system)
amount: 1 # Required quantity
optional: false # Optional material (can upgrade without it)
protection: false # Protection material
# Override economy cost for this level (omit to use global)
economy:
enabled: true
currencies:
- provider: "vault"
base_cost: 20000
cost_formula: "{base_cost}"
display_name: "<gold>Coins</gold>"
# Override success rate for this level
success_rate: 40.0
# Override parameter definitions for this level (e.g., fix radius at 3.5 for level 5)
parameters:
radius:
type: "number"
value: 3.5
decimals: 2
# Actions executed on success/failure
success_actions:
- "sendmessage text=<yellow>Reached Level V!"
- "playsound sound=entity.player.levelup volume=1.0 pitch=1.5"
failure_actions:
- "sendmessage text=<red>Upgrade failed..."Upgrade Flow
When a player runs /eskills upgrade <skill_id>, the system processes these steps:
1. Check if the skill is unlocked (can't upgrade if not unlocked)
2. Check if already at max level
3. Calculate target level = current level + 1
4. Check if coins are sufficient
5. Check if inventory materials are sufficient
6. Deduct coins and materials
7. Roll success rate
├─ Success → Level +1, execute success_actions
└─ Failure → Apply failure_penalty if configured, execute failure_actionsIf something goes wrong during the deduction phase (e.g., coins deducted but materials insufficient), the system automatically refunds everything that was already taken.
Upgrade Commands
| Command | Permission | Description |
|---|---|---|
/eskills upgrade <skill_id> | emakiskills.use | Player self-service skill upgrade |
/eskills level get <player> <skill> | emakiskills.admin | Query a player's skill level |
/eskills level set <player> <skill> <level> | emakiskills.admin | Set a player's skill level directly |
/eskills level add <player> <skill> <value> | emakiskills.admin | Add or subtract from a player's skill level |
Level and Parameter Display in GUI
In the skill GUI, each skill icon's Lore automatically shows the current level and parameter preview:
Level: 3/10
Parameter Preview:
- damage: 26.0
- radius: 2.5
- can_ignite: trueUp to 3 parameters are shown. Built-in parameters starting with emaki_ are not displayed.
Default Resources
| Resource ID | Name | Max Value | Regeneration |
|---|---|---|---|
mana | Mana | 100 | 5/2s |
Skill Unlock Mechanism
Skills are unlocked through two methods:
1. PDC Unlock
The equipment's PersistentDataContainer stores a list of skill IDs:
PDC Key: emaki_skills:item.skills.ids
Value: ["fireball", "ice_bolt", "heal"]When a player equips an item containing this PDC data, the corresponding skills are automatically unlocked. Skills are removed from the unlock pool when the equipment is unequipped.
2. Lore Unlock
When the equipment's Lore contains any text from a skill definition's lore_aliases, that skill is unlocked:
# Skill definition
lore_aliases:
- "火球术"
# Equipment Lore contains "火球术" → Skill unlockedTip
Both unlock methods can be used simultaneously. EquipmentSkillCollector scans both PDC and Lore, merging all unlocked skills.
PlayerSkillProfile Data Model
Each player's skill profile is stored in data/{uuid}.yml, recording cast mode state, slot bindings, local resources, cooldown timers, and skill levels:
# data/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.yml
cast_mode_enabled: true
bindings:
- slot: 0
skill_id: "fireball"
trigger_id: "right_click"
- slot: 1
skill_id: "ice_bolt"
trigger_id: "shift_right_click"
- slot: 2
skill_id: null
trigger_id: null
local_resources:
mana:
current: 75.0
timing:
last_cast_time_ms: 1700000000000
forced_delay_until_ms: 0
global_cooldown_until_ms: 1700000001000
skill_cooldowns:
fireball: 1700000005000
skill_levels:
fireball: 3
ice_bolt: 1