UI
Balaur has two UI layers, both script-facing.
Widgets: game HUDs as scene nodes
The widget component turns a node into a HUD element — label, button,
or panel — anchored to a screen corner or the center:
[[nodes]]
name = "Score"
[nodes.widget]
kind = "label"
text = "Score 0"
anchor = "top_left"
x = 20
y = 16
font_size = 22
text_color = "#2b2b2b"
Widgets live in the scene tree like any node, so they are saved with the
scene, editable in the editor (which previews them in its viewport), and
updatable from scripts through node:get_component("widget") /
set_component. ui.set_widget_layer scopes and toggles the layer.
The ui module: immediate-mode UI
For tools and anything beyond a HUD, the ui module exposes immediate-mode
egui to scripts. A script implements a
draw_ui lifecycle method, which runs once per frame inside the egui pass:
function Tool:draw_ui()
ui.left_panel("outline", { width = 260, fill = colors.bg }, function()
ui.label("Nodes", { size = 14, color = colors.text })
if ui.pill("Add node", { fill = colors.accent }) then
-- ...
end
end)
end
Panel and container calls take a callback and push their child UI around it,
so a script composes layouts exactly like Rust egui code. The widget set
includes panels, labels, pills, toggles, sliders, drag values, selects, text
fields, modals, scroll areas, menus, shortcuts, and ui.code_editor — an
editable, Luau-syntax-highlighted buffer.
Widgets take colors per call, so complete themes live in scripts and hot
reload with them. Fonts load from <project>/fonts/*.ttf, with the named
families heading / ui / mono always available.
All dimensions are design pixels: ui.set_scale(f) multiplies every metric
and the query functions divide back, so scripts author against the design's
pixel values at any zoom. HiDPI is separate and automatic.
The editor's entire interface is built with this module; see The editor.