Units
The units on the map are objects. A Unit is one of the game's units as it is right
now. The entries of units. are UnitTypes, and u.type is one.
program(() => {
for (const u of unitsAt(locations.Pen, { owner: P2 })) u.hp = u.maxHp / 2;
const target = nearest(units.TerranMarine, locations.Beacon, { owner: P1 });
if (target) target.order("move", locations.Exit);
});
unitsAt(location, filter?),unitsOf(player, filter?)andallUnits(filter?)are what afor…ofruns over.first(filter?),nearest(type, location, filter?)andrandomUnit(filter?)give one unit, ornull. TypeScript wants theif (target)before the unit is used, ortarget?.kill().- A filter is
{ type, owner, at }, every part known when the script is applied.units.Men,units.Buildingsandunits.Factorieswork as a type, andCurrentPlayeras an owner. - Units come oldest first. A unit made in the place of one that died can come where the
dead one did. A dying unit is passed over, so
first()after akill()is the next one.
A unit's fields#
These can be read and written: hp, shields and energy in whole points; kills;
cooldown (both weapons and spells at once); resources (a mineral field's); buildTime
(frames left of its making); rank; matrix (frames of defensive matrix: a write gives
250 points of it, and 0 takes it away); the timers stim, ensnare, plague,
lockdown, maelstrom, irradiate and stasis; and invincible, hallucinated and
speedUpgrade. u.hp = 0 kills.
These can only be read: maxHp and maxShields, owner, type, x, y,
orderId, speed (how fast it is moving now), cloaked, burrowed, underAttack (the
game raised its under-attack alert for the unit within the last second or so, which it
does for a hit out of the player's view), hasTarget (its order is aimed at a unit) and
inTransport. The game keeps these to itself: writing a position ends the game with "EUD
not supported", and a cloak write shows nothing. The editor marks such a write as you
type.
A building finished early by writing buildTime keeps the hit points it had reached, and
a Terran building under a third burns, so heal it after.
What a unit can be told#
order("move" | "patrol" | "attack", location), the game's own Order, reaching this unit alone;give(player),kill(),remove();damage(n)andheal(n), or{ percent: 50 }of the type's maximum;locate(location), which centres a location on the unit so thatcreateUnitand the other actions can happen where it stands.
select(player, unit) or select(player, [a, b]) makes those units the player's
selection, as if they had clicked them. Functions take and return units
(function weakest(): Unit | null), and a == b says whether two are the same unit.
Units kept across a wait#
A variable can keep a unit across a sleep(). The game gives a dead unit's place to the
next unit made, so every use checks that the unit is still the one that was kept. Once it
is gone, its numbers read 0, its booleans false, and writing to it or telling it something
does nothing. if (u) asks whether it is still there.
A loop over units runs within one frame, so a sleep() or an await inside one is an
error. To deal with one unit at a time, find the next one after each sleep:
program(() => {
let u = first({ owner: P2, at: locations.Pen });
while (u) { u.kill(); sleep(seconds(1)); u = first({ owner: P2, at: locations.Pen }); }
});
Each loop and each pick looks through the game's units when its line runs, and in a per-player program once for each player. Once or a few times a second is nothing. The editor notes it at the end of the line, scans units, so that a scan in a loop that runs every frame is a choice and not an accident.