Skip to content

JavaScript Scripting

EmakiItem registers a scripting module through the CoreLib scripting system. The module ID is item (items is an equivalent alias). Inside a script you obtain the module facade with emaki.module("item") to query/create items and register runtime item definitions and item factories.

This page covers only the EmakiItem-specific script methods, registration fields, context and examples. For the generic scripting mechanism see CoreLib JavaScript Scripting.

Note: emaki.item in the CoreLib injection object is the context ItemStack helper, not the EmakiItem plugin API; the EmakiItem plugin API is obtained via emaki.module("item").

Always guard with available() before calling any business method. EmakiItem is a CoreLib softdepend.

Obtaining the module

js
function main(ctx) {
  const item = emaki.module("item");
  if (!item.available()) {
    return { skipped: true, message: "EmakiItem unavailable" };
  }
  // ...
  return true;
}

Probe methods

MethodReturnsDescription
available()booleanWhether the module is available.

The EmakiItem module facade only exposes available().

Queries and creation

MethodReturnsDescription
exists(id)booleanWhether the item definition exists.
create(id, amount)mapCreate an item and return an item summary. When amount > 0 it is clamped to [1,64]; when omitted or ≤ 0 the definition's default amount (amount field, default 1) is used.
identify(itemKey)stringResolve an ItemStack by context attribute key and identify its item id; empty string when none.
definitionIds()listReturn a sorted copy of all item definition ids (YAML + runtime).
displayName(id)stringItem display name.

Item summary Maps preserve the legacy type, amount, displayName, optional lore, and customModelData fields, and add schemaVersion, normalized item, and the complete components snapshot. Air or no item returns an empty Map.

These query methods read a snapshot captured when the module was instantiated, so they do not reflect registrations performed later in the same script invocation.

Runtime item definitions

Runtime definition Maps and YAML definitions use the same EmakiItemDefinitionParser, so item, components, set, condition, repair, update, actions, and the remaining business fields have the same behavior. override remains registration control only.

MethodReturnsDescription
registerDefinition(definition)booleanRegister a runtime item definition.
registerDefinition(id, definition)booleanOverload: merge id into the definition, then register.
unregisterDefinition(id)voidUnregister a definition by id.
registeredDefinitions()listReturn the list of runtime-registered definition ids.

Definition fields

FieldTypeRequiredDefaultDescription
idstringyesnoneNormalized item id; registration fails when blank.
overridebooleannofalseWhether to replace a YAML definition with the same id. This controls registration only.
itemmap/stringyesnoneShared base-item definition. Prefer a map containing source, amount, and components.
name_actions / lore_actionsstructurenoBusiness operation chains for name and lore.
effectslistnoThe same variables / ea_attribute / es_skill effects as YAML.
set / condition / repair / updatemapnoThe same business configuration as YAML definitions.
actionsmapnoTrigger actions such as give and interact.
js
item.registerDefinition({
  id: "js_event_sword",
  override: false,
  item: {
    source: "minecraft-diamond_sword",
    amount: 1,
    components: {
      "minecraft:custom_name": "<red>JS Event Sword</red>",
      "minecraft:lore": ["<gray>Registered at runtime by JavaScript</gray>"],
      "minecraft:enchantment_glint_override": true
    }
  },
  effects: [
    { type: "ea_attribute", ea_attributes: { attack_damage: 10 } }
  ]
});

Registration validates the item.source resolver and component values. Unavailable sources, unknown component IDs, or invalid values for supported components fail registration; known newer-version components are skipped with a warning. Successful registration clears the item factory cache.

Item factories

Factories are tried in priority order when creating an item; a JS function dynamically returns an item definition fragment.

MethodReturnsDescription
registerFactory(definition)booleanRegister an item factory.
registerFactory(id, definition)booleanOverload: merge id into the definition, then register.
unregisterFactory(id)voidUnregister a factory by id.
registeredFactories()listReturn the list of registered factory ids.
createFactory(id, amount)mapRetained method that currently always returns an empty Map; obtain factory output through the normal creation flow by item ID.

Factory definition fields

FieldTypeRequiredDefaultDescription
idstringyesnoneFactory id (normalized); registration fails when blank.
priorityintno0Priority; lower is tried first, ties broken by id.
functionstringnocreateFactory function name; execute also works.
timeoutMillislongnoengine defaultPer-call script timeout.

Factory function arguments

FieldTypeDescription
idstringRequested item id (normalized).
factoryIdstringFactory id.
amountintRequested amount (at least 1).
scriptstringScript path.
playerUuidstringInjected when any player is online (the first online player, not necessarily the requester).
playerNamestringInjected when any player is online.

The factory function must return an item definition fragment Map; otherwise it is treated as no match and returns null. The returned Map has its id filled in, then goes through definition parsing to build an ItemStack. Multiple factories are tried in priority order, and the first non-null result wins.

Trigger script context

When an item trigger action invokes a script, you can read the following placeholders and attribute via emaki.context:

AccessKeyDescription
emaki.context.placeholder("item_id")item_idItem id.
emaki.context.placeholder("item_trigger")item_triggerTrigger name.
emaki.context.placeholder("item_name")item_nameItem name.
emaki.context.attribute("item_id")item_idItem id (attribute form).

Trigger example

EmakiItem ships the trigger-style example script scripts/examples/item_right_click.js:

js
function main(ctx) {
  const item = emaki.module("item");
  const itemId = emaki.context.placeholder("item_id");
  const trigger = emaki.context.placeholder("item_trigger");
  if (emaki.player.exists()) {
    emaki.player.sendMessage("[EmakiJS] Item trigger script: " + itemId + " trigger=" + trigger + " item=" + item.available());
  }
  return {
    success: true,
    output: {
      item_id: String(itemId || ""),
      trigger: String(trigger || ""),
      item_available: item.available()
    }
  };
}

Registration example

EmakiItem ships the extension-style example script scripts/examples/item_runtime_definition.js:

js
function register() {
  const item = emaki.module("item");

  item.registerDefinition({
    id: "js_event_sword",
    item: {
      source: "minecraft-diamond_sword",
      components: {
        "minecraft:custom_name": "<red>JS Event Sword</red>",
        "minecraft:lore": [
          "<gray>Registered at runtime by JavaScript</gray>",
          "<yellow>Attack +10</yellow>"
        ]
      }
    },
    effects: [{
      type: "ea_attribute",
      ea_attributes: { attack_damage: 10 }
    }],
    actions: {
      give: ["message text=<gold>You received the JS Event Sword!</gold>"]
    }
  });

  item.registerFactory({
    id: "js_random_relic",
    priority: 10,
    function: "createRelic"
  });
}

function createRelic(ctx) {
  if (ctx.id !== "js_random_relic") {
    return null;
  }
  const roll = emaki.random.integer(0, 99);
  return {
    item: {
      source: "minecraft-nether_star",
      components: {
        "minecraft:custom_name": roll >= 50 ? "<light_purple>Shining Random Relic</light_purple>" : "<aqua>Random Relic</aqua>",
        "minecraft:lore": [
          "<gray>Generated dynamically by a JavaScript factory</gray>",
          "<dark_gray>roll=" + roll + "</dark_gray>"
        ]
      }
    },
    effects: [{ type: "variables", variables: { roll: roll } }]
  };
}

Enabling extension scripts

Put the script into CoreLib's global extension directory and reload:

text
plugins/EmakiCoreLib/scripts/extensions/global/item_runtime_definition.js
text
/corelib script reload

The example file is released to plugins/EmakiCoreLib/scripts/examples/ by default and is not auto-enabled.

Notes

  • Every registration method requires the CoreLib scripting system to be enabled; otherwise registration returns false or is silently skipped.
  • When CoreLib is missing the module degrades gracefully: queries return empty and registration returns false.
  • Factories run in ascending priority order (lower is tried first).
  • The item factory cache is cleared after a definition is registered or unregistered.