Script commands
The script and editor.scripts commands that load, list, pause, resume, unload and check scripts, with their arguments and results.
On this page
Everything you can do with scripts in the Studio's Scripts panel is also a command, so tools and MCP agents can drive scripts the same way you do. Commands take a JSON object of arguments and return JSON.
There are two groups:
script.*commands talk to the running game's scripts. They're available whenever the game runs scripts.editor.scripts.*commands drive the Studio's Scripts panel and the project's script files. See The Scripts panel.
Summary#
| Command | Arguments | Does |
|---|---|---|
script.load | name, source, player?, roles?, owner?, friend? | Loads or hot-reloads a script. |
script.list | none | Lists running scripts, the hash chain and the log. |
script.pause | name | Pauses a script. |
script.resume | name | Resumes a paused script. |
script.unload | name | Stops and removes a script. |
script.types | format, player?, roles? | Generates the script API declarations. |
script.api | none | The game's script API as JSON. |
editor.scripts.panel | open? | Shows or hides the Scripts panel. |
editor.scripts.files | none | Lists the project's script files. |
editor.scripts.edit | name | Opens a script file in Source mode. |
editor.scripts.check | none | Compiles, validates and runs script tests. |
editor.scripts.live_reload | on | Turns hot reload on save on or off. |
? marks an optional argument.
script.load#
Loads a script by name, or hot-reloads the script with that name if it's already running (its this.state is kept). The request is queued and applies on the next fixed tick.
| Name | Type | Description |
|---|---|---|
name | string | Required. The script's name. |
source | string | Required. The script's source, in the game's language. |
player | string | A player id. With it, the script is that player's live script, subject to [script.players] and the moderation check. Without it, the script is the game's own. |
roles | list of strings | The player's roles in this game (with player). |
owner | boolean | The player owns the game (with player). |
friend | boolean | The player is a friend of the owner (with player). |
Returns: { "queued": "<name>", "applies": "next fixed tick" }. A missing name or source is an error (`source` is required).
Whether the script actually loaded shows up in the log from script.list: loaded, reloaded, refused ... from player ..., moderation refused ..., or ... didn't load: <error>.
{ "name": "hello", "source": "import { World, on } from \"neo\";\nexport default class Hello extends World { state = { n: 0 }; @on(\"tick\") t() { this.state.n += 1; } }" }script.list#
The running scripts and the script log. Takes no arguments.
Returns:
| Field | Description |
|---|---|
tick | The script runtime's tick count. |
sim_ms | Simulation time in milliseconds. |
chain | The tick's hash chain over every script's state hash (hex). |
scripts | One entry per script, in load order (below). |
log | Loads, reloads, refusals, unloads, pauses and manifest problems, newest last (up to 200 lines, each starting with [tick n]). |
Each entry in scripts:
| Field | Description |
|---|---|
name | The script's name. |
principal | "creator" for the game's own scripts, or { "player": "<id>", "roles": [...] }. |
paused | Whether it's paused. |
faults | How many faults it has had. |
last_fault | The last fault's text (handler: reason), or null. |
fuel_used | Instructions used in the last tick. |
fuel_per_tick | Its per-tick budget. |
state_hash | The first 8 bytes of its state hash (hex). |
script.pause, script.resume, script.unload#
| Name | Type | Description |
|---|---|---|
name | string | Required. The script's name. |
Returns: { "queued": "<name>" }. Applies on the next fixed tick.
- Pause: the script stops running. It gets no events or ticks while paused.
- Resume: the script runs again; its clock catches up and timers that came due resolve.
- Unload: the script is removed. Loading it again starts from fresh state.
script.types#
The script API declarations, generated from the game's #[derive(ScriptExpose)] types narrowed by neo.toml's [script], as one kind of script sees them.
| Name | Type | Description |
|---|---|---|
format | string | Required. "ts" (a neo.d.ts for JavaScript editors), "py" (a neo.pyi for Python editors), "md" (a Markdown reference) or "json". |
player | boolean | true for what a player's live script sees. Default: the game's own scripts. |
roles | list of strings | The player's roles (with player: true). |
Returns: for ts, py and md, { "format": "...", "text": "..." }. For json, the same JSON as script.api.
Names in the output follow the cross-language rule: camelCase in ts, snake_case in py.
script.api#
What the game's own scripts can touch, as JSON: the description agents write scripts against. Takes no arguments.
Returns: { "kinds": [...] }, one entry per visible kind:
| Field | Description |
|---|---|
kind | The kind name. |
doc | The type's doc comment. |
spawnable | Whether scripts may spawn it. |
fields | Each with name (snake_case), js (camelCase), type_ts, type_py, read, write, range ([min, max] or null) and doc. |
methods | Each with name, js, args (name, type_ts, type_py), returns_ts, returns_py, rate_per_s (0 when there's no rate) and doc. |
editor.scripts.panel#
| Name | Type | Description |
|---|---|---|
open | boolean | Show (true, the default) or hide (false) the Scripts panel. |
Returns: { "open": true } or { "open": false }.
editor.scripts.files#
The project's script files in assets/scripts (.js and .py). Takes no arguments.
Returns: a list of { "name", "path", "running" }, where running says whether a script with that name is running.
editor.scripts.edit#
| Name | Type | Description |
|---|---|---|
name | string | Required. The script file's name, without the extension. |
Opens the file in Source mode's code editor. Saving it hot-reloads it in the running game when live reload is on. Returns: { "opened": "<path>" }. See Source mode.
editor.scripts.check#
Runs the check: compiles every JavaScript script and module in the project, validates [script] against the kinds the game exposes, writes neo.d.ts and neo.pyi into assets/scripts, and runs the game's own script tests if it has any. Takes no arguments.
Returns: { "ok": true | false, "report": [...] }, one line per file, check and test.
editor.scripts.live_reload#
| Name | Type | Description |
|---|---|---|
on | boolean | Required. Whether changed script files hot-reload in the running game. On by default. |
Returns: { "live_reload": true } or { "live_reload": false }.
When a running script's file changes, it reloads with its state kept. When a module file changes, scripts loaded or reloaded after that use the new version.