This page lists every node in the trigger language. It is generated from the same catalog the validator uses, so it cannot fall out of step with the game. The JSON Schema for whole scripts is at /schemas/v1/trigger-script.json.
Every node is a JSON object with a k naming its kind. Unknown properties are errors. Wherever a field takes an expression, you can write a bare number, string or boolean instead: 5 means {"k":"int","v":5}, 1.5 means {"k":"real","v":1.5}, "hi" means {"k":"str","v":"hi"}. A string is always text; to read a variable, use {"k":"var","name":"score"}. Wherever a field takes text, a bare string is shorthand for a one-part template.
Every example below passes validateTriggerScript when placed into this script (events go in events, expressions in conditions, actions in actions):
{
"version": 1,
"vars": [
{
"name": "score",
"type": "int"
},
{
"name": "squad",
"type": "unitGroup"
},
{
"name": "code",
"type": "string"
}
],
"regions": [
{
"id": "arena",
"x": 0,
"y": 0,
"w": 8,
"h": 8
}
],
"functions": [
{
"name": "double",
"params": [
{
"name": "n",
"type": "int"
}
],
"returns": "int",
"actions": [
{
"k": "return",
"value": {
"k": "mul",
"a": {
"k": "var",
"name": "n"
},
"b": {
"k": "int",
"v": 2
}
}
}
]
}
],
"hashtables": [
{
"name": "scores",
"valueType": "int"
}
],
"triggers": [
{
"id": "main",
"events": [
{
"k": "mapInit"
}
],
"actions": []
}
]
}Events
What makes a trigger fire. A trigger fires when any one of its events happens.
Map events
mapInit
Map initialisation. Fires once on the first tick, after every global initialiser.
Editor: the map starts
No fields.
{"k":"mapInit"}Time events
periodic
Every N ticks. Fires when (tick − offset) is a multiple of everyTicks, from tick offsetTicks on.
Editor: every ‹Interval (ticks)› ticks, phase-shifted by ‹Phase offset›
| Field | Type | Required | Description |
|---|---|---|---|
everyTicks | int (≥ 1) | yes | Period in ticks (20 = 1 second). |
offsetTicks | int | no | Phase offset in ticks. |
{"k":"periodic","everyTicks":1}atTick
At tick. Fires once on an exact tick.
Editor: at tick ‹Tick›
| Field | Type | Required | Description |
|---|---|---|---|
tick | int (≥ 0) | yes | Tick number. |
{"k":"atTick","tick":1}timerExpires
Timer expires. Fires when a named timer reaches zero.
Editor: timer ‹Timer› expires
| Field | Type | Required | Description |
|---|---|---|---|
timer | timerId | yes | Timer name. |
{"k":"timerExpires","timer":"wave_timer"}Region events
unitEntersRegion
Unit enters region. Fires for each unit whose tile moved into the region this tick. Units that start inside do not count.
Editor: a unit enters ‹Region› matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
region | regionId | yes | Region id. |
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"unitEntersRegion","region":"arena"}unitLeavesRegion
Unit leaves region. Fires for each unit that left the region this tick — including by dying or being removed (matched against its last snapshot).
Editor: a unit leaves ‹Region› matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
region | regionId | yes | Region id. |
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"unitLeavesRegion","region":"arena"}Unit events
unitDies
Unit dies. Fires when a unit or building dies. The filter is matched against the unit as it was at death (aliveOnly is ignored); event unit = the dead unit, other unit = killer.
Editor: a unit dies matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"unitDies"}unitTrained
Unit trained. Fires when production completes a unit.
Editor: a unit finishes training matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"unitTrained"}buildingComplete
Building completes. Fires when construction finishes.
Editor: a building completes matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"buildingComplete"}unitAttacked
Unit attacked. Fires when a unit takes an attack; event value = damage, other unit = attacker.
Editor: a unit is attacked matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"unitAttacked"}heroLevels
Hero levels up. Fires when a hero gains a level; event value = new level.
Editor: a hero gains a level matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"heroLevels"}Item events
itemPickedUp
Item picked up. Fires when a hero picks up an item.
Editor: an item is picked up — ‹Item›
| Field | Type | Required | Description |
|---|---|---|---|
itemId | itemId | no | Only this item id; absent = any. |
{"k":"itemPickedUp"}Player events
playerEliminated
Player eliminated. Fires when a seat is eliminated.
Editor: a player is eliminated — ‹Player›
| Field | Type | Required | Description |
|---|---|---|---|
player | playerNum | no | Only this seat; absent = any. |
{"k":"playerEliminated"}upgradeComplete
Upgrade completes. Fires when research completes; event text = upgrade id.
Editor: an upgrade completes — ‹Upgrade›
| Field | Type | Required | Description |
|---|---|---|---|
upgradeId | upgradeId | no | Only this upgrade; absent = any. |
{"k":"upgradeComplete"}playerChats
Player chats. Fires when a player sends a chat line; event text = the line.
Editor: player ‹Player› sends chat matching "‹Pattern›" (‹Match mode›)
| Field | Type | Required | Description |
|---|---|---|---|
pattern | string | no | Text to match; absent = any message. |
matchMode | 'exact' | 'prefix' | 'contains' | no | How pattern matches (default exact). |
player | playerNum | no | Only this seat. |
{"k":"playerChats","pattern":"-reset","matchMode":"prefix"}playerKeyPress
Player presses key. Fires when a player presses or releases a key (through lockstep); event text = key, value = 1 down / 0 up.
Editor: player ‹Player› presses ‹Key› (‹Key state›)
| Field | Type | Required | Description |
|---|---|---|---|
key | keyName | no | Key name, e.g. 'w', 'Space', 'ArrowUp'. |
state | 'down' | 'up' | no | down or up (absent = both). |
player | playerNum | no | Only this seat. |
{"k":"playerKeyPress","key":"Space","state":"down"}Variable events
variableChanges
Variable changes. Fires (in the cascade phase) when a GLOBAL variable is written with a different value.
Editor: variable ‹Variable› changes
| Field | Type | Required | Description |
|---|---|---|---|
name | varName | yes | Global variable name. |
{"k":"variableChanges","name":"score"}UI events
dialogButton
Dialog button clicked. Fires when a player clicks a trigger dialog button (arrives through lockstep); event value = button index.
Editor: a dialog button is clicked on ‹Dialog›, button ‹Button index›
| Field | Type | Required | Description |
|---|---|---|---|
dialogId | dialogId | no | Only this dialog. |
buttonIndex | int (≥ 0) | no | Only this 0-based button. |
{"k":"dialogButton"}Combat events
projectileHits
Projectile hits. Fires when a projectile strikes its target or a bomb detonates. Event unit = target, other unit = shooter, value = damage.
Editor: a projectile hits matching ‹Tag›
| Field | Type | Required | Description |
|---|---|---|---|
tag | string | no | Match the shooter's authored tag, the spell id, the shooter's unit type or the projectile type. |
{"k":"projectileHits"}Custom events
custom
Custom event. Fires when raiseEvent raises this name (same tick, capped cascade).
Editor: custom event ‹Event name› is raised
| Field | Type | Required | Description |
|---|---|---|---|
name | eventName | yes | Event name. |
{"k":"custom","name":"boss_down"}Cutscene events
cutsceneFinished
Cutscene finished. Fires when a cutscene ends. Event value: 0 played out, 1 skipped by every human viewer, 2 replaced by another scene, 3 stopped by a trigger.
Editor: cutscene ‹Scene› finishes
| Field | Type | Required | Description |
|---|---|---|---|
sceneId | sceneId | no | Only this scene. |
{"k":"cutsceneFinished"}Conditions and expressions
Values. A trigger condition is any expression; the trigger runs only when all of its conditions are true.
Literal expressions
int
Integer — returns int. An integer literal. Non-integers are truncated.
Editor: ‹Value›
| Field | Type | Required | Description |
|---|---|---|---|
v | number | yes | The value. |
{"k":"int","v":1}real
Real number — returns real. A real-number literal.
Editor: ‹Value›
| Field | Type | Required | Description |
|---|---|---|---|
v | number | yes | The value. |
{"k":"real","v":1}bool
Boolean — returns bool. true or false.
Editor: ‹Value›
| Field | Type | Required | Description |
|---|---|---|---|
v | bool | yes | The value. |
{"k":"bool","v":true}str
Text — returns string. A string literal.
Editor: "‹Value›"
| Field | Type | Required | Description |
|---|---|---|---|
v | string | yes | The value. |
{"k":"str","v":"text"}Geometry expressions
point
Point — returns point. A tile coordinate built from two numbers.
Editor: (‹Tile X›, ‹Tile Y›)
| Field | Type | Required | Description |
|---|---|---|---|
x | expr (number) | yes | Tile X. |
y | expr (number) | yes | Tile Y. |
{"k":"point","x":1,"y":1}distance
Distance — returns real. Euclidean tile distance; either side may be a unit or a point.
Editor: distance from ‹From› to ‹To›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (any) | yes | Left operand. |
b | expr (any) | yes | Right operand. |
{"k":"distance","a":1,"b":1}pointX
Point X — returns number. X of a point.
Editor: X of ‹Point›
| Field | Type | Required | Description |
|---|---|---|---|
p | expr (point) | yes | The point. |
{"k":"pointX","p":{"k":"regionCenter","region":"arena"}}pointY
Point Y — returns number. Y of a point.
Editor: Y of ‹Point›
| Field | Type | Required | Description |
|---|---|---|---|
p | expr (point) | yes | The point. |
{"k":"pointY","p":{"k":"regionCenter","region":"arena"}}regionCenter
Region centre — returns point. Integer centre tile of a region.
Editor: centre of ‹Region›
| Field | Type | Required | Description |
|---|---|---|---|
region | regionId | yes | Region id. |
{"k":"regionCenter","region":"arena"}randomPointInRegion
Random point in region — returns point. Random tile inside the region (always two PRNG draws).
Editor: a random point in ‹Region›
| Field | Type | Required | Description |
|---|---|---|---|
region | regionId | yes | Region id. |
{"k":"randomPointInRegion","region":"arena"}pointInRegion
Point in region — returns bool. True when the point (or unit) lies inside the region.
Editor: ‹Point› is inside ‹Region›
| Field | Type | Required | Description |
|---|---|---|---|
p | expr (point) | yes | Point or unit. |
region | regionId | yes | Region id. |
{"k":"pointInRegion","p":{"k":"regionCenter","region":"arena"},"region":"arena"}offsetPoint
Offset point — returns point. A point moved by (dx, dy) tiles.
Editor: ‹Point› offset by (‹Tiles X›, ‹Tiles Y›)
| Field | Type | Required | Description |
|---|---|---|---|
p | expr (point) | yes | Point or unit. |
dx | expr (number) | yes | Tiles X. |
dy | expr (number) | yes | Tiles Y. |
{"k":"offsetPoint","p":{"k":"regionCenter","region":"arena"},"dx":1,"dy":1}Unit expressions
nullUnit
No unit — returns unit. Entity id 0. Every property of it reads as a zero value.
Editor: no unit
No fields.
{"k":"nullUnit"}unitProp
Unit property — returns any. Read a property of a unit. A unit that died THIS tick answers from its death snapshot; otherwise a missing unit gives the zero value.
Editor: ‹Property› of ‹Unit›
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
prop | 'hp' | 'maxHp' | 'hpPercent' | 'mana' | 'maxMana' | 'x' | 'y' | 'level' | 'xp' | 'kills' | 'owner' | 'alive' | 'isHero' | 'isBuilding' | 'isFlying' | 'typeId' | yes | Property to read. |
{"k":"unitProp","unit":{"k":"eventUnit"},"prop":"hp"}unitPoint
Unit position — returns point. Tile position of a unit.
Editor: position of ‹Unit›
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
{"k":"unitPoint","unit":{"k":"eventUnit"}}entityByAid
Unit by authored id — returns unit. The placed entity carrying this authored id, or no unit.
Editor: the unit with authored id ‹Authored id›
| Field | Type | Required | Description |
|---|---|---|---|
aid | aid | yes | Authored id from the entity inspector. |
{"k":"entityByAid","aid":"north_gate"}Variable expressions
var
Variable — returns any. Read a variable: a trigger/function local, a function parameter, a loop variable or a global (resolved in that order).
Editor: ‹Variable›[‹Index›]
| Field | Type | Required | Description |
|---|---|---|---|
name | varName | yes | Variable name. |
index | expr (int) | no | Element index for an array variable. Out-of-range reads yield the zero value. |
{"k":"var","name":"score"}Arithmetic expressions
add
A + B — returns number. Sum. If either side is a string the two are concatenated.
Editor: ‹A› + ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (any) | yes | Left operand. |
b | expr (any) | yes | Right operand. |
{"k":"add","a":1,"b":1}sub
A − B — returns number. Difference.
Editor: ‹A› − ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (number) | yes | Left operand. |
b | expr (number) | yes | Right operand. |
{"k":"sub","a":1,"b":1}mul
A × B — returns number. Product.
Editor: ‹A› × ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (number) | yes | Left operand. |
b | expr (number) | yes | Right operand. |
{"k":"mul","a":1,"b":1}div
A ÷ B — returns number. Quotient. Division by zero yields 0 — never Infinity or NaN.
Editor: ‹A› ÷ ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (number) | yes | Left operand. |
b | expr (number) | yes | Right operand. |
{"k":"div","a":1,"b":1}mod
A mod B — returns number. Remainder (sign of A). Modulo by zero yields 0.
Editor: ‹A› mod ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (number) | yes | Left operand. |
b | expr (number) | yes | Right operand. |
{"k":"mod","a":1,"b":1}neg
Negate — returns number. Arithmetic negation.
Editor: −‹A›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (number) | yes | Left operand. |
{"k":"neg","a":1}abs
Absolute value — returns number. Absolute value.
Editor: |‹A›|
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (number) | yes | Left operand. |
{"k":"abs","a":1}min
Minimum — returns number. The smaller of A and B.
Editor: min(‹A›, ‹B›)
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (number) | yes | Left operand. |
b | expr (number) | yes | Right operand. |
{"k":"min","a":1,"b":1}max
Maximum — returns number. The larger of A and B.
Editor: max(‹A›, ‹B›)
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (number) | yes | Left operand. |
b | expr (number) | yes | Right operand. |
{"k":"max","a":1,"b":1}clamp
Clamp — returns number. A limited to [lo, hi]; reversed bounds are swapped.
Editor: clamp(‹A›, ‹Minimum›, ‹Maximum›)
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (number) | yes | Value to clamp. |
lo | expr (number) | yes | Lower bound. |
hi | expr (number) | yes | Upper bound. |
{"k":"clamp","a":{"k":"var","name":"score"},"lo":0,"hi":100}trunc
Truncate — returns int. Real to integer toward zero (Math.trunc) — the one real→int rule in the language.
Editor: trunc(‹A›)
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (real) | yes | Left operand. |
{"k":"trunc","a":1.5}Comparison expressions
eq
A = B — returns bool. Equality. Strings compare by code unit; groups element-wise; points by x then y.
Editor: ‹A› = ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (any) | yes | Left operand. |
b | expr (any) | yes | Right operand. |
{"k":"eq","a":1,"b":1}ne
A ≠ B — returns bool. Inequality.
Editor: ‹A› ≠ ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (any) | yes | Left operand. |
b | expr (any) | yes | Right operand. |
{"k":"ne","a":1,"b":1}lt
A < B — returns bool. Less than.
Editor: ‹A› < ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (any) | yes | Left operand. |
b | expr (any) | yes | Right operand. |
{"k":"lt","a":1,"b":1}le
A ≤ B — returns bool. Less than or equal.
Editor: ‹A› ≤ ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (any) | yes | Left operand. |
b | expr (any) | yes | Right operand. |
{"k":"le","a":1,"b":1}gt
A > B — returns bool. Greater than.
Editor: ‹A› > ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (any) | yes | Left operand. |
b | expr (any) | yes | Right operand. |
{"k":"gt","a":1,"b":1}ge
A ≥ B — returns bool. Greater than or equal.
Editor: ‹A› ≥ ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (any) | yes | Left operand. |
b | expr (any) | yes | Right operand. |
{"k":"ge","a":1,"b":1}Logic expressions
and
A and B — returns bool. Logical AND. Short-circuits: B is not evaluated when A is false.
Editor: ‹A› and ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (bool) | yes | Left operand. |
b | expr (bool) | yes | Right operand. |
{"k":"and","a":true,"b":true}or
A or B — returns bool. Logical OR. Short-circuits: B is not evaluated when A is true.
Editor: ‹A› or ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (bool) | yes | Left operand. |
b | expr (bool) | yes | Right operand. |
{"k":"or","a":true,"b":true}not
Not A — returns bool. Logical negation.
Editor: not ‹A›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (bool) | yes | Left operand. |
{"k":"not","a":true}Time expressions
tick
Game tick — returns int. The current simulation tick (20 per second) — the only clock in the language.
Editor: the game tick
No fields.
{"k":"tick"}rand
Random integer — returns int. Inclusive random integer from the synchronised game PRNG. Always consumes exactly one draw.
Editor: random ‹Minimum› to ‹Maximum›
| Field | Type | Required | Description |
|---|---|---|---|
min | expr (int) | yes | Lower bound (inclusive). |
max | expr (int) | yes | Upper bound (inclusive). |
{"k":"rand","min":1,"max":6}timerRemaining
Timer ticks left — returns int. Ticks until the timer expires (0 if not running).
Editor: ticks left on ‹Timer›
| Field | Type | Required | Description |
|---|---|---|---|
timer | timerId | yes | Timer name. |
{"k":"timerRemaining","timer":"wave_timer"}timerRunning
Timer is running — returns bool. True while the timer runs and is not paused.
Editor: ‹Timer› is running
| Field | Type | Required | Description |
|---|---|---|---|
timer | timerId | yes | Timer name. |
{"k":"timerRunning","timer":"wave_timer"}Player expressions
playerResource
Player's resource — returns int. Current stock of one resource.
Editor: ‹Player›'s ‹Resource›
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
resource | 'gold' | 'lumber' | 'stone' | 'oil' | yes | Resource kind. |
{"k":"playerResource","player":0,"resource":"gold"}playerPop
Player's population — returns int. Population in use.
Editor: ‹Player›'s population
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
{"k":"playerPop","player":0}playerMaxPop
Player's population cap — returns int. Population cap.
Editor: ‹Player›'s population cap
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
{"k":"playerMaxPop","player":0}playerAlive
Player is alive — returns bool. True while the seat has not been eliminated or defeated.
Editor: ‹Player› is still alive
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
{"k":"playerAlive","player":0}playerTeam
Player's team — returns int. Team id of the seat, or -1.
Editor: ‹Player›'s team
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
{"k":"playerTeam","player":0}playerHasUpgrade
Player has upgrade — returns bool. True once the seat has completed the research.
Editor: ‹Player› has researched ‹Upgrade›
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
upgradeId | upgradeId | yes | Upgrade id. |
{"k":"playerHasUpgrade","player":0,"upgradeId":"dwarf_forged_weapons_1"}isAllied
Players are allied — returns bool. True when seats A and B are on the same team.
Editor: ‹A› is allied with ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (player) | yes | Left operand. |
b | expr (player) | yes | Right operand. |
{"k":"isAllied","a":0,"b":0}isEnemy
Players are enemies — returns bool. True when seats A and B are not allied.
Editor: ‹A› is an enemy of ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (player) | yes | Left operand. |
b | expr (player) | yes | Right operand. |
{"k":"isEnemy","a":0,"b":0}Group expressions
unitsInRegion
Units in region — returns unitGroup. Sorted group of units whose tile is inside the region.
Editor: units in ‹Region› matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
region | regionId | yes | Region id. |
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"unitsInRegion","region":"arena"}unitsWithTag
Units with tag — returns unitGroup. Sorted group of placed entities sharing an authored tag.
Editor: units tagged ‹Tag› matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
tag | tag | yes | Authored tag. |
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"unitsWithTag","tag":"wave"}unitsOfPlayer
Units of player — returns unitGroup. Sorted group of units owned by the seat.
Editor: units owned by ‹Player› matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"unitsOfPlayer","player":0}unitsOfType
Units of type — returns unitGroup. Sorted group of units or buildings of one type id.
Editor: units of type ‹Unit type› matching ‹Filter›
| Field | Type | Required | Description |
|---|---|---|---|
unitTypeId | unitTypeId | yes | Unit or building type id. |
filter | filter | no | Optional unit filter; every set field is ANDed. aliveOnly defaults to true. |
{"k":"unitsOfType","unitTypeId":"dwarf_ironguard"}groupCount
Group size — returns int. Number of units in a group.
Editor: number of units in ‹Unit group›
| Field | Type | Required | Description |
|---|---|---|---|
group | expr (unitGroup) | yes | The group. |
{"k":"groupCount","group":{"k":"unitsInRegion","region":"arena"}}groupAt
Unit at index — returns unit. 0-based element of the sorted group; out of range gives no unit.
Editor: unit ‹Index› of ‹Unit group›
| Field | Type | Required | Description |
|---|---|---|---|
group | expr (unitGroup) | yes | The group. |
index | expr (int) | yes | 0-based index. |
{"k":"groupAt","group":{"k":"unitsInRegion","region":"arena"},"index":1}groupRandom
Random unit of group — returns unit. A random member (one PRNG draw, even for an empty group).
Editor: a random unit in ‹Unit group›
| Field | Type | Required | Description |
|---|---|---|---|
group | expr (unitGroup) | yes | The group. |
{"k":"groupRandom","group":{"k":"unitsInRegion","region":"arena"}}groupUnion
Group union — returns unitGroup. Members of A or B.
Editor: ‹A› together with ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (unitGroup) | yes | Left operand. |
b | expr (unitGroup) | yes | Right operand. |
{"k":"groupUnion","a":{"k":"unitsInRegion","region":"arena"},"b":{"k":"unitsInRegion","region":"arena"}}groupDiff
Group difference — returns unitGroup. Members of A not in B.
Editor: ‹A› except ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (unitGroup) | yes | Left operand. |
b | expr (unitGroup) | yes | Right operand. |
{"k":"groupDiff","a":{"k":"unitsInRegion","region":"arena"},"b":{"k":"unitsInRegion","region":"arena"}}groupHas
Group contains — returns bool. True when the unit is in the group.
Editor: ‹Unit group› contains ‹Unit›
| Field | Type | Required | Description |
|---|---|---|---|
group | expr (unitGroup) | yes | The group. |
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
{"k":"groupHas","group":{"k":"unitsInRegion","region":"arena"},"unit":{"k":"eventUnit"}}groupEmpty
Empty group — returns unitGroup. A group with no units.
Editor: an empty group
No fields.
{"k":"groupEmpty"}Event expressions
eventUnit
Triggering unit — returns unit. The unit the event is about (entered, died, trained, was attacked…). No unit when the event has none.
Editor: the triggering unit
No fields.
{"k":"eventUnit"}eventOtherUnit
Other unit — returns unit. The killer for unitDies, the attacker for unitAttacked, the shooter for projectileHits.
Editor: the other unit
No fields.
{"k":"eventOtherUnit"}eventPlayer
Triggering player — returns player. The seat the event is about, or -1.
Editor: the triggering player
No fields.
{"k":"eventPlayer"}eventValue
Event value — returns number. Numeric payload: dialog button index, hero level, damage, raised value.
Editor: the event value
No fields.
{"k":"eventValue"}eventString
Event text — returns string. String payload: upgrade id, item id, chat text, custom event name.
Editor: the event text
No fields.
{"k":"eventString"}UI expressions
counter
Counter value — returns number. Current value of an on-screen counter.
Editor: counter ‹Counter›
| Field | Type | Required | Description |
|---|---|---|---|
id | counterId | yes | Counter id. |
{"k":"counter","id":"lives"}Trigger expressions
triggerFireCount
Trigger fire count — returns int. How many times a trigger has fired.
Editor: times ‹Trigger› has fired
| Field | Type | Required | Description |
|---|---|---|---|
triggerId | triggerId | yes | Trigger id. |
{"k":"triggerFireCount","triggerId":"main"}Text expressions
concat
Concatenate — returns string. A joined with B as strings.
Editor: ‹A› joined with ‹B›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (string) | yes | Left operand. |
b | expr (string) | yes | Right operand. |
{"k":"concat","a":"text","b":"text"}toStr
To text — returns string. Value as text. Non-integers print with decimals places (default 2).
Editor: ‹Value› as text to ‹Decimal places› dp
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (any) | yes | Left operand. |
decimals | int (≥ 0, ≤ 6) | no | Fixed decimal places, 0..6. |
{"k":"toStr","a":1}subStr
Substring — returns string. 0-based slice; out-of-range start gives empty text.
Editor: substring of ‹String› from ‹Start index› length ‹Length›
| Field | Type | Required | Description |
|---|---|---|---|
text | expr (string) | yes | Source text. |
start | expr (int) | yes | Start index. |
length | expr (int) | no | Maximum length; absent = to the end. |
{"k":"subStr","text":"Hello world","start":0,"length":5}strLen
Text length — returns int. Length in UTF-16 code units.
Editor: length of ‹String›
| Field | Type | Required | Description |
|---|---|---|---|
text | expr (string) | yes | The text. |
{"k":"strLen","text":"text"}hashString
Hash text — returns int. Deterministic 32-bit FNV-1a hash.
Editor: hash of ‹String›
| Field | Type | Required | Description |
|---|---|---|---|
text | expr (string) | yes | The text. |
{"k":"hashString","text":"text"}Physics expressions
unitVelocity
Unit velocity — returns real. Kinematic velocity component or speed (tiles/tick); 0 without kinematics.
Editor: ‹Axis› velocity of ‹Unit›
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
axis | 'x' | 'y' | 'speed' | yes | Component to read. |
{"k":"unitVelocity","unit":{"k":"eventUnit"},"axis":"x"}Save codes expressions
verifySaveCode
Read save code — returns any. Validate a save code for this map. With field, returns that field (or 0); without, returns 1 for a valid code and 0 otherwise.
Editor: save code ‹Code› field ‹Field› (valid?)
| Field | Type | Required | Description |
|---|---|---|---|
code | expr (string) | yes | The code text. |
field | string | no | Field to extract; playerId returns the issuing seat. |
{"k":"verifySaveCode","code":{"k":"var","name":"code"}}Function expressions
call
Call function — returns any. Call a user-defined function that declares a return type and yield its return value. Arguments are evaluated left to right and coerced to the parameter types. Recursion past the depth cap yields the zero value.
Editor: ‹Function›(‹Arguments›)
| Field | Type | Required | Description |
|---|---|---|---|
fn | functionName | yes | Function name. |
args | exprList | no | Arguments, one per parameter, in order. |
{"k":"call","fn":"double","args":[2]}Hashtable expressions
hashtableGet
Hashtable value — returns any. Value stored under (key1, key2), or the zero value of the table type. Keys are integers or strings.
Editor: ‹Hashtable›[‹Parent key›][‹Child key›]
| Field | Type | Required | Description |
|---|---|---|---|
table | hashtableName | yes | Hashtable name. |
key1 | expr (any) | yes | Parent key (int or string). |
key2 | expr (any) | yes | Child key (int or string). |
{"k":"hashtableGet","table":"scores","key1":1,"key2":1}hashtableHas
Hashtable has key — returns bool. True when a value is stored under (key1, key2).
Editor: ‹Hashtable› has [‹Parent key›][‹Child key›]
| Field | Type | Required | Description |
|---|---|---|---|
table | hashtableName | yes | Hashtable name. |
key1 | expr (any) | yes | Parent key. |
key2 | expr (any) | yes | Child key. |
{"k":"hashtableHas","table":"scores","key1":1,"key2":1}hashtableCount
Hashtable size — returns int. Number of entries in the table, or under one parent key when key1 is set.
Editor: number of entries in ‹Hashtable› under ‹Parent key›
| Field | Type | Required | Description |
|---|---|---|---|
table | hashtableName | yes | Hashtable name. |
key1 | expr (any) | no | Parent key to count children of. |
{"k":"hashtableCount","table":"scores"}Actions
What a trigger does, run top to bottom.
Control flow actions
if
If / then / else. Run then when cond is true, else else.
Editor: if ‹Condition›
| Field | Type | Required | Description |
|---|---|---|---|
cond | expr (bool) | yes | Condition. |
then | actions | yes | Actions when true. |
else | actions | no | Actions when false. |
{"k":"if","cond":true,"then":[]}while
While. Repeat the body while cond holds, at most maxIterations (hard cap 10000) times per run.
Editor: while ‹Condition›
| Field | Type | Required | Description |
|---|---|---|---|
cond | expr (bool) | yes | Loop condition, checked before each iteration. |
body | actions | yes | Loop body. |
maxIterations | int (≥ 1, ≤ 10000) | no | Iteration cap (≤ 10000). |
{"k":"while","cond":true,"body":[]}forEachUnit
For each unit. Run the body once per unit of a group (snapshotted and sorted before the first iteration).
Editor: for each unit ‹Loop variable› in ‹Unit group›
| Field | Type | Required | Description |
|---|---|---|---|
group | expr (unitGroup) | yes | Group to iterate. |
varName | loopVar | yes | Loop variable receiving each unit id; an undeclared name becomes a local. |
body | actions | yes | Loop body. |
{"k":"forEachUnit","group":{"k":"unitsInRegion","region":"arena"},"varName":"u","body":[]}forEachInt
For each integer. Run the body for each integer from..to inclusive (at most 10000).
Editor: for ‹Loop variable› from ‹From› to ‹To›
| Field | Type | Required | Description |
|---|---|---|---|
varName | loopVar | yes | Loop variable; an undeclared name becomes a local. |
from | expr (int) | yes | First value. |
to | expr (int) | yes | Last value (inclusive). |
body | actions | yes | Loop body. |
{"k":"forEachInt","varName":"i","from":1,"to":1,"body":[]}wait
Wait. Suspend this trigger for N ticks (min 1) and resume at the next action. Locals and loop state survive, including across save/load. Not allowed inside functions.
Editor: wait ‹Ticks› ticks
| Field | Type | Required | Description |
|---|---|---|---|
ticks | expr (int) | yes | Ticks to wait. |
{"k":"wait","ticks":1}raiseEvent
Raise custom event. Fire the custom event of this name later in the same tick.
Editor: raise custom event ‹Event name› with value ‹Value› and text ‹Text›
| Field | Type | Required | Description |
|---|---|---|---|
name | eventName | yes | Event name. |
value | expr (number) | no | Event value payload. |
text | expr (string) | no | Event text payload (default: the name). |
{"k":"raiseEvent","name":"boss_down"}comment
Comment. Does nothing; documents the script.
Editor: // ‹Comment›
| Field | Type | Required | Description |
|---|---|---|---|
text | string | yes | Comment text. |
{"k":"comment","text":"text"}Variable actions
setVar
Set variable. Write a variable (local, parameter, loop or global). Writing a global with a new value raises variableChanges.
Editor: set ‹Variable›[‹Index›] to ‹Value›
| Field | Type | Required | Description |
|---|---|---|---|
name | varName | yes | Variable name. |
index | expr (int) | no | Element index for an array. |
value | expr (any) | yes | New value (coerced to the variable type). |
{"k":"setVar","name":"score","value":1}addVar
Add to variable. Add a number to a numeric variable.
Editor: add ‹Amount› to ‹Variable›[‹Index›]
| Field | Type | Required | Description |
|---|---|---|---|
name | varName | yes | Variable name. |
index | expr (int) | no | Element index for an array. |
delta | expr (number) | yes | Amount to add. |
{"k":"addVar","name":"score","delta":1}Trigger actions
enableTrigger
Enable/disable trigger. Turn a trigger on or off.
Editor: set trigger ‹Trigger› enabled to ‹Enabled›
| Field | Type | Required | Description |
|---|---|---|---|
triggerId | triggerId | yes | Trigger id. |
on | bool | yes | Enabled. |
{"k":"enableTrigger","triggerId":"main","on":true}runTrigger
Run trigger. Run another trigger's actions inline in this event context.
Editor: run trigger ‹Trigger› (checking its conditions: ‹Check conditions›)
| Field | Type | Required | Description |
|---|---|---|---|
triggerId | triggerId | yes | Trigger id. |
checkConditions | bool | no | Evaluate its conditions first (and count it as fired). |
{"k":"runTrigger","triggerId":"main"}stopTrigger
Stop trigger. Abandon the rest of this trigger. Not allowed inside functions (use return).
Editor: stop running this trigger
No fields.
{"k":"stopTrigger"}Function actions
callFunction
Call function. Call a user-defined function as a statement, optionally storing its return value.
Editor: call ‹Function›(‹Arguments›) and store the result in ‹Store result in›[‹Index›]
| Field | Type | Required | Description |
|---|---|---|---|
fn | functionName | yes | Function name. |
args | exprList | no | Arguments, one per parameter, in order. |
intoVar | varName | no | Variable receiving the return value (function must declare returns). |
intoIndex | expr (int) | no | Element index when intoVar is an array. |
{"k":"callFunction","fn":"double","args":[2]}return
Return. Leave the current function, yielding value. At trigger level (no value allowed) it stops the trigger.
Editor: return ‹Value›
| Field | Type | Required | Description |
|---|---|---|---|
value | expr (any) | no | Return value (functions with a return type). |
{"k":"return"}Hashtable actions
hashtableSet
Hashtable set. Store a value under (key1, key2). New keys past the table cap are dropped.
Editor: set ‹Hashtable›[‹Parent key›][‹Child key›] to ‹Value›
| Field | Type | Required | Description |
|---|---|---|---|
table | hashtableName | yes | Hashtable name. |
key1 | expr (any) | yes | Parent key (int or string). |
key2 | expr (any) | yes | Child key (int or string). |
value | expr (any) | yes | Value (coerced to the table type). |
{"k":"hashtableSet","table":"scores","key1":1,"key2":1,"value":1}hashtableRemove
Hashtable remove. Remove the value under (key1, key2).
Editor: remove ‹Hashtable›[‹Parent key›][‹Child key›]
| Field | Type | Required | Description |
|---|---|---|---|
table | hashtableName | yes | Hashtable name. |
key1 | expr (any) | yes | Parent key. |
key2 | expr (any) | yes | Child key. |
{"k":"hashtableRemove","table":"scores","key1":1,"key2":1}hashtableClear
Hashtable clear. Remove every entry, or only those under key1.
Editor: clear ‹Hashtable› under ‹Parent key›
| Field | Type | Required | Description |
|---|---|---|---|
table | hashtableName | yes | Hashtable name. |
key1 | expr (any) | no | Parent key to flush; absent = whole table. |
{"k":"hashtableClear","table":"scores"}Units actions
createUnits
Create units. Spawn N units (max 500) for a player at a point.
Editor: create ‹Count› × ‹Unit type› for ‹Player› at ‹At point› facing ‹Facing (degrees)›° and store them in ‹Store in›
| Field | Type | Required | Description |
|---|---|---|---|
unitTypeId | unitTypeId | yes | Unit type id (base game or a defOverrides clone). |
count | expr (int) | yes | How many. |
player | expr (player) | yes | Seat id (0-based) of the player. |
at | expr (point) | yes | Spawn tile. |
facing | expr (int) | no | Facing in degrees. |
intoVar | varName | no | unitGroup variable receiving the created ids. |
{"k":"createUnits","unitTypeId":"dwarf_ironguard","count":1,"player":0,"at":{"k":"regionCenter","region":"arena"}}removeUnit
Remove unit. Remove a unit outright — no death, corpse or bounty.
Editor: remove ‹Unit› from the game
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
{"k":"removeUnit","unit":{"k":"eventUnit"}}killUnit
Kill unit. Kill a unit through the normal death path.
Editor: kill ‹Unit›
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
{"k":"killUnit","unit":{"k":"eventUnit"}}setUnitHp
Set unit HP. Set HP (clamped to 0..max).
Editor: set HP of ‹Unit› to ‹Value› (as a percentage: ‹Value is a percentage›)
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
value | expr (number) | yes | HP or percentage. |
percent | bool | no | Treat value as a percentage of max HP. |
{"k":"setUnitHp","unit":{"k":"eventUnit"},"value":1}setUnitMana
Set unit mana. Set mana (clamped).
Editor: set mana of ‹Unit› to ‹Value›
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
value | expr (number) | yes | Mana. |
{"k":"setUnitMana","unit":{"k":"eventUnit"},"value":1}setUnitOwner
Change owner. Give a unit to another seat.
Editor: give ‹Unit› to ‹Player›
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
player | expr (player) | yes | Seat id (0-based) of the player. |
{"k":"setUnitOwner","unit":{"k":"eventUnit"},"player":0}setUnitInvulnerable
Set invulnerable. Toggle invulnerability.
Editor: set ‹Unit› invulnerable to ‹Invulnerable›
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
on | bool | yes | Invulnerable. |
{"k":"setUnitInvulnerable","unit":{"k":"eventUnit"},"on":true}moveUnit
Move unit instantly. Teleport a unit to a tile.
Editor: move ‹Unit› to ‹To point›
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
to | expr (point) | yes | Destination tile. |
{"k":"moveUnit","unit":{"k":"eventUnit"},"to":{"k":"regionCenter","region":"arena"}}Group actions
addUnitToGroup
Add unit to group. Add a unit to a unitGroup variable.
Editor: add ‹Unit› to ‹Group variable›
| Field | Type | Required | Description |
|---|---|---|---|
varName | varName | yes | unitGroup variable. |
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
{"k":"addUnitToGroup","varName":"squad","unit":{"k":"eventUnit"}}removeUnitFromGroup
Remove unit from group. Remove a unit from a unitGroup variable.
Editor: remove ‹Unit› from ‹Group variable›
| Field | Type | Required | Description |
|---|---|---|---|
varName | varName | yes | unitGroup variable. |
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
{"k":"removeUnitFromGroup","varName":"squad","unit":{"k":"eventUnit"}}clearGroup
Clear group. Empty a unitGroup variable.
Editor: clear ‹Group variable›
| Field | Type | Required | Description |
|---|---|---|---|
varName | varName | yes | unitGroup variable. |
{"k":"clearGroup","varName":"squad"}Orders actions
order
Order units. Issue an order to a group, applied inside the tick (never through lockstep).
Editor: order ‹Units› to ‹Order› at ‹Target point› targeting ‹Target unit› (queued: ‹Queue behind current order›)
| Field | Type | Required | Description |
|---|---|---|---|
units | expr (unitGroup) | yes | Units to order (a single unit also works). |
order | 'move' | 'attack_move' | 'attack' | 'stop' | 'hold' | 'patrol' | 'follow' | yes | Order kind. |
to | expr (point) | no | Target tile for move / attack_move / patrol. |
target | expr (unit) | no | Target unit for attack / follow. |
queue | bool | no | Queue after current orders. |
{"k":"order","units":{"k":"unitsInRegion","region":"arena"},"order":"attack_move","to":{"k":"regionCenter","region":"arena"}}Economy actions
setResource
Set resource. Set a player's resource stock (rounded, ≥ 0).
Editor: set ‹Player›'s ‹Resource› to ‹Value›
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
resource | 'gold' | 'lumber' | 'stone' | 'oil' | yes | Resource kind. |
value | expr (int) | yes | New amount. |
{"k":"setResource","player":0,"resource":"gold","value":1}addResource
Add resource. Add to a player's resource stock (rounded, ≥ 0).
Editor: give ‹Player› ‹Amount› ‹Resource›
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
resource | 'gold' | 'lumber' | 'stone' | 'oil' | yes | Resource kind. |
delta | expr (int) | yes | Amount to add (negative subtracts). |
{"k":"addResource","player":0,"resource":"gold","delta":1}setAlliance
Set alliance. Ally B to A's team, or put B back on its own team.
Editor: set ‹A› and ‹B› allied to ‹Allied›
| Field | Type | Required | Description |
|---|---|---|---|
a | expr (player) | yes | Left operand. |
b | expr (player) | yes | Right operand. |
allied | bool | yes | Allied. |
{"k":"setAlliance","a":0,"b":0,"allied":true}setBuildableRegion
Restrict building. Limit where a seat may build: a list of regions, [] for nowhere, or null to restore the default.
Editor: restrict building for ‹Player› to ‹Regions›
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
regions | regionId[] | null | yes | Region ids, or null. |
{"k":"setBuildableRegion","player":0,"regions":["arena"]}Outcome actions
victory
Victory. Declare a seat victorious.
Editor: declare victory for ‹Player›
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
{"k":"victory","player":0}defeat
Defeat. Declare a seat defeated.
Editor: declare defeat for ‹Player›
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
{"k":"defeat","player":0}Timers actions
startTimer
Start timer. Start (or restart) a named timer.
Editor: start timer ‹Timer› for ‹Ticks› ticks (repeating: ‹Repeating›)
| Field | Type | Required | Description |
|---|---|---|---|
timer | timerId | yes | Timer name. |
ticks | expr (int) | yes | Duration in ticks (≥ 1). |
periodic | bool | no | Restart on expiry. |
{"k":"startTimer","timer":"wave_timer","ticks":1}pauseTimer
Pause timer. Pause a timer.
Editor: pause timer ‹Timer›
| Field | Type | Required | Description |
|---|---|---|---|
timer | timerId | yes | Timer name. |
{"k":"pauseTimer","timer":"wave_timer"}resumeTimer
Resume timer. Resume a paused timer.
Editor: resume timer ‹Timer›
| Field | Type | Required | Description |
|---|---|---|---|
timer | timerId | yes | Timer name. |
{"k":"resumeTimer","timer":"wave_timer"}stopTimer
Stop timer. Stop and delete a timer.
Editor: stop timer ‹Timer›
| Field | Type | Required | Description |
|---|---|---|---|
timer | timerId | yes | Timer name. |
{"k":"stopTimer","timer":"wave_timer"}UI actions
showText
Show text. Show a text banner, resolved in the sim.
Editor: show ‹Text› to ‹Shown to› for ‹Duration (ticks)› ticks
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
text | text | yes | Text template (a bare string is accepted). |
durationTicks | int (≥ 1) | no | Display time in ticks (default 100). |
{"k":"showText","players":null,"text":"Hello"}clearText
Clear text. Clear banners for these seats (null = all).
Editor: clear on-screen text for ‹Shown to›
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
{"k":"clearText","players":null}setCounter
Set counter. Create or update an on-screen counter.
Editor: set counter ‹Counter id› — ‹Label› — to ‹Value› for ‹Shown to› at position ‹Sort position›
| Field | Type | Required | Description |
|---|---|---|---|
id | counterId | yes | Counter id. |
label | text | yes | Label template. |
value | expr (number) | yes | Value. |
players | number[] | null | no | Seats that see this, or null/absent for everyone. |
order | int | no | Sort position. |
{"k":"setCounter","id":"lives","label":"Hello","value":1}removeCounter
Remove counter. Remove a counter.
Editor: remove counter ‹Counter id›
| Field | Type | Required | Description |
|---|---|---|---|
id | counterId | yes | Counter id. |
{"k":"removeCounter","id":"lives"}setLeaderboardTitle
Leaderboard title. Set the leaderboard title ("" hides it).
Editor: set the leaderboard title to ‹Title› for ‹Shown to›
| Field | Type | Required | Description |
|---|---|---|---|
title | text | yes | Title template. |
players | number[] | null | no | Seats that see this, or null/absent for everyone. |
{"k":"setLeaderboardTitle","title":"Hello"}setLeaderboardRow
Leaderboard row. Create or update a leaderboard row.
Editor: set leaderboard row ‹Row id› — ‹Label› — to ‹Value› at position ‹Sort position›
| Field | Type | Required | Description |
|---|---|---|---|
rowId | rowId | yes | Row id. |
label | text | yes | Label template. |
value | expr (number) | yes | Value. |
order | int | no | Sort position. |
{"k":"setLeaderboardRow","rowId":"p1","label":"Hello","value":1}removeLeaderboardRow
Remove leaderboard row. Remove a leaderboard row.
Editor: remove leaderboard row ‹Row id›
| Field | Type | Required | Description |
|---|---|---|---|
rowId | rowId | yes | Row id. |
{"k":"removeLeaderboardRow","rowId":"p1"}clearLeaderboard
Clear leaderboard. Remove every row and the title.
Editor: clear the leaderboard
No fields.
{"k":"clearLeaderboard"}showDialog
Show dialog. Open a modal dialog; clicks fire dialogButton.
Editor: show dialog ‹Dialog id› titled ‹Title›, saying ‹Body›, with buttons ‹Buttons›, to ‹Shown to›
| Field | Type | Required | Description |
|---|---|---|---|
dialogId | dialogId | yes | Dialog id. |
title | text | yes | Title template. |
body | text | yes | Body template. |
buttons | textList | yes | Button labels (at least one). |
players | number[] | null | yes | Seats that see this, or null for everyone. |
{"k":"showDialog","dialogId":"menu","title":"Choose","body":"Pick a reward.","buttons":["Gold","Lumber"],"players":null}hideDialog
Hide dialog. Close a dialog.
Editor: hide dialog ‹Dialog id›
| Field | Type | Required | Description |
|---|---|---|---|
dialogId | dialogId | yes | Dialog id. |
{"k":"hideDialog","dialogId":"menu"}ping
Ping minimap. Ping a tile on the minimap.
Editor: ping ‹At point› for ‹Shown to› in ‹Colour› for ‹Duration (ticks)› ticks
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
at | expr (point) | yes | Tile to ping. |
colorHex | colorHex | no | Colour (default #ffcc00). |
durationTicks | int (≥ 1) | no | Duration in ticks (default 60). |
{"k":"ping","players":null,"at":{"k":"regionCenter","region":"arena"}}playSound
Play sound. Play a sound effect (base game or map custom sound).
Editor: play sound ‹Sound› for ‹Shown to›
| Field | Type | Required | Description |
|---|---|---|---|
soundId | soundId | yes | Sound id. |
players | number[] | null | yes | Seats that see this, or null for everyone. |
{"k":"playSound","soundId":"victory","players":null}createUIFrame
Create UI frame. Create or replace a declarative HUD frame.
Editor: create UI frame ‹Frame ID› at ‹Anchor› (‹X offset (px)›, ‹Y offset (px)›) size ‹Width (px)›×‹Height (px)› titled ‹Title› saying ‹Text› progress ‹Progress 0..1› in ‹Progress colour› styled ‹Style› for ‹Shown to› visible ‹Visible›
| Field | Type | Required | Description |
|---|---|---|---|
frameId | frameId | yes | Frame id. |
anchor | 'top_left' | 'top_center' | 'top_right' | 'center_left' | 'center' | 'center_right' | 'bottom_left' | 'bottom_center' | 'bottom_right' | yes | Screen anchor. |
x | expr (number) | yes | X offset from the anchor (px). |
y | expr (number) | yes | Y offset from the anchor (px). |
width | expr (number) | yes | Width (px). |
height | expr (number) | yes | Height (px). |
title | text | no | Title template. |
text | text | no | Body template. |
progress | expr (real) | no | Progress bar fill 0..1. |
progressColor | colorHex | no | Progress bar colour. |
style | uiStyle | no | Visual style overrides. |
players | number[] | null | no | Seats that see this, or null/absent for everyone. |
visible | bool | no | Visible (default true). |
{"k":"createUIFrame","frameId":"hud","anchor":"top_left","x":1,"y":1,"width":1,"height":1}updateUIFrame
Update UI frame. Update fields of an existing frame.
Editor: update UI frame ‹Frame ID› title ‹Title› text ‹Text› progress ‹Progress 0..1› colour ‹Progress colour› visible ‹Visible›
| Field | Type | Required | Description |
|---|---|---|---|
frameId | frameId | yes | Frame id. |
title | text | no | Title template. |
text | text | no | Body template. |
progress | expr (real) | no | Progress 0..1. |
progressColor | colorHex | no | Progress bar colour. |
visible | bool | no | Visible. |
{"k":"updateUIFrame","frameId":"hud"}destroyUIFrame
Destroy UI frame. Remove a frame.
Editor: destroy UI frame ‹Frame ID›
| Field | Type | Required | Description |
|---|---|---|---|
frameId | frameId | yes | Frame id. |
{"k":"destroyUIFrame","frameId":"hud"}clearUIFrames
Clear UI frames. Remove every frame.
Editor: clear all UI frames for ‹Shown to›
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | no | Seats that see this, or null/absent for everyone. |
{"k":"clearUIFrames"}setQuest
Set quest. Create or update a quest-log entry.
Editor: set quest ‹Quest ID› "‹Title›" to ‹State›: ‹Description› icon ‹Icon› at position ‹Sort position›
| Field | Type | Required | Description |
|---|---|---|---|
questId | questId | yes | Quest id. |
title | text | yes | Title template. |
description | text | yes | Description template. |
state | 'active' | 'completed' | 'failed' | yes | Quest state. |
icon | string | no | Icon key. |
order | int | no | Sort position. |
{"k":"setQuest","questId":"main_quest","title":"Defend the gate","description":"Survive ten waves.","state":"active"}clearQuests
Clear quests. Remove every quest.
Editor: clear all quests
No fields.
{"k":"clearQuests"}Cutscene actions
playCutscene
Play cutscene. Start a map scene for these seats; the sim records only the start.
Editor: play cutscene ‹Scene› for ‹Shown to›
| Field | Type | Required | Description |
|---|---|---|---|
sceneId | sceneId | yes | Scene id. |
players | number[] | null | yes | Seats that see this, or null for everyone. |
{"k":"playCutscene","sceneId":"intro","players":null}stopCutscene
Stop cutscene. End running cutscenes for these seats.
Editor: stop the cutscene playing for ‹Shown to›
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
{"k":"stopCutscene","players":null}Camera actions
cameraPan
Pan camera. Pan the camera to a point over a duration.
Editor: pan camera for ‹Shown to› to ‹Point› over ‹Duration (ticks)› ticks
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
to | expr (point) | yes | Target tile. |
durationTicks | int (≥ 0) | no | Pan duration in ticks. |
{"k":"cameraPan","players":null,"to":{"k":"regionCenter","region":"arena"}}cameraSetZoom
Set camera zoom. Change the camera zoom.
Editor: set camera zoom for ‹Shown to› to ‹Zoom› over ‹Duration (ticks)› ticks
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
zoom | expr (real) | yes | Zoom factor. |
durationTicks | int (≥ 0) | no | Transition in ticks. |
{"k":"cameraSetZoom","players":null,"zoom":1.5}cameraLock
Lock camera. Lock the camera to a unit or a point.
Editor: lock camera for ‹Shown to› to ‹Follow unit› at ‹Hold point›
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
unit | expr (unit) | no | Unit to follow. |
at | expr (point) | no | Point to hold. |
{"k":"cameraLock","players":null,"unit":{"k":"eventUnit"}}cameraUnlock
Unlock camera. Release a camera lock.
Editor: unlock camera for ‹Shown to›
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
{"k":"cameraUnlock","players":null}cameraSetBounds
Camera bounds. Confine the camera to a region, or null to clear.
Editor: confine camera for ‹Shown to› to ‹Region›
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
region | regionId | null | yes | Region id, or null. |
{"k":"cameraSetBounds","players":null,"region":"arena"}cameraShake
Shake camera. Shake the camera.
Editor: shake camera for ‹Shown to› at ‹Intensity (0–1)› for ‹Duration (ticks)› ticks
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
intensity | expr (real) | yes | Shake intensity. |
durationTicks | int (≥ 0) | no | Duration in ticks. |
{"k":"cameraShake","players":null,"intensity":1.5}cameraReset
Reset camera. Clear locks, bounds and zoom overrides.
Editor: reset camera for ‹Shown to›
| Field | Type | Required | Description |
|---|---|---|---|
players | number[] | null | yes | Seats that see this, or null for everyone. |
{"k":"cameraReset","players":null}Physics actions
applyImpulse
Apply impulse. Give a unit a kinematic velocity.
Editor: apply velocity (‹Velocity X›, ‹Velocity Y›) to ‹Unit› with friction ‹Friction› bounce ‹Bounce› for ‹Duration (ticks)› ticks
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
vx | expr (real) | yes | Velocity X (tiles/tick). |
vy | expr (real) | yes | Velocity Y (tiles/tick). |
friction | expr (real) | no | Per-tick velocity multiplier. |
bounce | expr (real) | no | Restitution on collision. |
ticks | expr (int) | no | Maximum duration in ticks. |
{"k":"applyImpulse","unit":{"k":"eventUnit"},"vx":1.5,"vy":1.5}setUnitKinematics
Set kinematics. Tune kinematic parameters of a unit.
Editor: set kinematics of ‹Unit› friction ‹Friction› bounce ‹Bounce› stop below ‹Minimum speed›
| Field | Type | Required | Description |
|---|---|---|---|
unit | expr (unit) | yes | The unit (entity id). A dead or missing unit is harmless: reads give zero values, writes do nothing. |
friction | expr (real) | no | Per-tick velocity multiplier. |
bounce | expr (real) | no | Restitution on collision. |
minSpeedCutoff | expr (real) | no | Speed below which motion stops. |
{"k":"setUnitKinematics","unit":{"k":"eventUnit"}}Save codes actions
generateSaveCode
Generate save code. Encode named values into a tamper-evident code bound to this map, stored in a string variable.
Editor: generate save code for ‹Player› with ‹Data› into ‹Target variable›
| Field | Type | Required | Description |
|---|---|---|---|
player | expr (player) | yes | Seat id (0-based) of the player. |
toVar | varName | yes | String variable receiving the code. |
data | exprRecord | yes | Field name → value expression. |
{"k":"generateSaveCode","player":0,"toVar":"code","data":{"level":3}}Script structure
TriggerScript
| Field | Type | Required | Description |
|---|---|---|---|
version | int (≥ 1, ≤ 1) | yes | Always 1. |
vars | varDecls | yes | Global variables, initialised in order on map init. |
regions | regionDefs | yes | Named tile rectangles (RegionDef[]). |
triggers | triggerDefs | yes | Triggers (TriggerDef[]), evaluated in array order. |
saveCodeSalt | string | no | Binds save codes to this map; defaults to the map name. |
functions | functionDefs | no | User-defined functions (FunctionDef[]). |
hashtables | hashtableDecls | no | Declared hashtables (HashtableDecl[]). |
VarDecl
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Identifier: letters, digits and _, not starting with a digit or __. |
type | varType | yes | Value type. |
array | bool | no | Fixed-length array. |
arraySize | int (≥ 1) | no | Array length (globals ≤ 8192, locals ≤ 1024). |
init | expr (any) | no | Initial value (globals: at map init; locals: at each execution start). |
RegionDef
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Region id. |
x | int | yes | Top-left tile X. |
y | int | yes | Top-left tile Y. |
w | int (≥ 1) | yes | Width in tiles (≥ 1). |
h | int (≥ 1) | yes | Height in tiles (≥ 1). |
name | string | no | Editor label. |
TriggerDef
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Stable trigger id. |
name | string | no | Editor label. |
enabled | bool | no | Initially enabled (default true). |
runOnce | bool | no | Fire at most once. |
events | events | yes | Events (any one fires the trigger). |
conditions | exprList | no | Conditions, all of which must hold. They see globals only. |
locals | varDecls | no | Per-execution local variables; survive wait and save/load. |
actions | actions | yes | Actions, run top to bottom. |
FunctionDef
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Function identifier. |
description | string | no | Documentation. |
params | params | no | Typed parameters (≤ 16, scalars only). |
returns | varType | no | Return type; absent = returns nothing. |
locals | varDecls | no | Per-call locals. |
actions | actions | yes | Body. May not contain wait or stopTrigger. |
FunctionParam
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Parameter identifier. |
type | varType | yes | Parameter type. |
description | string | no | Documentation. |
HashtableDecl
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Hashtable identifier. |
valueType | varType | yes | Type every stored value is coerced to. |
maxEntries | int (≥ 1, ≤ 16384) | no | Entry cap (≤ 16384). |
description | string | no | Documentation. |
UnitFilter
| Field | Type | Required | Description |
|---|---|---|---|
players | intList | no | Owner must be one of these seats. |
ofPlayer | expr (player) | no | Owner must equal this seat. |
alliedTo | expr (player) | no | Owner must be allied to this seat. |
enemyOf | expr (player) | no | Owner must not be allied to this seat. |
unitTypeIds | unitTypeIdList | no | Unit/building type must be one of these. |
tags | stringList | no | Authored tag must be one of these. |
aliveOnly | bool | no | Only living units (default true). |
heroesOnly | bool | no | Only heroes. |
buildingsOnly | bool | no | Only buildings. |
excludeBuildings | bool | no | No buildings. |
flyingOnly | bool | no | Only flyers. |
excludeFlying | bool | no | No flyers. |
excluding | expr (unitGroup) | no | Drop these units. |
UIFrameStyle
| Field | Type | Required | Description |
|---|---|---|---|
backgroundColor | string | no | CSS colour. |
borderColor | string | no | CSS colour. |
textColor | string | no | CSS colour. |
fontSize | number | no | Font size (px). |
borderRadius | number | no | Corner radius (px). |
padding | number | no | Padding (px). |