scmJS docs

Keys, the mouse and chat

What the players do is keyPressed, keyHeld, clicked, mouse and chatted. A press, a click and a typed line are true on the one frame they arrive, so a program looks for them in a loop that runs every frame, or listens with on.key and on.chat:

program(() => {
  while (true) {
    if (keyPressed(CurrentPlayer, "F8")) createUnit(CurrentPlayer, units.TerranMarine, 1, locations.Base);

    if (clicked(CurrentPlayer, "right")) {
      const at = mouse(CurrentPlayer);                       // map pixels, kept as they are now
      centerLocation(locations.Cursor, at.x, at.y);
      createUnit(CurrentPlayer, units.TerranMarine, 1, locations.Cursor);
    }

    const m = chatted(CurrentPlayer, "-spawn {n} {what:unit}");
    if (m) createUnit(CurrentPlayer, m.what, m.n, locations.Base);

    underMouse(CurrentPlayer, { owner: CurrentPlayer })?.heal(10);
    sleep(frames(1));
  }
}, { owner: AllPlayers });

The player is one of P1 … P8 or CurrentPlayer; in a per-player program, each player's own keys, mouse and lines. All of it reaches every player's computer together, a few frames after it happens. That is the trip between computers, and it is the same in a game played alone.

Keys and buttons#

The mouse and locations#

Chat#

chatted(player, pattern) is null, or what the pattern read out of the line the player sent. on.chat("-give {n}", (p, { n }) => …) runs each time a player sends a line that fits.

Start a pattern with a word of its own, such as -spawn, so ordinary talk is never taken for it. A single-player game has no chat, so try typed lines in a multiplayer game; hosting one alone is enough.

What input takes from the map#

Only a program that reads input takes anything for it, and nothing is a death counter, a switch or a string: one unit-properties slot; one unit type the map does not use (the Valkyrie, unless the map uses it); the location the build already keeps for orders; and hidden units of Player 12 at the map's top-left corner, six for each human player and six more when the mouse is read. Outside a program these functions are an error, where if (keyPressed(…)) would otherwise quietly be true. Simulate presses no keys, so there they read as nothing; a test can press them.

What only one computer knows#

local is what this computer alone knows: local.player (the player at this computer), local.camera.x and .y (where its screen is on the map), local.mouse.x and .y (the cursor on the screen), local.selected and local.selectionCount.

A local value may choose what is shown on this computer. It may not change the game, since every computer would change it differently and the game would split, and the editor refuses that. await sync(player, value) sends that player's value to every computer and gives it back a few frames later, the same everywhere. select(P1, local.selected!) makes this computer's selection the player's selection on every computer.

program(async () => {
  let x = 0;
  while (true) {
    if (keyHeld(P1, "D")) x += 4;
    if (local.player == P1) print(`screen at ${local.camera.x}`);
    const cam = await sync(P1, local.camera.x);
    if (cam > x) x = cam;
    await nextFrame();
  }
});

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.