Skip to content

Skill Definitions

Skill definition files are stored in the skills/ directory, with each file defining one skill.

Full YAML Format

yaml
# 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

TypeDescription
local-resourceLocal resource (managed by Skills itself, e.g., mana)
ea-resourceEmakiAttribute resource (e.g., MP, SP)
ea-attribute-checkEmakiAttribute attribute check (read-only, no consumption)

Operation Types

OperationDescription
CONSUMECheck if the resource is sufficient; if so, deduct it
CHECKOnly 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).

yaml
# 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: -1

Field Descriptions

FieldTypeDescription
idstringResource unique identifier
display_namestringDisplay name
maxdoubleMaximum value
default_currentdoubleInitial current value
regen_amountdoubleAmount regenerated each time
regen_interval_ticksintRegeneration interval (ticks)
clamp_mindoubleMinimum value floor
clamp_maxdoubleMaximum value ceiling (-1 = use max)

Default Skills

Skill IDNameTypeMythicMobs SkillCooldownCost
fireballFireballActiveFireball5 seconds30 mana
attack_passiveEcho StrikePassiveExampleAttackPassive2 secondsNone

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.

yaml
# 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

AspectActive SkillPassive Skill
trigger_typeactive (default)passive
passive_triggersNoneMust declare trigger ID list
Trigger methodPlayer presses key in cast modeGame events auto-trigger
Cast modeRequiredNot required
Slot bindingMust equip to slot + bind triggerNo slots used
GUI displayAppears in skill pool, equippableNot shown in skill pool
Trigger selectionPlayer chooses in GUIFixed in YAML, not modifiable
Cooldown/resource check✅ (same as active)

Passive Trigger ID List

Trigger IDDescriptionMythicMobs target
attackAttack hits entityAttacked entity
damaged_by_entityDamaged by entityAttacker
damagedAny damage receivedNone
deathPlayer deathNone
kill_entityKill non-player entityKilled entity
kill_playerKill playerKilled player
shoot_bowShoot bowNone
arrow_hitArrow hits entityHit entity
arrow_landArrow hits blockNone (passes landing location)
shoot_tridentThrow tridentNone
trident_hitTrident hits entityHit entity
trident_landTrident hits blockNone (passes landing location)
break_blockBreak blockNone (passes block location)
place_blockPlace blockNone (passes block location)
drop_itemDrop item (not sneaking)Dropped item entity
shift_drop_itemShift+drop itemDropped item entity
swap_itemsSwap hand itemsNone
shift_swap_itemsShift+swap hand itemsNone
loginPlayer loginNone
sneakStart sneakingNone
teleportPlayer teleportNone (passes target location)
timerPeriodic checkNone

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

TypeYAML ValueDescription
Numbernumber (default)Calculated by math formula, supports min/max limits and decimal control
Expressionexpression or expr or formulaEquivalent to number, explicitly declares expression evaluation
Stringstring or textPasses text directly, supports {variable} replacement
Booleanboolean or boolTrue/false value, supports comparison expressions (e.g., {level} >= 3)
Random Textrandom_text or random_text_lines or random_linesRandomly selects text lines from a candidate list, ideal for random affix generation

Parameter Field Reference

FieldRequiredTypeDefaultDescription
typeNostring"number"Parameter type
formulaNostringMath formula, takes priority over value. Can use {level} etc.
expressionNostringEquivalent to formula, recommended field name when using type: expression
valueNostringStatic value. Used when formula/expression is empty
decimalsNoint0Decimal places (only for number/expression type, 0 = round to integer)
minNodoubleMinimum value limit (only for number/expression type)
maxNodoubleMaximum value limit (only for number/expression type)
defaultNostring""Fallback value when both formula and value are empty
variablesNomapNested variable definitions, each supporting numeric config types (constant/range/expression etc.)

random_text Specific Fields

FieldRequiredTypeDefaultDescription
rollsNonumeric config1Number of draws, supports constant, range, expression, etc.
allow_duplicatesNobooleanfalseWhether the same line can be drawn more than once
linesYeslistCandidate text line list (aliases: values, options, texts)
variablesNomapLocal variable definitions
separatorNostring\nSeparator for joining multiple lines

Variables Available in Formulas

VariableDescription
{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:

yaml
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:

yaml
# MythicMobs skill configuration
ExampleFireball:
  Skills:
  - damage{amount=<skill.var.damage>} @target
  - particles{particle=flame;amount=20;radius=<skill.var.radius>} @self

The system also auto-injects these built-in variables (you don't need to define them):

VariableDescription
<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.:

yaml
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.

yaml
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

FieldRequiredTypeDefaultDescription
enabledNobooleanfalseWhether upgrade is enabled
max_levelNoint1Maximum level. Set to 1 means not upgradeable
failure_penaltyNostring"none"Failure penalty: none = no downgrade; downgrade = lose one level

Economy Cost Configuration

yaml
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 name

cost_formula supports the same variables as skill parameter formulas ({level}, {target_level}, {base_cost}, etc.).

Success Rate Configuration

yaml
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% success

Keys 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:

yaml
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_actions

If 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

CommandPermissionDescription
/eskills upgrade <skill_id>emakiskills.usePlayer self-service skill upgrade
/eskills level get <player> <skill>emakiskills.adminQuery a player's skill level
/eskills level set <player> <skill> <level>emakiskills.adminSet a player's skill level directly
/eskills level add <player> <skill> <value>emakiskills.adminAdd 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: true

Up to 3 parameters are shown. Built-in parameters starting with emaki_ are not displayed.


Default Resources

Resource IDNameMax ValueRegeneration
manaMana1005/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:

yaml
# Skill definition
lore_aliases:
  - "火球术"

# Equipment Lore contains "火球术" → Skill unlocked

Tip

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:

yaml
# 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

Released under the GPL-3.0 License