scmJS docs

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);
});

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#

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.

scmJS 0.8.5 · Generated from the repository. The source is under the MIT license, which does not cover what ATTRIBUTION.md lists. StarCraft and Brood War are trademarks of Blizzard Entertainment; this project ships none of their data.