A user script runs against the open document, from Tools ▸ User scripts. It is ordinary JavaScript or TypeScript, and everything it can reach is listed on this page — this is the whole surface, generated from the same declaration that installs it.
Scripts run in an interpreter written in JavaScript, so a script has no network, no page, and no filesystem: not because they were taken away, but because nothing exists inside that sandbox except what appears below. The only effect a script can have is on your map.
API version 1 — MIT licensed, so you can develop against it in your own editor.
A script, in full
// Line up every crate on the Props layer to a whole tile.
const props = map.layer("Props");
if (!props) throw new Error("no Props layer");
let moved = 0;
for (const placement of props.placements) {
if (placement.type?.name !== "Crate") continue;
const x = Math.round(placement.x);
const y = Math.round(placement.y);
if (x === placement.x && y === placement.y) continue;
placement.move(x, y);
moved++;
}
console.log(`snapped ${moved} crates`);
// The whole run is one undo step: one Ctrl-Z puts all of it back. If this
// throws part-way, nothing it already changed is kept.
Globals
Already defined when your script starts. Everything else is reached by drilling into these.
mapMapThe open document.
selectionSelectionShorthand for map.selection.
paramsobjectThis script's configuration, as filled in on the run dialog.
Objects
Each is a live view of the document, not a copy: read a property twice and the second read sees any change in between.
Map8 members
The open document. The root of everything a script can reach.
Layer14 members
One layer. A tile layer also has tile methods; ask `kind` first.
Placement19 members
One placed entity. A live view: read a property and you get the document's current value, not a snapshot from when you found it.
Tile7 members
One painted cell.
EntityType3 members
A type from the project. Read-only — a script edits the map, not the project that defines what can go on it.
Selection3 members
What the user had selected when the script started.
What a script cannot do
Worth knowing before you write one, because none of these fail in an obvious way if you assume otherwise.
Reach the network, disk, or page. There is no fetch, document or require. A script cannot load anything or send anything anywhere.
Run forever. Execution is metered in interpreter steps, so an endless loop is stopped mid-loop rather than hanging the editor.
Use timers.setTimeout and setInterval are removed: a script that scheduled work could never be said to have finished.
Change the project. Entity types, tilesets and settings are read-only. A script edits the map.
Run on anyone else's machine. In a collaborative session the script runs only where it was started; everyone else receives the resulting edits as ordinary changes, under the name of whoever ran it.
Stale handles
Objects are views, so one can outlive the thing it points at — you keep a Placement, and it is deleted (by you, or by someone else in the session). Reading .exists is always safe and returns false; reading anything else throws an error naming the id. That is deliberate — silently returning nothing would let a script carry on editing what is no longer there.