Lua scripting
The safe extension tier: sandboxed Lua scripts that can add commands and edit the document, but cannot touch the machine.
Host: src/scripting/ (ScriptHost). Native plugins are the
trusted tier; scripts are the safe tier.
The sandbox
One shared Lua state loads every *.lua in a directory at startup.
Only base, table, string and math are
opened — no io, no os, no
package/require, no debug — and
dofile/loadfile/load are removed. A script
gets exactly one entry point: its own file. It can compute and contribute, but
not read the disk or shell out.
The yu3d table
yu3d.register_command{ id=, label=, group=, run=function(doc) ... end }
yu3d.log(message) -- to the developer console/log
yu3d.show(message) -- user-visible (host dialog), falls back to log
The document handle
A command's run receives a doc handle, valid only while
the command runs (it cannot be stashed for later):
doc:nodes() -- array of { id=, name=, type= }
doc:add_group(name) -- returns id (undoable)
doc:rename(id, name) -- (undoable)
doc:set_property(id, key, value) -- bool/int/real/text (undoable)
Edits go through the same undoable Edit path as the UI, and
set_property uses the generic property API, so a script can drive
any module or plugin node type.
Execution model
- One shared interpreter, created lazily, kept for the process lifetime.
- Commands run synchronously, one at a time; the current
Document*is bound for the duration. - Parse/runtime errors are logged and the offending file is skipped — a bad script can't take down the host.
int load_scripts(const string& dir); // non-recursive *.lua scan, returns count loaded