Skip to content

Sandbox ​

Scripts run in a restricted Lua 5.4 environment. Only a subset of the standard library is loaded. Anything that touches the filesystem, OS, or arbitrary module loading is blocked. Network access goes through a separate API that can be disabled from the menu.

Loaded libraries ​

  • base, core language functions (type, pairs, pcall, tostring, error, etc.)
  • math, math functions (sin, cos, sqrt, floor, random, etc.)
  • string, string manipulation (find, format, sub, gsub, match, etc.)
  • table, table operations (insert, remove, sort, concat, unpack, etc.)
  • coroutine, coroutine control (yield, resume, create, wrap, etc.)
  • utf8. Unicode string handling (len, codes, char, codepoint, etc.)

Blocked libraries ​

  • io. No file read/write
  • os. No os.execute, os.remove, os.clock, etc.
  • package. No require paths or module loading
  • debug. No debug.getinfo, debug.sethook, stack inspection

Common replacements ​

Replacements for common blocked libraries:

  • Need to persist data? Use Storage instead of io.
  • Need timing? Use the global clock() function instead of os.clock.
  • Need network access? Use the HTTP library, opt-in, kill-switchable from the menu.
  • Need modular code? Use export and import. require is blocked, but the engine provides two globals for cross-script module sharing:
lua
-- In your library script (e.g. utils.lua):
export("utils", {
    clamp = function(v, lo, hi) return math.max(lo, math.min(hi, v)) end,
})

-- In any other script:
local utils = import("utils")
if utils then
    local x = utils.clamp(value, 0, 100)
end

export(name, module) registers a table under a name. import(name) fetches it; returns nil if the exporting script hasn't loaded yet, so guard with an if.

Not affiliated with Valve Corporation.