Sandbox & Limits
The core runs inside the game process: a mod that misbehaves must never take Portal down. Every mod therefore runs inside layered containment.
Per-mod isolation
Section titled “Per-mod isolation”Each package gets its own Luau VM. There is no shared global state, no way for one mod’s variables to collide with another’s, and no API (yet) for inter-mod calls — isolation is total by default.
Resource budgets
Section titled “Resource budgets”| Budget | Value | Effect when exceeded |
|---|---|---|
| Memory | 64 MB per mod VM | Allocation raises a Luau error in that mod |
| Execution time | 5 s per VM entry (load, command dispatch, frame callback) | VM interrupt raises execution budget exceeded |
| Entry script size | 4 MB on disk | Rejected at discovery |
| Manifest size | 64 KB on disk | Rejected at discovery |
-- this mod kills only ITSELF at the memory wall:local sink = {}while true do sink[#sink + 1] = string.rep("x", 1024) end--> [USEMS] mods: FAILED 'my-mod' : entry failed: memory limit reached-- game keeps running; other mods unaffectedStandard-library sandbox
Section titled “Standard-library sandbox”Only the safe Luau libraries are loaded and sandbox(true) locks them
down: no file I/O, no process execution, no environment access, no debug
internals. The exact inventory is on the
Luau Standard Library page — verified by a runtime test,
not by aspiration.
Frozen registration
Section titled “Frozen registration”usems.register_command, register_cvar, and hook only work while
the entry script loads. Once it returns, the API surface freezes:
- The engine dispatches commands/hooks on its own thread; registration only ever happens on the loader thread. One writer, many readers.
- A command callback therefore cannot register new commands — declare everything up front and gate behavior inside callbacks instead.
Failure containment
Section titled “Failure containment”| Failure | Containment |
|---|---|
| Entry script raises | Mod marked FAILED, logged with the Luau error + line; nothing registered; game unaffected |
| Command callback raises | One warning line; the command stays registered |
| Frame hook raises | Callback unsubscribed with one warning; other hooks and mods keep running |
| Budget exceeded | Same as a raised error, at the boundary |
| Native crash in a mod’s C bridge (future) | SEH-guarded marshalling planned; today there are no native mod surfaces |
-- a failing hook removes only itself:usems.hook("frame", function() error("boom") end)-- [USEMS] my-mod: frame hook removed after error: boom-- (any other frame hooks in this mod still run)What is deliberately not sandboxed
Section titled “What is deliberately not sandboxed”Source console objects a mod registers are real engine objects. A mod can
register a command with FCVAR_CHEAT-less flags that executes console
strings — power is the point. The sandbox protects stability and privacy
(memory/files/process), not gameplay fairness; single-player games have no
referee to cheat.