Sandbox & Limits
Resource scripts do not get the full standard library of their language. Anything that reaches outside the game, or that could take the server or a player's game down with it, is either missing or capped. This page lists what is actually there.
Runaway Scripts
A single script call (one thread step, one event handler, one exported function) may run for at most 5 seconds and the VM may use at most 256 MiB of memory. A script that goes over either one is stopped with an error, and the whole resource is shut down: a script that ran away once does it again on the next tick.
This safety net covers Lua and JavaScript. In a Squirrel script an endless loop that never
calls Thread.Pause will freeze the server, or the game of every player who loaded the resource,
and nothing will step in.
The 5 seconds are per call, not per resource. Long work belongs in a
thread that calls Thread.Pause(0) in its loop: each tick is its own call and
gets its own 5 seconds.
Lua
Available:
| Library | |
|---|---|
base, table, string, math, utf8 | fully available |
os | without execute, exit, remove, rename, setlocale, tmpname, getenv |
debug | read-only part only: traceback and getinfo work, anything that changes state does not |
io | Server only |
Not available:
coroutine, superseded by the Thread API, which is built on itpackageandrequire. There is no module loader; list every script in the meta file insteaddofileandloadfile
JavaScript
The engine is a small embedded one, not a browser and not Node.js. The language itself is
complete and current (ES2025: classes, async/await, Map and Set with the set methods,
iterator helpers, typed arrays, Date, RegExp, JSON and so on; Temporal is not there), but
the host objects of those environments are not:
- No
import,exportorrequire. Every<script>of the resource runs as a plain script in one shared global scope; list the files in the meta file in the order they depend on each other. - No
setTimeout,setIntervalorfetch. Use the Timer and HTTP functions, which are the same in every language. - No file system, no processes, no network beyond the HTTP functions.
console.log,console.info,console.warn,console.errorandprintwrite to the server/client log, likeConsole.Log. Objects are printed as JSON.
Numbers are converted on the way into the API: a whole number becomes a 32-bit int, anything
with a fraction a single-precision float, see Event Arguments.
A number too large for an int therefore loses precision; send large IDs as strings.
The call stack is limited. Recursion that goes a few thousand levels deep ends in a
RangeError that you can catch, not in a crash.
Squirrel
deprecatedAvailable:
| Library | |
|---|---|
string, math | fully available |
io, system | Server only |
time | Client only |
The blob library is not registered.
Always-Present Globals
Two globals are set up before your scripts run and are part of the API rather than of your resource:
Do not assign to Exports or Timer. They are ordinary globals, so overwriting one breaks it for
every script in the resource.