Skip to content

JavaScript Scripting

EmakiCooking registers a scripting module through the CoreLib scripting system. The module ID is cooking. Inside a script you obtain the module facade with emaki.module("cooking") to register cooking result rules and cooking complete hooks.

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

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

Obtaining the module

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

Probe methods

MethodReturnsDescription
available()booleanWhether the module is available.
ready()booleanWhether the module finished initialization.
apiVersion()stringEmakiCooking API version.
pluginName()stringPlugin name.

Cooking result rules

Result rules run before output delivery. They can replace or append outputs, replace or append actions, and cancel the delivery.

MethodReturnsDescription
registerResultRule(definition)booleanRegister a result rule.
registerResultRule(id, definition)booleanOverload: merge id into the definition, then register.
unregisterResultRule(id)voidUnregister a rule by id.
registeredResultRules()listReturn the list of registered result rule ids.

Rule definition fields

FieldTypeRequiredDefaultDescription
idstringyesnoneUnique rule id (normalized); registration fails when blank.
functionstringnomodifyCookingResultRule callback function name; execute also works.
priorityintno0Priority; lower runs first, ties broken by id.
stationsstring / listnoempty (all stations)Station types the rule applies to; station also works. fermenter / fermentation are normalized to fermentation_barrel.
recipeIdsstring / listnoempty (all recipes)Recipe ids the rule applies to; recipes also works.
timeoutMillislongnoengine defaultPer-call script timeout.

Rule callback ctx fields

FieldTypeDescription
ruleIdstringCurrent rule id.
recipeIdstringRecipe id.
recipeNamestringRecipe display name.
stationTypestringStation type.
playerUuidstringPlayer UUID.
playerNamestringPlayer name.
phasestringCurrent phase.
worldstringWorld name.
x / y / zintCoordinates.
inputslistInput ingredients consumed this time. Each item has source (item source shorthand) / amount (consumed count). Paths without explicit inputs (juicer serving, wok failure fallback, etc.) are an empty list.
outputslistCurrent output list, each item a Map.
actionslistCurrent action list.
placeholdersmapPlaceholders passed at delivery time.
traceslistTraces from previous rules, each with id / message.

Rule callback return fields

The return value must be an object; otherwise it only records a trace and does not change the outputs.

Return fieldTypeDescription
outputslistReplace the whole output list. Common keys per item: item_sources, amount.
extraResultslistAppend after the output list.
actionslistReplace the action list.
extraActionslistAppend actions.
cancelbooleanWhether to cancel delivery; stops subsequent rules.
messagestringMessage written to the trace.

Cooking complete hooks

Complete hooks fire after output delivery, for side effects such as broadcasts and statistics.

MethodReturnsDescription
onComplete(definition)booleanRegister a complete hook.
onComplete(id, definition)booleanOverload: merge id into the definition, then register.
unregisterCompleteHook(id)voidUnregister a complete hook by id.
registeredCompleteHooks()listReturn the list of registered complete hook ids.

Hook definition fields

FieldTypeRequiredDefaultDescription
idstringyesnoneUnique hook id; registration fails when blank.
functionstringnoonCookingCompleteCallback function name; execute also works.
stationsstring / listnoempty (all stations)Station types the hook applies to; station also works. fermenter / fermentation are normalized to fermentation_barrel.
recipeIdsstring / listnoempty (all recipes)Recipe ids the hook applies to; recipes also works.
timeoutMillislongnoengine defaultPer-call script timeout.

Complete hooks have no priority field; multiple hooks fire in id lexical order. The callback event fields are the same as the result rule ctx.

The hook callback may return { actions: [...] }, where actions is an array of action-line strings that the plugin runs in order through the CoreLib ActionExecutor. The action-line syntax matches the actions used in recipes, e.g. "sendmessage text=\"<green>...\"", "playsound sound=minecraft:... volume=1 pitch=1". A failure only logs a warning to the console and does not affect the completed cooking result. Note: these actions run only while the triggering player is online; they are skipped when the player is offline.

Placeholders available in action lines:

PlaceholderDescription
%cooking_recipe_id%Cooking recipe id.
%cooking_station_type%Station type.

Example returning actions:

js
function onCookingComplete(event) {
  return {
    actions: [
      "sendmessage text=\"<green>Cooking complete: %cooking_recipe_id%\"",
      "playsound sound=minecraft:entity.villager.yes volume=1 pitch=1"
    ]
  };
}

Full example

EmakiCooking ships the example script scripts/examples/cooking_reward.js:

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

  cooking.registerResultRule({
    id: "example_oven_bonus",
    station: "oven",
    function: "modifyCookingResult"
  });

  cooking.onComplete({
    id: "example_complete_notice",
    function: "onCookingComplete"
  });
}

function modifyCookingResult(ctx) {
  // ctx.inputs: ingredients consumed this time, each {source, amount} (empty for juicer serving and other input-less paths)
  const inputCount = (ctx.inputs || []).reduce(function (sum, it) { return sum + it.amount; }, 0);
  emaki.logger.info("Cooking result rule: station=" + ctx.stationType
    + ", inputs=" + (ctx.inputs ? ctx.inputs.length : 0) + " (" + inputCount + " items)");
  return {
    extraResults: [{
      item_sources: "minecraft:cookie",
      amount: 1
    }],
    message: "Example: oven yields one bonus cookie"
  };
}

function onCookingComplete(event) {
  emaki.logger.info("Cooking complete hook: recipe=" + event.recipeId + ", station=" + event.stationType + ", outputs=" + event.outputs.length);
}

Enabling extension scripts

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

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

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

Script debugging

When you enable the debug submodule named script, EmakiCooking writes the per-rule execution trace to the server console every time its JS rules run, which helps server administrators debug script rules.

Enable command:

text
/ec debug module script

Trace fields: rule id and message. Cooking rules change outputs / actions / cancellation rather than numeric values, so the trace has no before / after. This output goes to the server console for server administrators to debug; it is not shown to players.

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: rules and hooks have no effect but raise no error.
  • Result rules run in ascending priority order (lower first), and cancelling delivery stops subsequent rules.