FluxWareScripting
Back to site

What scripts can and cannot do

Scripts run inside a restricted Lua environment with hard execution limits. This page states exactly what that means, including the parts that will occasionally be inconvenient.

Why there is a sandbox

A script you install from the marketplace is code written by a stranger, running on your machine, inside your game. The sandbox exists so that the worst a bad script can do is be a bad module: it cannot read your files, open a network connection, start a process, read another script, or reach into FluxWare past the functions documented here.

The limits below are not configurable and there is no way for a script to ask for more. That is the point of them.

There is also no way around them by arriving another way. Scripts come from your account's library and the client will not load Lua from anywhere else, so every public script has been through review. There is no second channel that skips it.

What Lua you get

Lua 5.2 (LuaJ 3.0.1). These standard libraries are available in full:

  • base
  • table
  • string
  • math
  • bit32

Everything FluxWare adds on top is in the reference: the namespaces in the sidebar, plus the global module{} constructor.

What is removed

Each of these is absent from a script's environment. Referring to one gets you nil, not an error, so guard code that checks for them will simply take the other branch.

RemovedWhy
luajavaReaches arbitrary Java by name, which would step straight outside everything else on this page.
ioNo filesystem access of any kind.
osProcess and clock access. util.time() covers the only safe part.
packageNo require. A script is one file; there is nothing to require.
coroutineA LuaJ coroutine is a real Java thread and carries its own debug-hook state, so its body would run unbudgeted, on a new thread, inside a game frame.
loadDynamic chunks, including binary ones that skip the parser entirely.
loadfileFilesystem.
dofileFilesystem.
debugInstalled internally to drive the instruction budget, then removed so a script cannot clear its own hook.
collectgarbageLets a script stall the client on demand.
string.dumpEmits binary chunks.
No require, so one document
There is no module system, which means a script cannot be split up and cannot depend on another script. For anything that would be a shared library, copy the functions in. It is a real limitation, and it follows from there being no filesystem to resolve an import against.

Execution limits

Callbacks run on the game thread, in the middle of a tick or a frame. A script that loops forever would not be slow, it would be a frozen client. So every callback runs under an allowance and is stopped when it runs out.

instructionsPerCallback200,000
instructionsPerRenderCallback50,000
instructionsForScriptBody2,000,000
sourceBytes262,144
errorsBeforeAutoDisable3
errorWindowSeconds10

Exceeding an instruction budget stops the callback. pcall cannot catch it: the abort is deliberately not a Lua error, because a script that could catch its own budget violation inside a loop would hang the client.

In practice you will not meet these limits by accident. They are sized so that an honest overlay or a per-tick calculation has room to spare, and a runaway loop hits the wall in a fraction of a frame.

Scripts and bans

Worth saying plainly: the sandbox protects your machine, not your account. A script that sends chat, swings, or moves your player in a pattern a server considers suspicious can get you banned there, exactly as a badly configured built-in module can. Nothing in this environment prevents that, because from the server's point of view a script is just the client behaving.

Read what you install. The marketplace shows a script's full source before you install it, and that is there to be used. Review catches what a reviewer can see; it cannot tell whether a perfectly ordinary-looking combat script is one your server will tolerate.