Skip to content

Commands

Commands are built in function macros that expand into instructions during compilation.

Here is a list of them, some have multiple overloads

Overloaded commands have the following syntax:

js
command.variant();

Input/output

print

Appends the items to the print buffer, calling this function on its own will not print any contents to a message block.

To print the contents of the print buffer and empty it, call printFlush.

js
const a = Math.floor(Math.rand(10));
const b = Math.floor(Math.rand(10));

// call normally
print("a + b = ", a, " + ", b, " = ", a + b, "\n");

// call with tagged string templates
print`a + b = ${a} + ${b} = ${a + b}\n`;

printFlush();

draw

Contains the multiple variants of the draw instruction

WARNING

Nothing is drawn until drawFlush is called.

  • draw.clear

    Fills the screen with a color.

    js
    draw.clear(0, 0, 0); // black screen
  • draw.color

    Sets the color for the next drawing operations.

    Each parameter must be within range: [0, 255].

    js
    draw.color(255, 255, 255, 128);
  • draw.col

    Sets the color for the next drawing operations.

    Uses compressed rgba data from packColor.

    js
    draw.col(packColor(1, 1, 1, 1));
  • draw.stroke

    Sets the width of the next lines to be drawn.

    js
    draw.stroke(15);
  • draw.line

    Draws a line between two points.

    js
    draw.line({ x: 5, y: 5, x2: 50, y2: 50 });
  • draw.rect

    Draws a filled rectangle.

    js
    draw.rect({
      x: 10,
      y: 15,
      height: 60,
      width: 40,
    });
  • draw.lineRect

    Draws a rectangle outline.

    js
    draw.lineRect({
      x: 10,
      y: 15,
      height: 60,
      width: 40,
    });
  • draw.poly

    Draws a filled, regular polygon.

    • sides - The number of sides the polygon should have
    • radius - The smallest distance between a line and the center of the polygon
    • rotation - The rotation of the polygon in degree
    js
    draw.poly({
      radius: 10,
      rotation: 0,
      sides: 10,
      x: 25,
      y: 25,
    });
  • draw.linePoly

    Draws the outline of a regular polygon.

    • sides - The number of sides the polygon should have
    • radius - The smallest distance between a line and the center of the polygon
    • rotation - The rotation of the polygon in degree
    js
    draw.linePoly({
      radius: 10,
      rotation: 0,
      sides: 10,
      x: 25,
      y: 25,
    });
  • draw.triangle

    Draws a filled triangle.

    js
    draw.triangle({
      x: 10,
      y: 10,
      x2: 20,
      y2: 20,
      x3: 30,
      y3: 10,
    });
  • draw.image

    Draws an image of the respective content. (like Units.dagger and Blocks.router)

    • image - The symbol for the image to be drawn.
    • rotation - The rotation of the image in degrees.
    js
    // draw a router
    draw.image({
      x: 30,
      y: 30,
      image: Blocks.router,
      size: 15,
      rotation: 0,
    });
    
    // draw the unit bound to the processor
    draw.image({
      x: 60,
      y: 60,
      image: Vars.unit.type,
      size: 15,
      rotation: 0,
    });

Block Control

printFlush

Writes the contents of the print buffer into the target message and clears the buffer afterwards.

  • target The message building to write to. Writes to message1 by default.

    Note that the default value only applies if you don't pass any parameter to this function.

js
const { message2 } = getBuildings();
printFlush(message2);

printFlush(); // defaults to message1

drawFlush

Writes the contents of the draw buffer into the target display and clears the buffer afterwards.

  • target The display building to write to. Writes to display1 by default.

    Note that the default value only applies if you don't pass any parameter to this function.

js
const { display2 } = getBuildings();
printFlush(display2);

printFlush(); // defaults to display1

Gets a block link by its index.

To make safe queries it is recommended to check an index before trying to get a link. This can be done by using Vars.links.

js
for (let i = 0; i < Vars.links; i++) {
  const building = getLink(i);
  const { x, y } = building;
  print`${building}: (${x}, ${y})\n`;
}

printFlush();

control

Contains the multiple variants of the control instruction

  • control.enabled

    Sets whether the building is enabled or disabled.

    js
    const { conveyor1 } = getBuildings();
    
    control.enabled(conveyor1, false);
  • control.shoot

    Makes the building shoot or aim at the given position

    • building - The shooting building
    • shoot - true to shoot, false to just aim at the position
    js
    const { cyclone1 } = getBuildings();
    
    control.shoot({
      building: cyclone1,
      shoot: true,
      x: Vars.thisx,
      y: Vars.thisy,
    });
  • control.shootp

    Shoot at an unit with velocity prediction

    • building - The shooting building
    • unit - The target unit
    • shoot - true to shoot, false to just aim
    js
    const { cyclone1 } = getBuildings();
    
    const player = radar({
      building: cyclone1,
      filters: ["player", "any", "any"],
      order: true,
      sort: "distance",
    });
    
    control.shootp({
      building: cyclone1,
      unit: player,
      shoot: true,
    });
  • control.config

    Sets the config of a block (like the item of a sorter)

    js
    const { sorter1 } = getBuildings();
    
    control.config(sorter1, Items.copper);
  • control.color

    Sets the color of an illuminator.

    js
    const { illuminator1 } = getBuildings();
    
    control.color(illuminator1, packColor(0.2, 0.65, 1, 1));

radar

Detects an unit nearby this building.

  • building - The building used to detect potential targets
  • filters - The filters for selecting a target. Use "any" for any target.
  • order - true to get the first result, false to get the last result.
  • sort - The method on which the results should be sorted

Example:

js
const { cyclone1 } = getBuildings();

// returns the furthest enemy unit
const result = radar({
  building: cyclone1,
  filters: ["enemy", "any", "any"],
  order: false,
  sort: "distance",
});

sensor

Alternate way to access special properties on objects.

This method allows you to use customly created symbols and sensor them on buildings.

  • property - The property to be sensed on the building
  • target - The object that will be "sensed"
ts
const { container1 } = getBuildings();

// problably defined by a mod
const myCustomSymbol = getVar<symbol>("@custom-symbol");
const result = sensor(myCustomSymbol, container1);
js
const { container1 } = getBuildings();

/** Probably defined by a mod @type {symbol} */
const myCustomSymbol = getVar("@custom-symbol");
const result = sensor(myCustomSymbol, container1);

Operations

lookup

Looks up content symbols by their index.

For the inverse of this operation, you can sense the id of a symbol:

js
const { type } = getLink(0);

print(type === lookup.block(type.id));
printFlush(); // prints "1"
  • lookup.block

    Looks up a block symbol by it's index on the content registry.

    Use Vars.blockCount to check the maximum index allowed.

    js
    const first = lookup.block(0);
    const last = lookup.block(Vars.blockCount - 1);
    
    print`
    first block type: ${first}
    last block type: ${last}`;
    
    printFlush();
  • lookup.unit

    Looks up an unit symbol by it's index on the content registry.

    Use Vars.unitCount to check the maximum index allowed.

    js
    const first = lookup.unit(0);
    const last = lookup.unit(Vars.unitCount - 1);
    
    print`
    first unit type: ${first}
    last unit type: ${last}`;
    
    printFlush();
  • lookup.item

    Looks up an item symbol by it's index on the content registry.

    Use Vars.itemCount to check the maximum index allowed.

    js
    const first = lookup.item(0);
    const last = lookup.item(Vars.itemCount - 1);
    
    print`
    first item type: ${first}
    last item type: ${last}`;
    
    printFlush();
  • lookup.liquid

    Looks up a liquid symbol by it's index on the content registry.

    Use Vars.liquidCount to check the maximum index allowed.

    js
    const first = lookup.liquid(0);
    const last = lookup.liquid(Vars.liquidCount - 1);
    
    print`
    first liquid type: ${first}
    last liquid type: ${last}`;
    
    printFlush();

packColor

Packs RGBA color information into a single number.

Each paremeter must range from 0 to 1.

js
const colorData = packColor(0.1, 0.6, 0.8, 0.1);

// world processor only
// sets the color of the ambient light
setRule.ambientLight(colorData);

// set color of illuminator
const { illuminator1 } = getBuildings();
control.color(illuminator1, packColor(0.2, 0.65, 1, 1));

Flow control

wait

Stops the execution for the given amount of seconds

js
print("before");
printFlush();
wait(3.5);
print("after");
printFlush();

endScript

Jumps to the top of the instruction stack

js
const { switch1 } = getBuildings();

if (!switch1.enabled) endScript();
// do something when the switch is enabled

stopScript

Halts the execution of this processor. Can be used to debug code and analyze the processor registers.

js
// stop the processor to debug variables
stopScript();

Unit control

unitBind

Binds an unit to the this processor. The unit is accessible at Vars.unit.

If an unit symbol is received, the processor will pick an unit of the given type.

If an unit object is received, the processor will bind to the unit.

js
unitBind(Units.flare);

const { x, y } = Vars.unit;

print`x: ${x} y: ${y}`;
printFlush();

unitControl

Controls the unit bound to the processor

  • unitControl.idle

    Makes the unit bound to this processor stop moving but allows it to keep doing it's action (like mining or building).

    js
    unitControl.idle();
  • unitControl.stop

    Makes the unit bound to this processor stop mining, building and moving

    js
    unitControl.stop();
  • unitControl.move

    Makes the unit bound to this processor move to the given position

    js
    unitControl.move(10, 20);
  • unitControl.approach

    Makes the unit bound to this processor approach the given position at the given radius

    • radius - How distant to the position the unit can be
    js
    unitControl.approach({
      x: 15,
      y: 30,
      radius: 5,
    });
  • unitControl.pathfind

    Makes the unit bound to this processor move to the given location.

    Uses the unit's pathfinding algorithm to decide how to reach the desired location instead of blidly going in a straight line.

    js
    // makes flares follow the player's cursor
    const { foreshadow1 } = getBuildings();
    
    const player = radar({
      building: foreshadow1,
      filters: ["player", "any", "any"],
      order: true,
      sort: "distance",
    });
    
    unitBind(Units.flare);
    
    unitControl.pathfind(player.shootX, player.shootY);
  • unitControl.boost

    Whether the unit bound to this processor should be boosted (floating).

    js
    unitControl.boost(true);
  • unitControl.target

    Makes the unit bound to this processor shoot/aim at the given position

    • shoot - true to shoot, false to just aim
    js
    unitControl.target({
      x: 15,
      y: 30,
      shoot: true,
    });
  • unitControl.targetp

    Makes the unit bound to this processor target an unit with velocity prediction

    • unit - The shoot target
    • shoot - true to shoot, false to just aim
    js
    unitBind(Units.flare);
    
    const player = unitRadar({
      filters: ["player", "any", "any"],
      order: true,
      sort: "distance",
    });
    
    unitControl.targetp({
      unit: player,
      shoot: true,
    });
  • unitControl.itemDrop

    Makes the unit bound to this processor drop it's held items onto the given target

    • target - Where to drop the items, if Blocks.air, the unit will throw it's items away
    • amount - How many items should be dropped
    js
    const { container1 } = getBuildings();
    
    // ...
    
    // drop 40 items on the container
    unitControl.itemDrop(container1, 40);
    
    // ...
    
    // discard 10 items from the current unit
    unitControl.itemDrop(Blocks.air, 10);
  • unitControl.itemTake

    Makes the unit bound to this processor take items from a building

    • target - The building that will have it's items taken
    • item - The kind of item to take
    • amount - How many items should be taken
    js
    const { vault1 } = getBuildings();
    
    // bind unit and move to the valult...
    
    unitControl.itemTake(vault1, Items.graphite, 50);
    
    // do something with the graphite...
  • unitControl.payDrop

    Makes the unit bound to this processor drop one entity from it's payload

    js
    unitControl.payDrop();
  • unitControl.payTake

    Makes the unit bound to this processor take an entity into it's payload

    • takeUnits - Whether to take units or buildings
    js
    unitControl.payTake({
      takeUnits: true,
    });
  • unitControl.payEnter

    Makes the unit bound to this processor enter/land on the payload block the unit is on

    js
    unitControl.payEnter();
  • unitControl.mine

    Makes the unit bound to this processor mine at the given position

    js
    unitControl.mine(10, 20);
  • unitControl.flag

    Sets the numeric flag of the unit bound to this processor

    js
    // a unique id based on the coordinates of this processor
    const processorId = Vars.thisx * Vars.mapw + Vars.thisy;
    
    unitControl.flag(processorId);
  • unitControl.build

    Makes the unit bound to this processor build a building with the given properties

    • block - The kind of building to build
    • rotation - The rotation of the building, ranges from 0 to 3
    • config - The config of the building
    js
    unitControl.build({
      x: 10,
      y: 20,
      block: Blocks.sorter,
      rotation: 1,
      config: Items.silicon,
    });
  • unitControl.getBlock

    Makes the unit bound to this processor get data about a block at the given position

    js
    // prints info about the block the player is pointing at
    unitBind(Units.flare);
    
    const player = unitRadar({
      filters: ["player", "any", "any"],
      sort: "distance",
      order: true,
    });
    
    const { shootX, shootY } = player;
    const [type, building, floor] = unitControl.getBlock(shootX, shootY);
    
    print`
    block: ${type}
    floor: ${floor}
    size: ${building.size ?? 1}
    `;
    printFlush();
  • unitControl.within

    Checks if the unit bound to this processor is within a radius of a given position.

    js
    if (Vars.unit == undefined) {
      unitBind(Units.flare);
    }
    
    const player = unitRadar({
      filters: ["player", "any", "any"],
      sort: "distance",
      order: true,
    });
    
    const nearby = unitControl.within({
      x: player.x,
      y: player.y,
      radius: 5,
    });
    
    print`nearby: ${nearby}`;
    printFlush();
  • unitControl.unbind

    Resets the AI of the unit.

    Calling unbind does not actually unbind the unit from the processor, it just makes the unit resume its natural behavior.

    js
    unitControl.unbind();

unitRadar

Finds an unit near the unit bound to this processor

  • filters - The filters for selecting a target. Use "any" for any target.
  • order - true to get the first result, false to get the last result.
  • sort - The method on which the results should be sorted

Example:

js
// returns the furthest enemy unit
const result = unitRadar({
  filters: ["enemy", "any", "any"],
  order: false,
  sort: "distance",
});

unitLocate

Uses the unit bound to this processor to find specific types of blocks

  • unitLocate.ore

    Uses the unit bound to this processor to find an ore vein anywhere on the map

    • ore - The kind of item the ore should contain
    js
    const [found, x, y] = unitLocate.ore(Items.copper);
    
    if (found) {
      unitControl.approach({ x, y, radius: 5 });
    }
  • unitLocate.building

    Uses the unit bound to this processor to find a building anywhere on the map

    • group - The group that the building belongs to
    • enemy - Whether it should be an enemy building or an ally one
    js
    const vault = getBuilding("vault1");
    const takeAmount = 100;
    
    unitBind(Units.mega);
    
    // we don't use the `found` variable
    // because we always have our own core
    const [, x, y, core] = unitLocate.building({
      group: "core",
      enemy: false,
    });
    
    const location = {
      x,
      y,
      radius: 5,
    };
    
    if (!unitControl.within(location) && Vars.unit.totalItems == 0) {
      // if the unit has no items and it is not near
      // the core, move it to the core
      // and take 100 copper
      unitControl.approach(location);
      unitControl.itemTake(core, Items.copper, takeAmount);
    } else {
      // else, approach the vault and drop the items on it
      unitControl.approach({
        x: vault.x,
        y: vault.y,
        radius: 5,
      });
      unitControl.itemDrop(vault, takeAmount);
    }
  • unitLocate.spawn

    Uses the unit bound to this processor to find an enemy spawn anywhere on the map.

    Returns the enemy spawn point or its core, if it exists.

    js
    const [found, x, y, core] = unitLocate.spawn();
    
    if (!found) {
      print("No enemy core found");
    } else if (core) {
      print`core location at (${x}, ${y})`;
    } else {
      print`enemy spawn at (${x}, ${y})`;
    }
    
    printFlush();
  • unitLocate.damaged

    Uses the unit bound to this processor to find a damaged ally buildings anywhere on the map

    js
    const [found, x, y, building] = unitLocate.damaged();
    
    if (found) {
      print`go fix a ${building} at (${x}, ${y})`;
    } else {
      print("No damaged building found");
    }
    printFlush();

World

These commands are exclusive to world processors and will not work on a regular processor. They must be imported from mlogjs:world.

js
import { getBlock, setBlock } from "mlogjs:world";

getBlock

Gets block data from the map.

  • getBlock.floor

    Gets the floor type on the given location

    js
    no fence
  • getBlock.ore

    Gets the ore type on the given location. Blocks.air if there is no ore

    js
    no fence
  • getBlock.block

    Gets the block type on the give location. Blocks.air if there is no block.

    js
    no fence
  • getBlock.building

    Gets the building on the given location. undefined if there is no building.

    js
    no fence

setBlock

  • setBlock.floor

    Sets the floor of the tile at the given location.

    js
    no fence
  • setBlock.ore

    Sets the ore at the given location. Use Blocks.air to remove any ore.

    js
    no fence
  • setBlock.block

    Sets the block at a given location, it can be a regular building or an environment block.

    js
    no fence

spawnUnit

Spawns an unit at the given location.

  • rotation - The initial rotation of the unit in degrees.
js
no fence

applyStatus

Contains the variants for the applyStatus instruction.

  • applyStatus.apply

    Applies a status effect to the given unit.

    The only status effects that don't require a duration are overdrive and boss.

    js
    no fence
  • applyStatus.clear

    Removes a status effect to the given unit.

    js
    no fence

spawnWave

Spawns an enemy wave, can be used even if there is an already active wave.

js
no fence

setRule

Contains the multiple variants of the setrule instruction.

  • setRule.currentWaveTime

    Sets the wave countdown in seconds.

    js
    no fence
  • setRule.waveTimer

    Enables/disables the wave timer.

    js
    no fence
  • setRule.waves

    Allows or prevents waves from spawning.

    js
    no fence
  • setRule.wave

    Sets the current wave number.

    js
    no fence
  • setRule.waveSpacing

    Sets the time between waves in seconds.

    js
    no fence
  • setRule.waveSending

    Sets wether waves can be manually summoned by pressing the play button.

    js
    no fence
  • setRule.attackMode

    Sets wether the gamemode is the attack mode

    js
    no fence
  • setRule.enemyCoreBuildRadius

    Sets the radius of the no-build zone around enemy cores.

    js
    no fence
  • setRule.dropZoneRadius

    Sets the radius around enemy wave drop zones.

    js
    no fence
  • setRule.unitCap

    Sets the base unit cap.

    js
    no fence
  • setRule.mapArea

    Sets the playable map area. Blocks that are out of the new bounds will be removed.

    js
    no fence
  • setRule.lighting

    Sets wether ambient lighting is enabled

    js
    no fence
  • setRule.ambientLight

    Sets the ambient light color. packColor can be used to get the RGBA data recevied by this function.

    js
    no fence
  • setRule.solarMultiplier

    Sets the multiplier for the energy output of solar panels.

    js
    no fence
  • setRule.buildSpeed

    Sets the build speed multiplier of a team.

    The multiplier will always be clamped between 0.001 and 50.

    js
    no fence
  • setRule.unitBuildSpeed

    Sets the speed multiplier for unit factories.

    The multiplier will always be clamped between 0 and 50.

    js
    no fence
  • setRule.unitCost

    Sets the build cost multiplier for constructing units.

    js
    no fence
  • setRule.unitDamage

    Sets the damage multiplier for units on a given team.

    js
    no fence
  • setRule.blockHealth

    Sets the block health multiplier for a given team.

    js
    no fence
  • setRule.blockDamage

    Sets the block damage multiplier for a given team. Sets the multiplier of damaged dealt by blocks of a given team.

    js
    no fence
  • setRule.rtsMinWeight

    Sets the Real Time Strategy minimum weight for a team.

    In other words, it sets the minimum "advantage" needed for a squad to attack. The higher the value, the more cautious the squad is.

    js
    no fence
  • setRule.rtsMinSquad

    Sets the Real Time Strategy minimum size of attack squads of a team.

    The higher the value, the more units are required before a squad attacks.

    js
    no fence

flushMessage

Writes the contents of the print buffer in the selected mode and clears the buffer afterwards.

js
no fence
  • flushMessage.notify

    Shows a nofication at the top of the screen

    js
    no fence
  • flushMessage.mission

    Puts the content on the top left corner of the screen

    js
    no fence
  • flushMessage.announce

    Puts the content on the middle of the screen

    • duration - The duration, in seconds
    js
    no fence
  • flushMessage.toast

    Puts the content on the middle top of the screen

    • duration - The duration, in seconds
    js
    no fence

cutscene

  • cutscene.pan

    Moves the player's camera to the given location.

    js
    no fence
  • cutscene.zoom

    Zooms the player camera to the desired level

    js
    no fence
  • cutscene.stop

    Gives the camera control back to the player

    js
    no fence

explosion

Creates an explosion

js
no fence

setRate

Sets the speed of this world processor in instructions per tick.

js
no fence

fetch

Contains the variants of the fetch instruction.

  • fetch.unit

    Gets an unit from the given team The index starts at 0.

    js
    no fence
  • fetch.unitCount

    Gets the amount of units existing on a given team.

    js
    no fence
  • fetch.player

    Gets a player from a team.

    The index starts at 0.

    js
    no fence
  • fetch.playerCount

    Gets the amount of players existing on a given team.

    js
    no fence
  • fetch.core

    Gets a core from a team.

    The index of the starts at 0.

    js
    no fence
  • fetch.coreCount

    Gets the amount of cores existing on a given team.

    js
    no fence
  • fetch.build

    Gets a building from a team.

    The index starts at 0.

    js
    no fence
  • fetch.buildCount

    Gets the amount of buildings existing on a given team.

    js
    no fence

getFlag

Checks if a global flag is set.

js
no fence

setFlag

Sets a global flag.

js
no fence

setProp

Creates a writable record that allows you to set a property of a building or unit.

js
no fence