Reference for the Lua scripting surface. A script is a .lua file attached to
an entity (via a Script component). It defines lifecycle hooks the engine
calls, reads context globals (live per-frame state), and calls API
functions to act on the world.
Backend note: Lua is the native backend (
mlua, Lua 5.4). A Rhai backend exists with a subset of the same surface.
function props() -- declare editor-exposed / persistent variables
function on_ready() -- once, when the entity's script starts
function on_update() -- every frame
function on_rpc(name, args, from) -- networked RPC received
function on_ui(name, args, entity) -- markup callback (on_press, etc.)
function on_http(name, code, body) -- HTTP response (http_get/http_post)
function on_player_joined(id) -- server: a player connected
function on_player_left(id) -- server: a player disconnectedReturn a table declaring variables. They show in the inspector and persist:
their runtime values are read back from the VM each frame, so a UI template can
bind them ({{ Entity.varname }}).
function props()
return {
speed = { type = "float", value = 5.0, hint = "Move speed" },
enabled = { type = "bool", value = true },
label = { type = "string", value = "hi" },
_t = { type = "float", value = 0.0, hint = "Internal (underscore = hidden-ish)" },
}
endTypes: float, int, bool, string, vec2, vec3, color.
delta— seconds since last frameelapsed— seconds since start
position_xposition_yposition_zrotation_xrotation_yrotation_zscale_xscale_yscale_z
has_parentparent_position_xparent_position_yparent_position_z
self_entity_id,self_entity_nameself_health,self_max_health
mouse_xmouse_y— cursor positionmouse_delta_xmouse_delta_y— movement this framemouse_leftmouse_rightmouse_middle— heldmouse_left_just_pressedmouse_right_just_pressedmouse_scroll
input_xinput_y— normalized movement intent
- Sticks:
gamepad_left_xgamepad_left_ygamepad_right_xgamepad_right_y - Triggers:
gamepad_left_triggergamepad_right_trigger - Buttons (bool):
gamepad_southgamepad_eastgamepad_westgamepad_northgamepad_l1gamepad_r1gamepad_l2gamepad_r2gamepad_l3gamepad_r3gamepad_selectgamepad_start - D-pad:
gamepad_dpad_upgamepad_dpad_downgamepad_dpad_leftgamepad_dpad_right
camera_yaw,camera_ev(auto-exposure EV-100)
is_collidingtimers_finished— set when astart_timerelapses (see Timers)
set_position(x, y, z) set_rotation(x, y, z) -- euler degrees
set_scale(x, y, z) set_scale_uniform(s)
translate(x, y, z) rotate(x, y, z)
look_at(x, y, z)parent_set_position(x, y, z) parent_set_rotation(x, y, z) parent_translate(x, y, z)
set_child_position(name, x, y, z) set_child_rotation(name, x, y, z) child_translate(name, x, y, z)get("Component.field") -- read on self -> value
set("Component.field", value) -- write on self
get_on("EntityName", "Component.field") -- read on a named entity
set_on("EntityName", "Component.field", value)
get_component("Component") -- whole component as a table
get_component_on("EntityName", "Component")
get_components() -- list component type names on self
get_components_on("EntityName")
has_component("Component") -- bool
has_component_on("EntityName", "Component")value accepts numbers, bools, strings, and {x=,y=,z=} / {r=,g=,b=,a=}
tables for vectors/colors. Field paths support nesting: Transform.translation.x,
Sun.color.x.
is_key_pressed("KeyW") is_key_just_pressed("Space") is_key_just_released("Escape")
input_button_pressed("name") input_button_just_pressed("name") input_button_just_released("name")
input_axis_1d("name") -- -> float
input_axis_2d("move") -- -> x, y (two return values)Key names match Bevy KeyCode (KeyW, ArrowUp, Space, Enter, Escape,
ShiftLeft, …). Actions/buttons work for keyboard + gamepad uniformly.
play_sound(path [, volume] [, bus]) -- one-shot SFX (bus default "Sfx")
play_sound_looping(path, volume)
play_music(path [, volume] [, fade_in]) -- looped, bus "Music"
stop_music([fade_out])
stop_all_sounds()
play_audio([entity_name]) -- fire an entity's AudioPlayer poolplay_animation(name) stop_animation() pause_animation() resume_animation()
set_animation_speed(speed)
crossfade_animation(name, duration)
-- animation graph / state machine params:
set_anim_bool(name, value) set_anim_param(name, value) trigger_anim(name)
set_layer_weight(layer, weight)spawn_entity(...) -- spawn an entity
spawn_primitive(...) -- spawn a primitive shape
despawn_self()
despawn_by_prefix(prefix) -- despawn entities whose name starts with prefix
load_scene(path)apply_force(...) apply_impulse(...) set_velocity(...) set_gravity_scale(scale)set_visibility(visible) -- self
set_material_color(...)set_sun_angles(azimuth, elevation)
set_fog(...)start_timer(name, duration [, repeat])
stop_timer(name)
-- when a timer elapses, `timers_finished` reflects it for that framelock_cursor() unlock_cursor()
screen_shake(...)rpc(name, args) -- send an RPC to peers
net_is_server() net_is_client() net_is_connected()
net_player_count()http_get(url [, callback]) -- callback default "get"
http_post(url, body [, callback]) -- body = JSON string; callback default "post"
json_parse(str) -- JSON string -> Lua table/value (nil on error)
-- result delivered to: function on_http(name, code, body)Requests run on a background thread; the game loop never blocks. The handling
script typically json_parses the body and stores a value in a props()
variable, which a UI template then binds.
action(name [, args_table]) -- trigger a ScriptAction observed by domain crates
action_on(entity_name, name [, args]) -- targeted at another entityUsed for engine verbs without a dedicated function (e.g. UI spawn:
action("hui_spawn", { template = "templates/menu.html" })).
is_loaded() is_loading()
asset_progress() -- table: { state, fraction, loaded_files, total_files, ... }print(...) -- standard Lua print
print_log(msg) -- engine log
clamp(v, min, max) lerp(a, b, t)
vec2(x, y) vec3(x, y, z) -- construct vector tablesfunction on_update()
local mx, my = input_axis_2d("move")
translate(mx * speed * delta, 0, my * speed * delta)
endfunction on_update()
set_on("World Environment", "Sun.azimuth", (elapsed * 10) % 360)
endfunction on_ready() http_post("https://api.example.com/login", body, "login") end
function on_http(name, code, body)
if name == "login" and code == 200 then
local d = json_parse(body)
username = d.user.username -- a props() var -> bind {{ Entity.username }}
end
end-- markup: <button on_press="start">Play</button>
function on_ui(name)
if name == "start" then load_scene("scenes/level1.scn") end
endThis reference is generated from the registered Lua surface in
crates/renzora_scripting/src/backends/lua.rs. Exact argument lists for a few verbs (spawn/physics/animation) may have additional optional params; check the source if a call is rejected.