Lua scripting (ECS hooks)¶
The scripting crate hosts Lua 5.4 via mlua. Script hooks run on the engine fixed tick
(1/60 seconds) and can be sourced from a global script file, per-object script assets, or both.
Loading¶
Scripting initializes when at least one of the following is present:
environment variable
VGE_LUA_SCRIPTpointing to a global script fileone or more placed level objects with
script_asset_idmapped to script assets
The active scripts are loaded when a level is applied/loaded. There is no always-on hot reload loop in the editor runtime path.
Global hooks¶
``on_tick(dt)`` (optional)
Called every frame after per-instance hooks.
dtis the fixed timestep in seconds (same as the engine integrator).
``_instance_hooks`` (optional table)
Keys: level instance ids (the
instance_idfield saved in JSON for eachPlacedObject).Values: functions
function(dt, api) ... end.
``_entity_scripts`` (optional table)
Per-object script assets can return a function and are exposed by instance id. This supports attaching scripts from project assets to individual objects without hard-coding IDs in one monolithic script.
Lua API¶
The api table (per hook invocation) exposes:
Method |
Behavior |
|---|---|
|
Logs at |
|
Returns |
|
Returns |
|
Returns |
|
Returns |
|
Sets entity rotation and returns |
|
Returns per-frame mouse movement as |
|
Returns current mouse position as |
|
Requests mouse re-center in the host window on this tick. |
|
Requests cursor visibility change. |
|
Returns current camera angles as |
|
Updates camera angles and returns |
``api.default_instance`` duplicates the table key (the instance id passed as the hook’s table entry) for convenience.
Safety¶
Hooks run synchronously during EngineState::tick. The Rust side passes raw pointers to the live World only for the duration of Lua calls: do not call back into engine APIs from other threads, and avoid re-entrancy.
Sandbox and restrictions¶
The runtime disables dangerous globals and module loading helpers in script environments, including:
os, io, package, debug, dofile, loadfile, and require.
Plan scripts around engine-exposed APIs rather than filesystem/process access.
Example¶
See scripts/default_game.lua in the repository for a commented template.
Rust API surface¶
scripting::ScriptHost::from_file/try_from_envScriptHost::tick(&self, world: &mut World, entity_by_instance: &HashMap<u64, Entity>, dt)Legacy helpers:
LuaBackend,run_lua_file,ScriptHotWatch(scriptingcrate root).