Skip to content

Skill Definitions ​

Skill definition files spell out what each field means, its default, and which values it accepts. Skill files live in plugins/EmakiSkills/skills/*.yml. One skill per file: you only describe what the skill is (name, cooldown, costs, upgrades) and hand the actual effect to the native script system or MythicMobs. Local resource definitions live in plugins/EmakiSkills/resources/*.yml

Loading rules ​

  • One file loads exactly one skill. A blank id makes the whole file be skipped and recorded as a loader issue
  • To park a skill temporarily, set enabled: false; it never enters the registry, which is the same as the skill not existing
  • Skill ids are normalized to lower case; ids inside list fields get the same treatment, with - folded to _
  • List fields accept alias keys (see the table); when both are present their entries are merged in order and de-duplicated

Top-level fields ​

yaml
id: "fireball"
enabled: true
display_name: "<red>Fireball"
description:
  - "<gray>Hurls a fireball forwards."
icon_material: "fire_charge"
mythic_skill: "EmakiFireball"
trigger_type: "active"
cooldown_ticks: 100
global_cooldown_ticks: 20
FieldTypeRequiredDefaultValuesDescription
idstringYes—Non-blank; lower-casedUnique skill id. A blank value skips the whole file
enabledbooleanNotruetrue / falseWhether the skill is loaded. false means the skill does not exist
display_namestringNoidAny MiniMessage textDisplay name used by the GUI, action bar, and the %skill% placeholder in feedback
descriptionlist<\string>No[]—Description lines shown in the GUI
icon_materialstringNo""Bukkit Material name (lower-cased)GUI icon material. When blank the slot config or a built-in fallback material is used
mythic_skillstringNo""MythicMobs skill idThe MythicMobs skill run in mythic / hybrid mode, and the effect used for non-player casters
trigger_typestringNo"active"active / passive (anything else counts as active)Active or passive skill
passive_triggerslist<\string>No[]Registered passive trigger idsEvent sources of a passive skill. Unregistered ids are dropped at dispatch time without an error
cron_expressionstringNo""Quartz cron expressionWhen non-blank, a cron_<id> passive trigger is registered and added to passive_triggers; see CoreLib expressions - Cron
cron_max_executionsintegerNo0≥ 0, negatives become 0Total firing cap for the cron trigger; 0 means unlimited
variablesmapNo{}Keys not starting with emaki_Runtime variable block; see Variable types
scriptmapNodisabled—Native script block; see Native scripting
upgrademapNodisabled—Upgrade rules, documented below
cooldown_ticksintegerNo0≥ 0, negatives become 0Per-skill cooldown in ticks (20 ticks = 1 second)
global_cooldown_ticksintegerNo0≥ 0, negatives become 0Global cooldown in ticks, shared by every skill after a cast
resource_costslist<\map>No[]—Resource costs or checks; entry fields below
lore_aliaseslist<\string>No[]—Aliases matched when reading skills from equipment lore
pdc_skill_idstringNoid—ID used when reading the skill from equipment PDC
tagslist<\string>No[]Limited when matching skill_tags.equip_limitsSkill tags used for equip-count limits and category filtering
tab_tagslist<\string>No[]Alias tabTagsGUI tab tags
required_skillslist<\string>No[]Alias dependenciesSkill ids that must already be equipped before this one can be equipped
conflicting_skillslist<\string>No[]Alias conflictsSkill ids that cannot be equipped together with this one
ui_categorystringNo"default"—GUI category
sort_orderintegerNo0Lower sorts firstGUI ordering
show_in_slotsbooleanNotruetrue / falseWhether the skill may appear in the player's active slot selection list. Equipment-forced trigger skills usually set this to false
conditionmapNonone—Cast (and upgrade) condition block, below

The condition block ​

Casting and upgrading share the same condition block. The condition text is rendered through PlaceholderAPI before evaluation

yaml
condition:
  type: "all_of"
  entries:
    - "%player_level% >= 5"
    - "%emakiskills_level_fireball% >= 2"
FieldTypeRequiredDefaultValuesDescription
conditionmapNonone—Must be a mapping node; without entries the block counts as no condition at all
condition.typestringNoall_ofall_of, any_of, none_of, at_least, exactlyHow multiple conditions combine
condition.entrieslist<\string>No[]Expression stringsCondition expressions; omitting the key leaves the whole block empty
condition.required_countintegerNo0≥ 0Match threshold for the at_least / exactly combine modes
condition.invalid_as_failurebooleanNotruetrue / falseRead by the shared condition parser; EmakiSkills' cast and upgrade paths always treat an unparseable expression as "not passed"
condition.on_pass.actions / condition.on_fail.actionslist<\string>No[]—Read by the shared condition parser; EmakiSkills skills do not use them
condition.on_fail.block_output / condition.on_fail.messageboolean / stringNofalse / ""—Same as above; not used by EmakiSkills skills

An unparseable condition counts as "not passed": the skill is not cast and the upgrade is rejected. The cast failure key is cast.condition_not_met and the upgrade failure key is upgrade.condition_not_met

Condition text is handed to PlaceholderAPI before evaluation, so every %...% in it must be resolvable by an installed expansion (for example %emakiskills_level_fireball%). An unresolvable placeholder reaches the expression as-is and, per the rule above, counts as not passed

Variables and scripts ​

  • variables: runtime values; syntax and types are in Variable types. Script lines, conditions, and text read them as %var.<name>%
  • script: the native script block; keys and phases are in Native scripting
yaml
variables:
  fire_damage:
    type: expression
    value: "10 + %level% * 5"
  battle_cry:
    type: random_text
    lines:
      - "<red>Burn!"
      - "<red>Flame power!"

script:
  mode: native          # native / mythic / hybrid
  stop_on_failure: true
  actions:
    cast:
      - 'trigger | damage amount=%var.fire_damage%'
    hit:
      - 'trigger | ignite duration=3s'

resource_costs ​

yaml
resource_costs:
  - type: "ea-resource"
    target_id: "mana"
    amount: 20
    operation: "consume"
    failure_message: "<red>Not enough mana."
FieldTypeRequiredDefaultValuesDescription
typestringYes—ea-resource, attribute-check (alias ea-attribute-check), local-resource, auraskills-mana (aliases aura-skills-mana, aura-mana), mythiclib-mana (aliases mmocore-mana, mythic-mana)Resource type. An unrecognized value makes the whole entry be dropped
target_idstringNo""Resource / attribute idThe local resource, Attribute resource, or attribute id involved
amountdoubleNo0≥ 0, negatives become 0Amount to check or deduct
operationstringNoconsumeconsume (deduct), require (check only)Any other value is treated as consume
failure_messagestringNo""MiniMessage, rendered through PlaceholderAPIMessage shown when the check fails; when blank it falls back to the target_id text

Watch the fallbacks when a dependency is missing: auraskills-mana requires AuraSkills and mythiclib-mana requires MythicLib or MMOCore; when the plugin is absent the entry counts as unavailable, so the check passes and the deduction is skipped. ea-resource and attribute-check behave the same way when EmakiAttribute is unavailable. attribute-check never deducts

Local resource files ​

resources/*.yml defines the resources used by local-resource. The resource id comes from the id key you write, not the file name

yaml
id: "mana"
display_name: "<gradient:#4DA6FF:#00BFFF>Mana</gradient>"
max: 100.0
default_current: 100.0
regen_amount: 2.0
regen_interval_ticks: 20
clamp_min: 0.0
clamp_max: 100.0
FieldTypeRequiredDefaultValuesDescription
idstringYes—Non-blank; lower-casedUnique resource id; a blank value skips the whole file
display_namestringNoidMiniMessageDisplay name
maxdoubleNo100.0≥ 0, negatives become 0Resource maximum
default_currentdoubleNo100.0≥ 0, negatives become 0Starting value the first time a player is loaded
regen_amountdoubleNo0.0≥ 0, negatives become 0Amount added by each natural regeneration step
regen_interval_ticksintegerNo0≥ 0, negatives become 0Regeneration interval in ticks; 0 disables regeneration
clamp_mindoubleNo0.0≥ 0, negatives become 0Lower bound of the current value
clamp_maxdoubleNo0.0Falls back to max when <= 0, otherwise ≥ clamp_minUpper bound of the current value

Local resources versus other resource systems

Local resources are stored only in skill data and are not synchronized with EmakiAttribute. If you already keep a resource of the same name in EmakiAttribute, switch skill costs to ea-resource so the two never diverge

Upgrade configuration ​

yaml
upgrade:
  enabled: true
  max_level: 5
  gui_template: "upgrade_gui"
  failure_penalty: "none"
  economy:
    enabled: true
    currencies:
      - provider: "vault"
        currency_id: ""
        base_cost: 1200
        cost_formula: "%base_cost% * %target_level%"
        display_name: "<gold>Coins</gold>"
  success_rates:
    2: 100.0
    3: 90.0
  levels:
    2:
      materials:
        - item_sources:
            - "minecraft-blaze_powder"
          amount: 2
      actions:
        success:
          - 'send_message text="<yellow>The fireball grows stronger.</yellow>"'
FieldTypeRequiredDefaultValuesDescription
upgrade.enabledbooleanNofalsetrue / falseWhether upgrades are enabled. When off, the maximum level is 1
upgrade.max_levelintegerNo1≥ 1, values below 1 become 1Maximum level, also the clamp used by the level command and the API
upgrade.gui_templatestringNoupgrade_guiA template name under gui/Upgrade GUI template. Blank, equal to upgrade_gui, or pointing at a missing template all fall back to upgrade_gui (a warning is logged when the template is missing)
upgrade.failure_penaltystringNononenone / downgradeFailure penalty. Only downgrade lowers the level by one (never below 1). Writing reset only changes the GUI text; it does not reset the level
upgrade.economy.enabledbooleanNofalsetrue / falseWhether currency costs are charged
upgrade.economy.currencieslist<\map>No[]—Currency list, fields below
upgrade.success_ratesmap<int,double>No100.0Keys are integers > 0; values are clamped to 0-100Success rate by target level; unlisted levels use 100. Non-positive or non-integer keys are skipped
upgrade.levelsmap<int,map>No{}Keys are integers > 1 with mapping nodesPer-target-level overrides for materials, economy, success rate, and upgrade actions

Each upgrade.economy.currencies entry:

FieldTypeRequiredDefaultValuesDescription
providerstringNoauto (lower-cased)Economy provider nameEconomy source; when blank it is auto and CoreLib selects one
currency_idstringNo""—Currency id
base_costdoubleNo0≥ 0, negatives become 0The value of %base_cost% inside cost_formula
cost_formulastringNo%base_cost%ExpressionThe amount actually charged. May use %base_cost%, %level% (current level), %target_level%, and %max_level%; an entry whose result is ≤ 0 is not charged
display_namestringNo""MiniMessageDisplay name; falls back to currency_id, then to provider

Each upgrade.levels.<n> entry (<n> is the target level and must be > 1):

FieldTypeRequiredDefaultValuesDescription
levels.<n>.materialslist<\map>No[]—Required items for this level; fields below
levels.<n>.economy.enabledbooleanNotruetrue / falseWhether this level overrides the economy to "enabled"
levels.<n>.economy.currencieslist<\map>No[]Same as upgrade.economy.currenciesCurrency override for this level; with enabled: false this level is free
levels.<n>.success_ratedoubleNoupgrade.success_rates valueClamped to 0-100Success rate override for this level, taking priority over upgrade.success_rates
levels.<n>.actions.successlist<\string>No[]Action pipeline linesActions run after a successful upgrade
levels.<n>.actions.failurelist<\string>No[]Action pipeline linesActions run after a failed upgrade (a failed roll or a downgrade)

Each levels.<n>.materials entry:

FieldTypeRequiredDefaultValuesDescription
item_sourceslist<\string>No""Item source syntax, see Item MatcherAllowed item sources; only the first list entry is used as the item token. Combined with a sibling matcher using AND
matchermapNononeComponent / PDC / lore conditionsNon-item-source conditions. Item sources must not be written inside matcher
amountintegerNo1≥ 1, 0 becomes 1Required amount
optionalbooleanNofalsetrue / falseParsed, but the current upgrade check and charging flow never read it
protectionbooleanNofalsetrue / falseParsed, but the current upgrade check and charging flow never read it

Omitting both item_sources and matcher makes the entry never match, which is equivalent to not needing that item. Entries sharing the same item_sources are merged and accumulated while charging; entries with a matcher are independent of each other

Upgrade flow and GUI ​

  • Compute the target level first (current level + 1), then clamp it by max_level; the skill must be unlocked and upgrade.enabled must be true
  • Order: condition check → SkillPreUpgradeEvent (cancellable, success rate may be replaced) → cost check → charge → roll → apply the level or the failure penalty
  • Costs are charged before the roll, so a failed roll does not refund the currency and materials already charged (compensation is only attempted when the commit stage throws)
  • Player-visible feedback comes from the upgrade.* keys in lang/<language>.yml (for example upgrade.success, upgrade.failed, upgrade.insufficient_funds)

The upgrade GUI is rendered from the template named by upgrade.gui_template; the type you write on each slot decides its content:

Slot typeContent
skill_displaySkill icon and name, with level, success rate, and failure-penalty text as replacements
cost_currencyCurrency cost list; shows gui.upgrade_cost_free when there is no cost. Replacements %currencies%, %currency_count%
cost_materialMaterial cost list, one line per item showing "have/required" and colored by whether it is satisfied. Replacements %materials%, %material_count%, %missing_count%
success_rateSuccess-rate title, replacement %success_rate%
confirmConfirmation button; its icon and status text switch between upgrades-disabled, max-level, insufficient-materials, and ready. Clicking calls the same upgrade service as the command

The GUI and the upgrade flow share one quote function (preview), so the numbers you see always match what gets charged: the GUI renders costs from the state at render time, and clicking Upgrade re-quotes and charges from that result. The numbers agree while the player's state is unchanged; if the state moved in between (a material was consumed elsewhere, for example), the re-quote and actual charge win, and a shortfall fails the whole attempt without charging

Skill sources and tag limits in config.yml ​

You write both blocks below in plugins/EmakiSkills/config.yml; they control how skills are recognized and how many can be equipped

Equipment skill source switches ​

yaml
skill_sources:
  read_lore_skills: true
  read_pdc_skills: true
  require_lore_pdc_match: false
FieldTypeRequiredDefaultValuesDescription
skill_sources.read_lore_skillsbooleanNotruetrue / falseWhether to read skills from equipment lore
skill_sources.read_pdc_skillsbooleanNotruetrue / falseWhether to read skills from equipment PDC
skill_sources.require_lore_pdc_matchbooleanNofalsetrue / falseStrict mode. When enabled, only the lore∩PDC intersection for the same item and slot is kept; skills present on just one side do not apply

Keep this in mind: the config precheck warns when both sides are off, or when strict mode is on with only one side enabled

Tag equip limits ​

When a skill's tags match an entry here, you can equip at most that many skills carrying the tag:

yaml
skill_tags:
  equip_limits:
    ultimate: 1
    mobility: 2
FieldTypeRequiredDefaultValuesDescription
skill_tags.equip_limits.<tag>integerNonone (unlimited)> 0; <= 0 or non-integer values ignore the keyMaximum number of skills with that tag equipped at once. Tag names are id-normalized with - turned into _
tag_limitsmapNononeSame as aboveLegacy key. Read as a fallback when skill_tags.equip_limits is empty

With the config above, at most one ultimate skill and two mobility skills can be equipped at the same time. Tags not listed here are unlimited

Minimal example ​

yaml
id: fireball
enabled: true
display_name: '<red>Fireball'
description:
  - '<gray>Hurls a fireball forwards.'
icon_material: FIRE_CHARGE
mythic_skill: EmakiFireball
trigger_type: active
cooldown_ticks: 100
global_cooldown_ticks: 20
resource_costs:
  - type: ea-resource
    target_id: mana
    amount: 20
    operation: consume
    failure_message: '<red>Not enough mana.'