Skip to content

EmakiItem ​

EmakiItem provides lightweight custom items, stable item IDs (the unique ID you assign each item in config), sets, trigger actions, auto update, and PlaceholderAPI support, and the sections below show which page covers each feature, what config.yml exposes, and how it works with other modules. Treat it as the starting point for equipment progression: create one item with a stable ID first, then hand it to Forge, Strengthen, Gem, Attribute, and Skills to keep building on it

Module facts ​

ItemValue
Module version2.8.16
Main command/emakiitem
Alias/ei
Hard dependencyEmakiCoreLib
Soft dependenciesEmakiAttribute, EmakiSkills, MythicMobs, PlaceholderAPI
Permissionsemakiitem.use, emakiitem.give, emakiitem.browse, emakiitem.inspect, emakiitem.update, emakiitem.reload, emakiitem.debug, emakiitem.admin

Pages ​

PageContents
CommandsListing and giving items, inspecting the held item and its components, refreshing items and sets, reload and debug
Definitions and SetsThe fields of items/*.yml and sets/*.yml, and how an item ID produces an ItemStack
Browser GUIThe two-level browser opened by /ei browse, pack.yml pack metadata, and slot types
TriggersRunning actions on interact, attack, projectile, block, and drop events
Update StrategyBringing items players already hold up to a changed definition
Repair SystemThe disabled state at zero durability and the material/currency repair flow
Cross-Module IntegrationItem source syntax when Attribute, Forge, Strengthen, Gem, Skills, or Cooking reference an item
MythicMobs IntegrationDropping EmakiItem items from MythicMobs Drops
PlaceholdersPlaceholderAPI output
CoreLib ActionsMain-hand update, redraw, repair, durability, and vanilla data component actions
APICreating, identifying, and querying items through EmakiItemApi, and extending custom effect types
Event APIBukkit events and interception points across the item flow

Core capabilities ​

CapabilityDescription
Stable item IDUses config IDs instead of display names
Item componentsConfigures material, name, lore, model, enchants, flags, durability, and more
Attribute outputCan provide attribute payloads to Attribute
Skill bindingCan expose skills or skill unlock data
Set systemGrants attributes, skills, or lore based on equipped piece count
TriggersRuns actions on interaction, combat, projectile, block, drop, and other events
Auto updateRefreshes item state on login, hand switch, inventory click, pickup, and similar cases
Repair systemItems enter a disabled state at zero durability and can be repaired with materials or currency
Browser GUIA two-level GUI browses every item by pack and takes pieces directly
ID aliases and migrationMaps renamed item IDs and can migrate configs and player inventories in bulk

Default runtime folder ​

text
plugins/EmakiItem/
├── config.yml
├── id_aliases.yml
├── items/
├── sets/
├── gui/
└── lang/

You write items into items/ and sets into sets/; gui/ holds the repair and two browser templates (repair_gui.yml, pack_browser_gui.yml, item_browser_gui.yml), and id_aliases.yml stores renamed item ID mappings

Every subdirectory of items/ is an item pack; drop a pack.yml in it to define how that pack looks in the browser, see Browser GUI

Main configuration ​

Before reading the tables, keep two points in mind. config.yml holds only global settings; each item's own behavior lives in its definition file. "Required" asks whether the plugin falls back on its own when a key is missing: every key below has a fallback, so all read "No". "Range" states the constraint the plugin actually enforces; "—" means the plugin performs no validation

Top-level settings ​

FieldTypeRequiredDefaultRangeDescription
versionstringNo"2.8.16"—Config structure marker maintained by the project's resource sync flow, not a feature switch. Falls back to 2.6.7 when absent
languagestringNozh_CN—Language file name, matching lang/<language>.yml. Falls back to zh_CN when absent
release_default_databooleanNotruetrue / falseWhether bundled default data such as items/ and sets/ is released at startup; when disabled only existing data is loaded and no missing sample is generated. This does not control config.yml or language files
yaml
# Shipped defaults
version: "2.8.16"
language: "zh_CN"
release_default_data: true

Usage example: switch to English and stop releasing sample data

yaml
language: "en_US"
release_default_data: false

data_directories ​

FieldTypeRequiredDefaultRangeDescription
data_directoriesobjectNo——Directory scan settings, applied to items/ and sets/
data_directories.max_depthintNo2>= 1 (the source applies max(1, value))Maximum recursive subdirectory depth, counting the data directory itself: 1 reads only .yml files at the directory root, 2 allows one level of subdirectories, 3 allows two. Directories beyond the limit are skipped with a warning
yaml
# Shipped defaults
data_directories:
  max_depth: 2

Usage example: allow two levels of subdirectories (for example items/<pack>/<subdir>/*.yml)

yaml
data_directories:
  max_depth: 3

set_bonus ​

FieldTypeRequiredDefaultRangeDescription
set_bonusobjectNo——Set bonus settings. Set definitions live in sets/*.yml; items declare their set and piece through their own config
set_bonus.enabledbooleanNotruetrue / falseWhether the set bonus system is enabled. When off, no set bonus is computed or applied
set_bonus.refresh_triggersobjectNo——Set refresh triggers. Equipment changes, inventory changes, and command refreshes recompute the currently worn/held piece count and bonuses; omitted entries are treated as true
set_bonus.refresh_triggers.joinbooleanNotruetrue / falseRefresh set state when a player joins
set_bonus.refresh_triggers.held_changebooleanNotruetrue / falseRefresh when the held item changes
set_bonus.refresh_triggers.inventory_clickbooleanNotruetrue / falseRefresh on inventory click
set_bonus.refresh_triggers.inventory_dragbooleanNotruetrue / falseRefresh on item drag
set_bonus.refresh_triggers.pickupbooleanNotruetrue / falseRefresh on item pickup
set_bonus.refresh_triggers.interactbooleanNotruetrue / falseRefresh on interaction
set_bonus.refresh_triggers.commandbooleanNotruetrue / falseAllow a set refresh when related EmakiItem commands run
yaml
# Shipped defaults
set_bonus:
  enabled: true
  refresh_triggers:
    join: true
    held_change: true
    inventory_click: true
    inventory_drag: true
    pickup: true
    interact: true
    command: true

Usage example: turn off the high-frequency inventory click and drag refreshes and keep only the low-frequency ones

yaml
set_bonus:
  refresh_triggers:
    inventory_click: false
    inventory_drag: false

item_state ​

FieldTypeRequiredDefaultRangeDescription
item_stateobjectNo——Custom item-state settings written to the emaki:item_state PDC and read/written by the item_state_* action stages and the API. The whole section is additive: leaving it untouched keeps the previous behavior
item_state.clampbooleanNotruetrue / falseWhether written values are clamped to the min/max declared in fields. When disabled only overflow protection remains, with no configurable clamping
item_state.fill_defaultsbooleanNotruetrue / falseWhether add uses the fields default as the starting value when the field is absent. When disabled a missing field is rejected outright (reason=missing_state)
item_state.fieldsmapNo{}—Field declarations keyed by state key name (lowercased on write). Undeclared fields are unaffected by clamping, defaults, and thresholds
item_state.migrationsmapNo{}—Migration steps per schema version; an empty map means no migration
item_state.preservationobjectNo——State preservation policy
item_state.derivationobjectNo——State-change-driven derived refreshes

item_state.fields ​

FieldTypeRequiredDefaultRangeDescription
item_state.fields.<key>objectNo——One field declaration; <key> is the state key name
item_state.fields.<key>.typestringNodoubleINTEGER / LONG / DOUBLE / BOOLEAN / STRING (case-insensitive)Field type. A blank or unrecognized type skips the whole field; min/max/thresholds only apply to numeric types (INTEGER, LONG, DOUBLE)
item_state.fields.<key>.defaultscalarNononeMust coerce to typeUsed as the starting value for add when the field is absent and fill_defaults is on. A value that cannot coerce means no default
item_state.fields.<key>.minnumberNononenumericLower clamp bound; only when clamp is on and the field is numeric
item_state.fields.<key>.maxnumberNononenumericUpper clamp bound
item_state.fields.<key>.thresholdsmapNo{}—Threshold set keyed by threshold id. At most the 64 smallest thresholds by ascending value are kept per field, regardless of write order; changing the set re-arms that field's once latch
item_state.fields.<key>.thresholds.<id>.valuenumberYesnonenumericThe threshold value. An entry without this key is dropped
item_state.fields.<key>.thresholds.<id>.oncebooleanNofalsetrue / falseWhether the reward fires only once until it is re-armed
item_state.fields.<key>.thresholds.<id>.reward_on_fallbooleanNofalsetrue / falseWhether a downward crossing also triggers the reward
item_state.fields.<key>.thresholds.<id>.actionslistNoempty—Actions run when the threshold is crossed
item_state.fields.<key>.thresholds.<id>.message_keystringNo""—Language key used for the threshold message
item_state.fields.<key>.thresholds.<id>.soundstringNo""—Sound played when the threshold is crossed
item_state.fields.<key>.thresholds.<id>.sound_volumedoubleNo1.0—Sound volume
item_state.fields.<key>.thresholds.<id>.sound_pitchdoubleNo1.0—Sound pitch
item_state.fields.<key>.thresholds.<id>.refresh_derivedbooleanNotruetrue / falseWhether this threshold runs a derived refresh after firing

item_state.migrations ​

FieldTypeRequiredDefaultRangeDescription
item_state.migrations.<key>objectNo——One migration step; <key> is only an identifier
item_state.migrations.<key>.fromintYesnone—Source schema version. The step is skipped when it is absent or when to <= from
item_state.migrations.<key>.tointYesnone> fromTarget schema version
item_state.migrations.<key>.renamemapNoempty—Field renames written as old_field: new_field; entries whose source equals their target are ignored
item_state.migrations.<key>.retypemapNoemptytarget type as in typeField type changes written as field: type
item_state.migrations.<key>.droplistNoempty—Field names to drop

item_state.preservation ​

FieldTypeRequiredDefaultRangeDescription
item_state.preservation.verify_rebuildbooleanNotruetrue / falseVerify state survives an item rebuild and backfill from the pre-rebuild snapshot when it is missing; it only writes when state was genuinely lost, so the normal path is a no-op
item_state.preservation.repair_on_pickupbooleanNofalsetrue / falseRepair damaged state metadata on pickup
item_state.preservation.repair_on_dropbooleanNofalsetrue / falseRepair damaged state metadata on drop
item_state.preservation.repair_on_tradebooleanNofalsetrue / falseRepair damaged state metadata on trade
item_state.preservation.repair_on_container_transferbooleanNofalsetrue / falseRepair damaged state metadata on container transfer
item_state.preservation.repair_on_joinbooleanNofalsetrue / falseRepair damaged state metadata when a player joins

item_state.derivation ​

FieldTypeRequiredDefaultRangeDescription
item_state.derivation.enabledbooleanNofalsetrue / falseMaster switch for derived refreshes. Off by default to avoid adding refresh overhead to existing servers
item_state.derivation.refresh_lorebooleanNotruetrue / falseRefresh set lore during a derived refresh
item_state.derivation.refresh_attributesbooleanNotruetrue / falseSync attributes during a derived refresh
item_state.derivation.scan_holderbooleanNotruetrue / falseAllow scanning online players to locate the item when holder information is missing
item_state.derivation.max_depthintNo21–8 (the source applies clamp(value, 1, 8))Maximum recursion depth for derived refreshes and threshold rewards, blocking self-triggering loops
yaml
# Shipped defaults
item_state:
  clamp: true
  fill_defaults: true
  preservation:
    verify_rebuild: true
    repair_on_pickup: false
    repair_on_drop: false
    repair_on_trade: false
    repair_on_container_transfer: false
    repair_on_join: false
  derivation:
    enabled: false
    refresh_lore: true
    refresh_attributes: true
    scan_holder: true
    max_depth: 2

Usage example: declare a kill counter with thresholds and migrate a legacy field by schema version

yaml
item_state:
  fields:
    kills:
      type: INTEGER
      default: 0
      min: 0
      max: 9999
      thresholds:
        novice:
          value: 10
          once: true
          message_key: "state.kills.novice"
          sound: "minecraft:entity.player.levelup"
          sound_volume: 1.0
          sound_pitch: 1.2
        veteran:
          value: 100
          actions:
            - 'send_message text="<gold>Kill streak reached.</gold>"'
  migrations:
    "1":
      from: 0
      to: 1
      rename:
        kill_count: kills
      retype:
        kills: LONG
      drop:
        - legacy_tag

proficiency_guard ​

FieldTypeRequiredDefaultRangeDescription
proficiency_guardobjectNo——Proficiency dispatch guard applied to damage_dealt / kill_entity / kill_player slot dispatch. Everything except dedupe_per_event defaults to disabled or unlimited, so existing gain rates are unchanged
proficiency_guard.dedupe_per_eventbooleanNotruetrue / falseDispatch one item definition at most once per event, fixing "the same definition sitting in several slots fires once per slot"
proficiency_guard.max_dispatches_per_eventintNo0>= 0 (the source applies max(0, value)); 0 means unlimitedMaximum dispatches per event
proficiency_guard.same_target_cooldown_secondsnumberNo0>= 0 (converted to milliseconds internally); 0 means no cooldownCooldown in seconds against the same target
proficiency_guard.daily_soft_capintNo0>= 0 (the source applies max(0, value)); 0 means no capDaily soft cap. Counts live in memory, reset on the server's local date change, and do not survive a restart
proficiency_guard.decay_factordoubleNo1.0(0, 1]; out-of-range or non-finite values fall back to 1.0Decay factor once the soft cap is exceeded. 1.0 means no decay (reject outright past the cap)
proficiency_guard.decay_minimum_ratiodoubleNo0.0[0, 1] (clamped by the source)Lower bound for the decayed pass probability
proficiency_guard.guarded_triggerslistNodamage_dealt, kill_entity, kill_player—Triggers governed by this section; an empty list falls back to the three defaults
yaml
# Shipped defaults
proficiency_guard:
  dedupe_per_event: true
  max_dispatches_per_event: 0
  same_target_cooldown_seconds: 0
  daily_soft_cap: 0
  decay_factor: 1.0
  decay_minimum_ratio: 0.0
  guarded_triggers:
    - "damage_dealt"
    - "kill_entity"
    - "kill_player"

Usage example: cap dispatches per event and add a 1-second cooldown against the same target

yaml
proficiency_guard:
  max_dispatches_per_event: 3
  same_target_cooldown_seconds: 1

mythicmobs ​

FieldTypeRequiredDefaultRangeDescription
mythicmobsobjectNo——MythicMobs integration settings. Skipped automatically when MythicMobs is not installed, without affecting other features
mythicmobs.enabledbooleanNotruetrue / falseMaster switch for the MythicMobs integration. When off no drop is registered
mythicmobs.dropsobjectNo——Custom drop settings
mythicmobs.drops.enabledbooleanNotruetrue / falseWhether the MythicMobs custom drop is registered
mythicmobs.drops.nameslistNoemakiitem, ei_item—Recognized drop names; falls back to the defaults when empty
yaml
# Shipped defaults
mythicmobs:
  enabled: true
  drops:
    enabled: true
    names:
      - "emakiitem"
      - "ei_item"

Usage example: expose only a custom drop name

yaml
mythicmobs:
  drops:
    names:
      - "emakiitem"

Interactions ​

Keep the split in mind: set_bonus.refresh_triggers controls set state refreshing, while item auto-update is controlled separately by update.triggers in an item definition; neither overrides the other

item_state.* applies to the emaki:item_state PDC partition (plugin-defined data, the hidden fields a plugin writes onto an item) and is read and written by the item_state_* action stages and the API. The whole section is additive: leave every key untouched and the behavior matches the previous version. proficiency_guard.* applies to slot dispatch for damage_dealt, kill_entity, and kill_player; everything except dedupe_per_event defaults to disabled or unlimited

Typical item lifecycle ​

  1. You define item IDs, material, name, lore, and components in items/
  2. Add Attribute stats, Skills, or set info when you need them
  3. Give the item out with a command
  4. A player equips or uses the item
  5. Item refreshes the item automatically at each trigger
  6. Forge / Strengthen / Gem then keep writing their own layers on top
  7. CoreLib rebuilds the final display

Relations with other modules ​

ModuleIntegration
EmakiAttributeItem writes base or set attributes
EmakiSkillsItem writes equipment skill IDs and forced equipment triggers. The PDC keys are owned by a standalone protocol module and do not depend on EmakiSkills being enabled
EmakiForgeForge can modify items created by EmakiItem
EmakiStrengthenStrengthen can strengthen EmakiItem equipment
EmakiGemGem can add sockets and inlay gems onto EmakiItem equipment
MythicMobsMythicMobs mobs can drop EmakiItem items through Drops