Every node type and the fields it accepts.
HUD nodes
A node is one element in a HUD tree — a panel, a label, a button. You author nodes in a *.hud.json document; the runtime draws the tree and scripts mutate it. This page lists every node type, what it renders, and the fields it accepts.
How a node is written
{
"id": "health_bar",
"type": "progress",
"value": 1.0
}
id— stable name used by scripts and events. Document-wide and unique.type— which node kind to build. Optional; defaults tocontainer.- Every other field depends on the type. Shared layout fields are covered in Layout.
container
Groups children and arranges them. Renders nothing itself — it is a box for layout.
{
"id": "toolbar",
"type": "container",
"stack": "row",
"gap": 8,
"children": []
}
Renders an invisible region whose children flow in a row with 8 units between them.
panel
A visible grouped box with a background color. Use it for cards, bars, and dialogs.
{
"id": "card",
"type": "panel",
"background_color": "#1b1c27cc",
"pad": 16,
"children": []
}
Renders a filled rectangle behind its children. background_color accepts [r, g, b, a] (0…1) or a hex string.
label
Read-only text. The most common node in Skyforge’s HUD.
{
"id": "score",
"type": "label",
"text": "Score: ${score}",
"font_size": 24
}
Renders one text line (or a wrapped block). text supports ${variable} interpolation. Text styling lives in Text, theme & locale.
text
Display text with the same rendering as label, intended where content is long or updated heavily (chat, logs, tooltips).
{
"id": "chat_log",
"type": "text",
"text": "",
"text_wrap": "word",
"max_lines": 8
}
Renders a multi-line text block. Same fields as label; pick either — the rendering contract is shared.
image
A texture rectangle. Portraits, icons, backgrounds.
{
"id": "portrait",
"type": "image",
"texture": "asset://ui/hero",
"size": [128, 128]
}
texture— anasset://URI pointing at an imported image asset. Required for the image to show.size— canvas units. The texture is centered inside this box with its source aspect ratio preserved, including when the canvas and window have different proportions.
Renders the referenced texture. Swap it at runtime with Hud.set_image(id, texture, source_x, source_y, source_width, source_height).
button
A pressable control with a text caption. Interactive.
{
"id": "start",
"type": "button",
"text": "Launch",
"action": "ui_ok",
"disabled": false,
"focusable": true
}
text— the caption rendered on the button.action— input action name that activates this button (the gamepad south button, Enter, a virtual button). Optional; pointer clicks always work.disabled— boolean. A disabled button renders dimmed and does not accept input.focusable— boolean. Whether keyboard/gamepad focus can land here.
Renders a labeled button. Presses arrive as UI events; see HUD from Lua.
toggle
A boolean switch — music on/off, invert-y.
{
"id": "toggle_music",
"type": "toggle",
"text": "Music",
"checked": true,
"action": "ui_ok"
}
checked— boolean start state.action— activates the toggle like a button.disabled,focusable— same meaning as button.
Renders a checkbox-style switch. Read and write with Hud.set_checked / the value-changed event.
slider
A draggable value within a range — volume, brightness.
{
"id": "volume",
"type": "slider",
"value": 0.8,
"min_size": [200, 32]
}
value— start position withinminimum…maximum.minimum/maximum— the slider range; defaults 0 and 1.disabled,focusable— same meaning as button.
Renders a track and knob. Dragging emits value_changed; Hud.set_value(id, n) moves it from scripts.
text_input
An editable text field — player name, seed entry.
{
"id": "seed_input",
"type": "text_input",
"text": "",
"placeholder": "World seed",
"action": "ui_ok"
}
text— current contents.placeholder— hint shown while empty.action— activates the field (focuses it) from a pad or key.disabled,focusable— same meaning as button.
Renders an editable line. Read with Hud.get_text(id); raise the on-screen keyboard with Input.set_text_input_active (see Virtual & touch input).
scroll
A viewport over larger content. Children draw inside; the user drags to pan.
{
"id": "scroll",
"type": "scroll",
"children": []
}
Renders a clipped region that scrolls when content is taller or wider than the box. Combine with long lists and the virtualization helpers in HUD from Lua.
list
A stacked collection of rows — inventory, lobby players, chat.
{
"id": "inventory_list",
"type": "list",
"stack": "column",
"gap": 4,
"children": []
}
Renders a vertical (or configured) run of child rows. For very long lists see virtualization in HUD from Lua.
progress
A 0…1 meter — health, load bar, cooldown.
{
"id": "health_bar",
"type": "progress",
"value": 1.0
}
value— filled fraction from 0 to 1. Start value; update withHud.set_value("health_bar", 0.75).
Renders a track filled to the current value. It is display-only — it never accepts input.
modal
A dialog that traps focus while it is open — confirm quit, level complete.
{
"id": "quit_dialog",
"type": "modal",
"visible": false,
"children": [
{ "id": "quit_text", "type": "label", "text": "Quit Skyforge?" },
{ "id": "quit_yes", "type": "button", "text": "Yes", "action": "ui_ok" },
{ "id": "quit_no", "type": "button", "text": "No", "action": "ui_cancel" }
]
}
visible— boolean. Keep dialogs hidden until needed.children— the dialog body.
Renders its children as a dialog layer and holds Tab, arrows, and D-pad focus inside until closed. Show it with Hud.set_visible("quit_dialog", true).
virtual_button
An on-screen button that publishes a virtual input (see Virtual & touch input).
{
"id": "jump_btn",
"type": "virtual_button",
"control": "jump",
"size": [140, 140]
}
control— name published asvirtual:jumpwhile pressed. Required.
Renders a round pressable control. Bound actions read as pressed while a finger is down.
virtual_stick
An on-screen analog stick that publishes a virtual input.
{
"id": "move_stick",
"type": "virtual_stick",
"control": "move",
"size": [220, 220]
}
control— publishesvirtual:move(both axes),virtual:move:x, orvirtual:move:y. Required.
Renders a base and knob. Dragging the knob drives the bound vector2 action.
Interactive fields
Interactive nodes — button, toggle, slider, text_input, virtual controls — share these fields:
| Field | Type | Meaning |
|---|---|---|
action | string | Input action name that activates the control from keyboard, gamepad, or a virtual button. |
disabled | boolean | true blocks all input and dims the control. |
focusable | boolean | Whether Tab, arrows, and D-pad can focus the control. Defaults to interactive types being focusable. |
Accessibility fields
Every node accepts:
| Field | Type | Meaning |
|---|---|---|
accessibility_label | string | Spoken name of the control, e.g. “Jump”. |
accessibility_description | string | Longer spoken hint, e.g. “Leaps over gaps”. |
accessibility_hidden | boolean | Hides decorative nodes from assistive technology. |
Give every interactive control a label. Mark purely decorative images accessibility_hidden. Focus is shared across Tab, arrows, D-pad, and pointer; a modal traps it until closed.
Next
- Layout — dock, stack, anchors, safe areas.
- Text, theme & locale — fonts, variables, styles.
- HUD from Lua — setters and events.
- UI & HUD — the overview page.
Panels that block world clicks
Set blocks_pointer: true on an enabled panel or container to capture pointer clicks over its rectangle without putting it in keyboard/controller focus navigation. The default is false; ordinary decorative panels let clicks through. Child buttons still receive clicks in front of the panel. Hidden ancestors and scroll clipping apply normally.
{"id":"build_menu", "type":"panel", "size":[320,240], "blocks_pointer":true}
The HUD Inspector exposes Interaction → Block pointer. Gameplay should check Input.ui_pointer_captured() before acting on a mouse press, or pass a touch ID for touch input. This prevents a construction-menu click from also placing a building in the world. demi hud inspect --format json reports the resolved blocking flag.