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:
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.
// call normally
print("a + b = ", left, " + ", right, " = ", left + right);
// call with tagged string templates
print`a + b = ${left} + ${right} = ${left + right}`;
draw
Contains the multiple variants of the draw instruction
WARNING
Nothing is drawn until drawFlush is called.
draw.clearFills the screen with a color.
jsdraw.clear(0, 0, 0); // black screendraw.colorSets the color for the next drawing operations.
Each parameter must be within range: [0, 255].
jsdraw.color(255, 255, 255, 128);draw.colSets the color for the next drawing operations.
Uses compressed rgba data from
packColor.jsdraw.col(packColor(1, 1, 1, 1));draw.strokeSets the width of the next lines to be drawn.
jsdraw.stroke(15);draw.lineDraws a line between two points.
jsdraw.line({ x: 5, y: 5, x2: 50, y2: 50 });draw.rectDraws a filled rectangle.
jsdraw.rect({ x: 10, y: 15, height: 60, width: 40, });draw.lineRectDraws a rectangle outline.
jsdraw.lineRect({ x: 10, y: 15, height: 60, width: 40, });draw.polyDraws a filled, regular polygon.
sides- The number of sides the polygon should haveradius- The smallest distance between a line and the center of the polygonrotation- The rotation of the polygon in degree
jsdraw.poly({ radius: 10, rotation: 0, sides: 10, x: 25, y: 25, });draw.linePolyDraws the outline of a regular polygon.
sides- The number of sides the polygon should haveradius- The smallest distance between a line and the center of the polygonrotation- The rotation of the polygon in degree
jsdraw.linePoly({ radius: 10, rotation: 0, sides: 10, x: 25, y: 25, });draw.triangleDraws a filled triangle.
jsdraw.triangle({ x: 10, y: 10, x2: 20, y2: 20, x3: 30, y3: 10, });draw.imageDraws an image of the respective content. (like
Units.daggerandBlocks.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.
targetThe message building to write to. Writes tomessage1by default.Note that the default value only applies if you don't pass any parameter to this function.
const message = getBuilding("message2");
printFlush(message);
printFlush(); // defaults to message1
drawFlush
Writes the contents of the draw buffer into the target display and clears the buffer afterwards.
targetThe display building to write to. Writes todisplay1by default.Note that the default value only applies if you don't pass any parameter to this function.
const display = getBuilding("display2");
drawFlush(display);
drawFlush(); // defaults to display1
getLink
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.
if (index < Vars.links) {
const myBlock = getLink(index);
// ...
}
control
Contains the multiple variants of the control instruction
control.enabledSets whether the building is enabled or disabled.
jsconst conveyor = getBuilding("conveyor1"); control.enabled(conveyor, false);control.shootMakes the building shoot or aim at the given position
building- The shooting buildingshoot-trueto shoot,falseto just aim at the position
jscontrol.shoot({ building: getBuilding("cyclone1"), shoot: true, x: Vars.thisx, y: Vars.thisy, });control.shootpShoot at an unit with velocity prediction
building- The shooting buildingunit- The target unitshoot-trueto shoot,falseto just aim
jsconst turret = getBuilding("cyclone1"); const player = radar({ building: turret, filters: ["player", "any", "any"], order: true, sort: "distance", }); control.shootp({ building: turret, unit: player, shoot: true, });control.configSets the config of a block (like the item of a sorter)
jsconst sorter = getBuilding("sorter1"); control.config(sorter, Items.copper);control.colorSets the color of an illuminator.
jsconst illuminator = getBuilding("illuminator1"); control.color(illuminator, packColor(0.2, 0.65, 1, 1));
radar
Detects an unit nearby this building.
building- The building used to detect potential targetsfilters- The filters for selecting a target. Use "any" for any target.order-trueto get the first result,falseto get the last result.sort- The method on which the results should be sorted
Example:
const turret = getBuilding("cyclone1");
// returns the furthest enemy unit
const result = radar({
building: turret,
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 buildingtarget- The object that will be "sensed"
const myBuilding = getBuilding("container1");
// problably defined by a mod
const myCustomSymbol = getVar<symbol>("@custom-symbol");
const result = sensor(myCustomSymbol, myBuilding);
const myBuilding = getBuilding("container1");
/** @type {symbol} problably defined by a mod */
const myCustomSymbol = getVar("@custom-symbol");
const result = sensor(myCustomSymbol, myBuilding);
Operations
lookup
Looks up content symbols by their index.
lookup.blockLooks up a block symbol by it's index on the content registry.
Use
Vars.blockCountto check the maximum index allowed.jsif (index < Vars.blockCount) { const blockKind = lookup.block(index); }lookup.unitLooks up an unit symbol by it's index on the content registry.
Use
Vars.unitCountto check the maximum index allowed.jsif (index < Vars.unitCount) { const unitKind = lookup.unit(index); }lookup.itemLooks up an item symbol by it's index on the content registry.
Use
Vars.itemCountto check the maximum index allowed.jsif (index < Vars.itemCount) { const itemKind = lookup.item(index); }lookup.liquidLooks up a liquid symbol by it's index on the content registry.
Use
Vars.liquidCountto check the maximum index allowed.jsif (index < Vars.liquidCount) { const liquidKind = lookup.liquid(index); }
packColor
Packs RGBA color information into a single number.
Each paremeter must range from 0 to 1.
const colorData = packColor(0.1, 0.6, 0.8, 0.1);
// world processor only
setRule.ambientLight(colorData);
Flow control
wait
Stops the execution for the given amount of seconds
print("before");
printFlush();
wait(3.5);
print("after");
printFlush();
endScript
Jumps to the top of the instruction stack
const { enabled } = getBuilding("switch1");
if (!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.
// 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.
unitBind(Units.flare);
const { x, y } = Vars.unit;
print`x: ${x} y: ${y}`;
printFlush();
unitControl
Controls the unit bound to the processor
unitControl.idleMakes the unit bound to this processor stop moving but allows it to keep doing it's action (like mining or building).
jsunitControl.idle();unitControl.stopMakes the unit bound to this processor stop mining, building and moving
jsunitControl.stop();unitControl.moveMakes the unit bound to this processor move to the given position
jsunitControl.move(10, 20);unitControl.approachMakes the unit bound to this processor approach the given position at the given radius
radius- How distant to the position the unit can be
jsunitControl.approach({ x: 15, y: 30, radius: 5, });unitControl.boostWhether the unit bound to this processor should be boosted (floating).
jsunitControl.boost(true);unitControl.targetMakes the unit bound to this processor shoot/aim at the given position
shoot-trueto shoot,falseto just aim
jsunitControl.target({ shoot: true, x: 15, y: 30, });unitControl.targetpMakes the unit bound to this processor target an unit with velocity prediction
unit- The shoot targetshoot-trueto shoot,falseto just aim
jsconst player = unitRadar({ filters: ["player", "any", "any"], order: true, sort: "distance", }); unitControl.targetp({ shoot: true, unit: player, });unitControl.itemDropMakes the unit bound to this processor drop it's held items onto the given target
target- Where to drop the items, ifBlocks.air, the unit will throw it's items awayamount- How many items should be dropped
jsconst container = getBuilding("container1"); // ... // drop 40 items on the container unitControl.itemDrop(container, 40); // ... // discard 10 items from the current unit unitControl.itemDrop(Blocks.air, 10);unitControl.itemTakeMakes the unit bound to this processor take items from a building
target- The building that will have it's items takenitem- The kind of item to takeamount- How many items should be taken
jsconst vault = getBuilding("vault1"); // bind unit and move to the valult... unitControl.itemTake(vault, Items.graphite, 50); // do something with the graphite...unitControl.payDropMakes the unit bound to this processor drop one entity from it's payload
jsunitControl.payDrop();unitControl.payTakeMakes the unit bound to this processor take an entity into it's payload
takeUnits- Whether to take units or buildings
jsunitControl.payTake({ takeUnits: true, });unitControl.payEnterMakes the unit bound to this processor enter/land on the payload block the unit is on
jsunitControl.payEnter();unitControl.mineMakes the unit bound to this processor mine at the given position
jsunitControl.mine(10, 20);unitControl.flagSets the numeric flag of the unit bound to this processor
jsconst localFlag = 123; unitControl.flag(localFlag);unitControl.buildMakes the unit bound to this processor build a building with the given properties
block- The kind of building to buildrotation- The rotation of the building, ranges from 0 to 3config- The config of the building
jsunitControl.build({ x: 10, y: 20, block: Blocks.sorter, rotation: 1, config: Items.silicon, });unitControl.getBlockMakes the unit bound to this processor get data about a block at the given position
jsconst [type, building, floor] = unitControl.getBlock(10, 20); // do something with the resultsunitControl.withinChecks if the unit bound to this processor is within a radius of a given position.
jsunitControl.within({ x: 10, y: 20, radius: 5, });unitControl.unbindResets the AI of the unit.
Calling
unbinddoes not actually unbind the unit from the processor, it just makes the unit resume its natural behavior.jsunitControl.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-trueto get the first result,falseto get the last result.sort- The method on which the results should be sorted
Example:
// 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.oreUses the unit bound to this processor to find an ore vein anywhere on the map
ore- The kind of item the ore should contain
jsconst [found, x, y] = unitLocate.ore(Items.copper); if (found) { unitControl.approach({ x, y, radius: 5 }); }unitLocate.buildingUses the unit bound to this processor to find a building anywhere on the map
group- The group that the building belongs toenemy- Whether it should be an enemy building or an ally one
jsconst 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.spawnUses 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.
jsconst [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.damagedUses the unit bound to this processor to find a damaged ally buildings anywhere on the map
jsconst [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 regular processor
getBlock
Gets block data from the map. Available ONLY for world processors.
getBlock.floorGets the floor type on the given location
jsconst floorType = getBlock.floor(10, 20);getBlock.oreGets the ore type on the given location.
Blocks.airif there is no orejsconst oreType = getBlock.ore(10, 20); if (oreType != Blocks.air) { print("found ", oreType); } else { print("no ore found"); } printFlush();getBlock.blockGets the block type on the give location.
Blocks.airif there is no block.jsconst blockType = getBlock.block(10, 20); if (blockType != Blocks.air) { print("found ", blockType); } else { print("no block found"); } printFlush();getBlock.buildingGets the building on the given location.
undefinedif there is no building.jsconst building = getBlock.building(10, 20); if (building != undefined) { print("found ", building, ""); } else { print("no building found"); } printFlush();
setBlock
setBlock.floorSets the floor of the tile at the given location.
jssetBlock.floor(10, 20, Blocks.metalFloor5);setBlock.oreSets the ore at the given location. Use
Blocks.airto remove any ore.jssetBlock.ore(10, 20, Blocks.oreCopper);setBlock.blockSets the block at a given location, it can be a regular building or an environment block.
jssetBlock.block({ x: 10, y: 20, to: Blocks.router, rotation: 0, team: Teams.sharded, });
spawnUnit
Spawns an unit at the given location.
rotation- The initial rotation of the unit in degrees.
spawnUnit({
team: Teams.sharded,
type: Units.flare,
x: 10,
y: 20,
rotation: 90,
});
applyStatus
Contains the variants for the applyStatus instruction.
applyStatus.applyApplies a status effect to the given unit.
The only status effects that don't require a duration are
overdriveandboss.jsapplyStatus.apply("burning", Vars.unit, 10); applyStatus.apply("boss", Vars.unit);applyStatus.clearRemoves a status effect to the given unit.
jsapplyStatus.clear("burning", Vars.unit); applyStatus.clear("boss", Vars.unit);
spawnWave
Spawns an enemy wave, can be used even if there is an already active wave.
// natural wave, units appear on the enemy spawn
spawnWave(true);
// syntethic wave, units appear on the given coordinates
spawnWave(false, 10, 20);
setRule
Contains the multiple variants of the setrule instruction.
setRule.currentWaveTimeSets the wave countdown in seconds.
jssetRule.currentWaveTime(10);setRule.waveTimerEnables/disables the wave timer.
jssetRule.waveTimer(true);setRule.wavesAllows or prevents waves from spawning.
jssetRule.waves(true);setRule.waveSets the current wave number.
jssetRule.wave(10);setRule.waveSpacingSets the time between waves in seconds.
jssetRule.waveSpacing(180);setRule.waveSendingSets wether waves can be manually summoned by pressing the play button.
jssetRule.waveSending(true);setRule.attackModeSets wether the gamemode is the attack mode
jssetRule.attackMode(true);setRule.enemyCoreBuildRadiusSets the radius of the no-build zone around enemy cores.
jssetRule.enemyCoreBuildRadius(150);setRule.dropZoneRadiusSets the radius around enemy wave drop zones.
jssetRule.dropZoneRadius(20);setRule.unitCapSets the base unit cap.
jssetRule.unitCap(40);setRule.mapAreaSets the playable map area. Blocks that are out of the new bounds will be removed.
jssetRule.mapArea({ x: 0, y: 0, width: 500, height: 500, });setRule.lightingSets wether ambient lighting is enabled
jssetRule.lighting(true);setRule.ambientLightSets the ambient light color.
packColorcan be used to get the RGBA data recevied by this function.js// enables lighting and sets the color to gray setRule.lighting(true); setRule.ambientLight(packColor(0.5, 0.5, 0.5, 1));setRule.solarMultiplierSets the multiplier for the energy output of solar panels.
jssetRule.solarMultiplier(10);setRule.buildSpeedSets the build speed multiplier of a team.
The multiplier will always be clamped between
0.001and50.jssetRule.buildSpeed(Teams.sharded, 1.5);setRule.unitBuildSpeedSets the speed multiplier for unit factories.
The multiplier will always be clamped between
0and50.jssetRule.unitBuildSpeed(Teams.sharded, 3);setRule.unitCostSets the build cost multiplier for constructing units.
jssetRule.unitCost(Teams.sharded, 1.75);setRule.unitDamageSets the damage multiplier for units on a given team.
jssetRule.unitDamage(Teams.sharded, 1.25);setRule.blockHealthSets the block health multiplier for a given team.
jssetRule.blockHealth(Teams.crux, 0.75);setRule.blockDamageSets the block damage multiplier for a given team.
jssetRule.blockDamage(Teams.crux, 2);setRule.rtsMinWeightSets 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.
jssetRule.rtsMinWeight(Teams.sharded, 3);setRule.rtsMinSquadSets 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.
jssetRule.rtsMinSquad(Teams.sharded, 5);
flushMessage
Writes the contents of the print buffer in the selected mode and clears the buffer afterwards. World processor ONLY.
print("Hello");
flushMessage.announce(4); // lasts 4 seconds
wait(5);
print("World");
flushMessage.toast(4);
wait(5);
flushMessage.notifyShows a nofication at the top of the screen
jsprint("something"); flushMessage.notify();flushMessage.missionPuts the content on the top left corner of the screen
jsprint("something"); flushMessage.mission();flushMessage.announcePuts the content on the middle of the screen
duration- The duration, in seconds
jsprint("something"); flushMessage.announce(3);flushMessage.toastPuts the content on the middle top of the screen
duration- The duration, in seconds
jsprint("something"); flushMessage.toast(5);
cutscene
cutscene.panMoves the player's camera to the given location.
jscutscene.pan({ x: 10, y: 20, speed: 15, });cutscene.zoomZooms the player camera to the desired level
jscutscene.zoom(3);cutscene.stopGives the camera control back to the player
jscutscene.stop();
explosion
Creates an explosion
explosion({
team: Teams.crux,
x: 5,
y: 15,
radius: 20,
damage: 100,
air: true,
ground: true,
pierce: true,
});
setRate
Sets the speed of this world processor in instructions per tick.
setRate(20);
fetch
Contains the variants of the fetch instruction.
fetch.unitGets an unit from the given team The index starts at 0.
jsconst count = fetch.unitCount(Teams.sharded); for (let i = 0; i < count; i++) { const unit = fetch.unit(Teams.sharded, i); print`x: ${unit.x}, y: ${unit.y}\n`; } printFlush();fetch.unitCountGets the amount of units existing on a given team.
jsconst count = fetch.unitCount(Teams.sharded); for (let i = 0; i < count; i++) { const unit = fetch.unit(Teams.sharded, i); print`x: ${unit.x}, y: ${unit.y}\n`; } printFlush();fetch.playerGets a player from a team.
The index starts at 0.
jsconst count = fetch.playerCount(Teams.sharded); for (let i = 0; i < count; i++) { const player = fetch.player(Teams.sharded, i); print`x: ${player.x}, y: ${player.y}\n`; } printFlush();fetch.playerCountGets the amount of players existing on a given team.
jsconst count = fetch.playerCount(Teams.sharded); for (let i = 0; i < count; i++) { const player = fetch.player(Teams.sharded, i); print`x: ${player.x}, y: ${player.y}\n`; } printFlush();fetch.coreGets a core from a team.
The index of the starts at 0.
jsconst count = fetch.coreCount(Teams.sharded); for (let i = 0; i < count; i++) { const core = fetch.core(Teams.sharded, i); print`x: ${core.x}, y: ${core.y}\n`; } printFlush();fetch.coreCountGets the amount of cores existing on a given team.
jsconst count = fetch.coreCount(Teams.sharded); for (let i = 0; i < count; i++) { const core = fetch.core(Teams.sharded, i); print`x: ${core.x}, y: ${core.y}\n`; } printFlush();fetch.buildGets a building from a team.
The index starts at 0.
jsconst count = fetch.buildCount(Teams.sharded, Blocks.router); for (let i = 0; i < count; i++) { const router = fetch.build(Teams.sharded, i, Blocks.router); print`x: ${router.x}, y: ${router.y}\n`; } printFlush();fetch.buildCountGets the amount of buildings existing on a given team.
jsconst count = fetch.buildCount(Teams.sharded, Blocks.router); for (let i = 0; i < count; i++) { const router = fetch.build(Teams.sharded, i, Blocks.router); print`x: ${router.x}, y: ${router.y}\n`; } printFlush();
getFlag
Checks if a global flag is set.
const flagEnabled = getFlag("foo");
setFlag
Sets a global flag.
setFlag("foo", true);
MlogJS