Skip to main content
Euca embeds a sandboxed Lua VM (euca-script, via mlua) so you can attach per-entity behavior scripts that read and write the world through a small euca API, with an instruction budget and hot reload. Scripts run each tick in script_tick_system.
Lua needs a ScriptEngine resource that the default server doesn’t register. On the reference headless_server, POST /script/load returns {"ok":false,"message":"No ScriptEngine resource in world"} — the engine isn’t registered by default (the same “register the resource on your host” pattern as templates and input bindings). Register a ScriptEngine on your server build to enable Lua.

What it does

  • Sandbox — dangerous globals are removed, and each script call is capped at an instruction budget (default 100,000) so a runaway loop can’t hang the tick.
  • ECS bridge — the euca global exposes spawn(), despawn(id), get_position(id) / set_position(id,x,y,z), get_health(id) / set_health(id,v), delta_time(), and an event API on("event", fn) / emit("event", …).
  • Per-entity scripts — a ScriptComponent (script name, update function, enabled flag) attaches a script to an entity; script_tick_system calls its update function each tick.
  • Hot reload — a file watcher reloads changed scripts at runtime.
  • Fork-safe — the engine is shared as Arc<Mutex<ScriptEngine>>, so a forked world reuses the same VM rather than cloning it.

Endpoints

MethodPathDescription
POST/script/loadLoad a .lua file and attach it to an entity
GET/script/listList entities with attached scripts

Example

curl -s -X POST http://localhost:3917/script/load \
  -H 'Content-Type: application/json' \
  -d '{"entity_id":0,"path":"scripts/spin.lua"}'
# On a server with a ScriptEngine: {"ok":true, ...}
# On the stock headless server:   {"ok":false,"message":"No ScriptEngine resource in world"}
-- scripts/spin.lua — runs each tick for the attached entity
function update(id)
  local x, y, z = euca.get_position(id)
  euca.set_position(id, x, y + euca.delta_time(), z)
end

Status

  • ✅ Sandboxed Lua VM, instruction budget, ECS bridge, per-entity scripts, hot reload, fork-safe sharing — shipped.
  • 🟡 The default headless server does not register a ScriptEngine (see the warning above).

Script endpoints

Load and list endpoints with schemas.