Skip to main content

Script (Entity Action Type)

Runs a script against one entity. Use it when the behaviour you want has no shape in JSON, such as picking a target out of a list, remembering something between calls, or branching on state Apoli has no condition for.

Type ID: apoli:script

Fields

FieldTypeDefaultDescription
scriptIdentifierrequiredThe script to run. Either an ID registered from KubeJS with ApoliEvents, or the path of a .js file shipped in a data pack at data/<namespace>/apoli/scripts/<path>.js, in which case the .js is part of the ID.
paramsNBToptionalValues handed to the script. Read them with event.params from KubeJS, or params inside a data pack script. This is how one script serves several powers.

Examples

Drain the nearest living entity within four blocks and heal for what you took. The whole search and pick is a few lines of JavaScript instead of a nested apoli:selector and apoli:if_else_list. The script goes in kubejs/server_scripts/vampire.js:

kubejs/server_scripts/vampire.js
ApoliEvents.entityAction('vampire:drain', event => {
  const player = event.entity
  const victim = event.level.getEntitiesWithin(player.boundingBox.inflate(4))
    .filter(e => e.living && e !== player)
    .sort((a, b) => a.distanceToSqr(player) - b.distanceToSqr(player))[0]

  if (!victim) return
  victim.attack(event.params.getFloat('damage'))
  player.heal(event.params.getFloat('heal'))
})
{
  "type": "apoli:action_on_key_press",
  "key": { "key": "key.origins.primary_active" },
  "cooldown": 60,
  "entity_action": {
    "type": "apoli:script",
    "script": "vampire:drain",
    "params": { "damage": 4.0, "heal": 2.0 }
  }
}

The same action can be written as a data pack file instead, so the behaviour ships inside the zip. The file body is the action, and ctx and params are already in scope. This one is data/vampire/apoli/scripts/drain.js:

data/vampire/apoli/scripts/drain.js
ctx.entity.heal(params.getFloat('heal'))
{
  "type": "apoli:script",
  "script": "vampire:drain.js",
  "params": { "heal": 2.0 }
}

Data pack scripts are disabled until an operator enables them. See the KubeJS page for how, and for what the sandbox allows.

note

This action needs KubeJS. Without it the type still loads and the pack still works, but the call logs once and does nothing. Scripts always run on the server.