Execute Command (Bi-Entity Action Type)

Runs a command as the actor, with the actor's and target's UUIDs substituted into it.

Executes a command on the server as the actor entity, replacing placeholders in the command string with the actor’s and target’s UUIDs first.

Type ID: apoli:execute_command

Fields

FieldTypeDefaultPurpose
commandStringrequiredThe command to run, without a leading /.
actor_selectorString"%a"The text replaced with the actor’s UUID.
target_selectorString"%t"The text replaced with the target’s UUID.
argumentsMacro ArgumentsoptionalValues for $(key) placeholders in command, including live resource values off either entity. See Macro arguments.

How it works

  • The command runs as the actor, at permission level 4 with output suppressed, so @s inside the command is the actor.
  • Every occurrence of actor_selector is replaced with the actor’s UUID and every occurrence of target_selector with the target’s UUID, before the command is parsed.
  • Change the placeholders when the defaults would collide with the command text — set actor_selector to "{actor}" and %a stays literal.
  • Setting a selector to "" disables that substitution.

Examples

Teleport the actor to the target:

"bientity_action": {
  "type": "apoli:execute_command",
  "command": "tp %a %t"
}

Give the actor an item, using a custom placeholder:

"bientity_action": {
  "type": "apoli:execute_command",
  "command": "give {actor} minecraft:gunpowder",
  "actor_selector": "{actor}"
}

Because the command runs as the actor, execute at is how you move execution to the target:

"bientity_action": {
  "type": "apoli:execute_command",
  "command": "execute at %t run summon minecraft:lightning_bolt"
}

Commands are far slower than the equivalent action types and skip Apoli’s own bookkeeping. Reach for apoli:damage, apoli:mount and friends first, and keep this for things Apoli has no action for.

Macro arguments

arguments fills $(key) placeholders in command before the command is parsed — the same shape a vanilla function macro uses, but done by Apoli, so it works on every version whether or not the game has function macros.

FieldTypeDefaultPurpose
storageIdentifieroptionalRead the values from this command storage.
pathString""A dot-separated key path inside that storage.
resourcesResource mapoptionalResource values read live off the entity the command runs as. See Resources in a command.
valuesNBT CompoundoptionalInline values. Applied last, so they win on a key clash.

Values are written out the way a function macro writes them: strings bare, numbers as numbers, compounds and lists as SNBT. If a $(key) in the command has no matching value, the command is skipped rather than run malformed — and Apoli logs one line naming the key that was missing, so a typo or an absent resource does not fail silently.

Resources in a command

resources puts apoli:resource and apoli:cooldown values straight into the command, read at the moment it runs. Write it as key: id:

"arguments": {
  "resources": {
    "mana": "example:mana"
  }
}

or as a plain list, which keys each resource by the last segment of its path — example:mana becomes $(mana):

"arguments": {
  "resources": ["example:mana"]
}

resources takes either an object of key: id pairs or a plain list of ids — never a mix. "resources": ["mana": "example:mana"] is not valid JSON, and a data pack file that contains it fails to parse in full, so the power never loads at all. Check the log for Couldn't parse data file if a power seems to do nothing.

When a $(key) cannot be filled the command is skipped and one line is logged naming the key and the reason — the power id is not loaded, the holder does not have it, or the power it names is not a resource. Turn on /apoli:dev_mode and that line is also sent to you in chat, every time, rather than once to the log.

Each key also gets _max and _min companions wherever the resource declares those bounds, so a readout needs no second lookup:

"entity_action": {
  "type": "apoli:execute_command",
  "command": "say mana: $(mana)/$(mana_max)",
  "arguments": {
    "resources": ["example:mana"]
  }
}

That prints mana: 7/10 in chat — which is the quickest way to watch a resource move while you are building the power that changes it. Turn on /apoli:dev_mode and every apoli:execute_command also echoes its finished command to you, macros already expanded, so you can see exactly what ran.

resources reads the actor. The bi-entity form adds target_resources, with the same two spellings, reading the target — so one command can print both sides:

"bientity_action": {
  "type": "apoli:execute_command",
  "command": "say %a has $(mana) mana, %t has $(hp) health left",
  "arguments": {
    "resources": ["example:mana"],
    "target_resources": ["example:hp"]
  }
}

apoli:store_data is the usual way to fill that storage — it writes id, pos, x/y/z and, for blocks, a state string that /setblock accepts as-is:

"entity_action": {
  "type": "apoli:execute_command",
  "command": "setblock $(pos) $(state)",
  "arguments": {
    "storage": "example:scratch",
    "path": "block"
  }
}