Skip to content

CoreLib Actions

When EmakiAttribute is enabled, it adds attribute, resource, tag, and sync stages to the CoreLib action registry. Use them anywhere CoreLib pipelines are accepted: Forge/Strengthen/Cooking/Skills/Item action lists, CoreLib pipeline templates, or pipelines triggered by other plugins through the CoreLib pipeline engine.

NOTE

This page documents only the stages registered by EmakiAttribute. CoreLib's own message, command, economy, and item stages are documented in CoreLib Actions. Current stage IDs use only the canonical names below; historical aliases are no longer registered. The old attributedamage is now written attribute_damage; the other stage IDs are unchanged.

Which entity is affected comes from the source: use self for the caster, or player_by_name for a named player.

Stage ID reference

Stage IDPurposeTarget requirement
attribute_damageApplies attribute-typed custom damage to the target.REQUIRED_ENTITY
attribute_addAdds a timed attribute modifier to the target.REQUIRED_ENTITY
attribute_setSets a timed attribute modifier on the target.REQUIRED_ENTITY
attribute_removeClears every timed modifier inside the target's effect_id group.REQUIRED_ENTITY
attribute_resource_addAdds to one of the target's resources.REQUIRED_ENTITY
attribute_resource_setSets one of the target's resources.REQUIRED_ENTITY
attribute_resource_removeRemoves from one of the target's resources.REQUIRED_ENTITY
attribute_resource_consumeConsumes one of the target's resources.REQUIRED_ENTITY
attribute_tag_addAdds timed attribute modifiers in bulk by tag.REQUIRED_ENTITY
attribute_tag_removeRemoves timed attribute modifiers by tag.REQUIRED_ENTITY
attribute_tag_clearClears timed attribute modifiers by tag.REQUIRED_ENTITY
attribute_syncRecomputes attribute and resource state for the target or everyone online.OPTIONAL
attribute_refreshDrops attribute caches, then recomputes for the target or everyone online.OPTIONAL

Apart from the two sync stages, attribute_damage and the resource stages accept only player targets; the timed-attribute and tag stages accept any living entity (including non-player mobs) and skip non-living targets. attribute_damage declares REQUIRED_ENTITY, but the implementation only handles Player: a non-player living target is skipped with not_player and takes no damage.

Upgrade notes: timed attribute behaviour changes

Two changes are visible to existing configuration:

  1. The tag entry point no longer produces composite effect IDs. attribute_tag_add effect_prefix=poison used to write separate unrelated top-level records such as poison:physical_attack and poison:movement_speed; they now all join a single poison effect group. Configuration that deleted one composite ID such as poison:physical_attack no longer matches and must use attribute_remove effect_id=poison instead. Conversely, attribute_remove effect_id=poison — which previously removed nothing — now works.
  2. Multi-group SET on the same attribute now has a defined winner. It used to depend on internal hash-map iteration order, so the same configuration could produce different results and could change as the map grew. The last write now wins (highest internal monotonic revision), and repeated runs are stable. /ea trace marks the losing entry as overridden by a higher revision.

Single-attribute configuration is unaffected and behaves exactly as before.

attribute_damage

Applies one Attribute damage instance to the target. Unlike CoreLib's built-in damage, this stage routes through EmakiAttribute, so the module's damage types, resistances, and combat snapshot all apply.

ParameterTypeRequiredDefaultDescription
amountDOUBLEYesBase damage.
typeSTRINGNo""Damage type ID. Empty uses EmakiAttribute's default damage type.
causeSTRINGNoCUSTOMBukkit EntityDamageEvent.DamageCause, such as CUSTOM, MAGIC, or ENTITY_ATTACK.
yaml
actions:
  - 'self | attribute_damage amount=25 type=physical cause=CUSTOM'
  - 'looking_at range=15 | attribute_damage amount=40 type=spell cause=MAGIC'

An unrecognised cause fails with INVALID_CONFIG rather than silently damaging with the wrong cause; a blank value means CUSTOM. Damage refused by the module's rules fails with REJECTED. On success the stage reports damage_type.

Timed attribute modifiers

effect_id identifies an effect group, not a single effect. Several attributes can share one effect_id: they coexist instead of overwriting each other, and attribute_remove clears the whole group at once. attribute_add and attribute_set decide whether that attribute's entry inside the group adds or overwrites, which is why they are separate stages rather than one stage with a mode argument.

yaml
actions:
  - 'self | attribute_add effect_id=buff_strength attribute=physical_attack value=10 duration_ticks=200t'
  - 'self | attribute_add effect_id=buff_strength attribute=physical_crit_rate value=5 duration_ticks=200t'
  - 'self | attribute_remove effect_id=buff_strength'

Both attribute_add calls above land in one group, and attribute_remove clears both attributes.

attribute_add / attribute_set

Both stages take the same arguments.

ArgumentTypeRequiredDefaultDescription
effect_idSTRINGYesEffect group id; reusing one id groups several attributes together.
attributeSTRINGYesAttribute ID; an unregistered id fails with INVALID_CONFIG.
valueDOUBLEYesModifier value; NaN and ±Inf fail with INVALID_CONFIG.
duration_ticksDURATIONYesDuration; accepts 20t, 1s, 1000ms; a bare number is ticks.
stack_modeSTRINGNothe attribute's temporary_stack_modeHow to combine with an existing entry for the same attribute in that group: REPLACE overwrites, STACK adds value and remaining duration. An undeclared value fails with INVALID_CONFIG.
yaml
actions:
  - 'self | attribute_add effect_id=forge_bonus attribute=physical_attack value=12 duration_ticks=10s'
  - 'self | attribute_set effect_id=arena_buff attribute=physical_attack value=30 duration_ticks=200t'
  - 'self | attribute_add effect_id=forge_bonus attribute=physical_attack value=3 duration_ticks=10s stack_mode=STACK'

attribute_remove

ArgumentTypeRequiredDefaultDescription
effect_idSTRINGYesEffect group id to clear; every attribute in that group is removed.
yaml
actions:
  - 'self | attribute_remove effect_id=arena_buff'

All three stages normalise effect_id and attribute as IDs. A blank effect_id fails with INVALID_CONFIG; a non-living target is skipped with not_living_entity (non-player mobs are supported). When the target carries no such group the stage is skipped rather than successful. On success they report effect_id, attribute, value, duration_ticks, status, affected_count, existed, and remaining_ticks, where status is one of APPLIED / REPLACED / STACKED / REMOVED.

Resources

The four resource stages modify a player's current resource value through EmakiAttribute's resource sync boundary. They share one parameter set.

ParameterTypeRequiredDefaultDescription
resourceSTRINGYesResource ID, such as health or mana.
amountDOUBLEYesOperation amount.
Stage IDArithmetic
attribute_resource_addcurrent + amount
attribute_resource_setset to amount
attribute_resource_removecurrent - amount, floored at 0
attribute_resource_consumeidentical to attribute_resource_remove

attribute_resource_consume and attribute_resource_remove compute the same value. Both IDs are kept because existing configuration refers to them by name; they share one implementation.

The final value is still clamped by the resource definition's sync rules, so add cannot exceed the maximum.

yaml
actions:
  - 'self | attribute_resource_add resource=mana amount=10'
  - 'self | attribute_resource_set resource=health amount=20'
  - 'self | attribute_resource_remove resource=health amount=5'
  - 'self | attribute_resource_consume resource=mana amount=20'

resource is normalised as an ID; an unloaded resource fails with INVALID_CONFIG. On success the stage reports resource, operation, amount, old_value, new_value, and current_max.

Tag-addressed timed modifiers

A tag names a group of attributes configured together, so one call can apply a whole buff without listing its parts.

attribute_tag_add

ParameterTypeRequiredDefaultDescription
tagSTRINGYesAttribute tag, case-insensitive.
valueDOUBLEYesModifier value applied to every matching attribute.
duration_ticksDURATIONYesHow long the modifiers last.
effect_prefixSTRINGNotag:<tag>Effect group id that every matched attribute joins. Empty uses tag:<tag>.
stack_modeSTRINGNo""Stack mode: REPLACE or STACK. Blank uses each attribute's own temporary_stack_mode; an unrecognised value fails with INVALID_CONFIG.
yaml
actions:
  - 'self | attribute_tag_add tag=DEBUFF value=-5 duration_ticks=5s effect_prefix=poison stack_mode=REPLACE'

Every attribute matched above lands in the single poison group, so attribute_remove effect_id=poison clears the whole set.

attribute_tag_remove / attribute_tag_clear

ParameterTypeRequiredDefaultDescription
tagSTRINGYesAttribute tag whose timed modifiers should be removed.
yaml
actions:
  - 'self | attribute_tag_remove tag=DEBUFF'
  - 'self | attribute_tag_clear tag=BUFF'

These two behave identically: both remove by tag. The duplication is carried over from the previous implementation. Deciding what clear was meant to do (drop every tag, presumably) would change behaviour that existing configuration may depend on, so it was left alone.

A blank tag fails with INVALID_CONFIG; when no attribute carries the tag, or the target has no matching effect, the stage is skipped rather than reported successful. All three stages report tag, effect_id, status, and count (how many attributes were matched and processed) on success.

Sync

Both stages take a single parameter; they differ in its default and in whether caches are dropped.

Stage IDParameterTypeDefaultDescription
attribute_syncallBOOLEANfalseRecomputes values without dropping caches. Defaults to the target only.
attribute_refreshallBOOLEANtrueDrops the module's caches, then recomputes. This is the stage to run after editing attribute configuration. Defaults to every online player.
yaml
actions:
  # Sync yourself only
  - 'self | attribute_sync'
  # Sync every online player; no target needed, so the source can be omitted
  - 'attribute_sync all=true'
  # After a config change: drop caches and recompute server-wide
  - 'attribute_refresh'
  # Drop caches and recompute for yourself only
  - 'self | attribute_refresh all=false'

Both declare OPTIONAL rather than REQUIRED_ENTITY, because all=true needs no target at all; the per-target path checks for a player itself and skips when there is none.

These are also the only stages in this module whose thread domain depends on their arguments: all=true walks the online-player list and runs on the server-global domain, while all=false touches a single entity. When all is written as a placeholder it cannot be read during planning, so the stage's own default decides the domain, which means attribute_refresh is planned as global.

On success the stage reports all, plus player when all=false.

Notes

  • Apart from attribute_sync all=true and attribute_refresh all=true, every stage on this page needs a player target.
  • To add or clear timed modifiers on a mob directly from a MythicMobs skill, use emaki_attribute_add, emaki_attribute_remove, emaki_attribute_add_tag, and emaki_attribute_clear_tag from MythicMobs Integration. Those are MythicMobs mechanics, not the CoreLib stages on this page.
  • duration_ticks is parsed as CoreLib DURATION: 20t, 1s, and 1000ms all work, and a plain number is ticks.
  • When the relevant service is not ready, the stage fails with MISSING_CONTEXT rather than skipping silently.