godot-ui
Installation
SKILL.md
Godot UI (UI developer)
Version 0.1 (2026-10-02), part of Godot Expert Skills v0.1. Target: Godot 4.7.2.stable, macOS Apple Silicon.
Expert level here means one layout proven, by numbers and images, from a 1080x2400 phone in portrait to a 3840x2160 monitor, in every language, with mouse, pad and screen reader. The stretch transform scales, containers place, one Theme built in code styles, and nothing ships before a layout matrix and a contact sheet say so.
REQUIRED BACKGROUND: godot-expert (channels, review loop, 6.3 traps).
Stance (the expert delta)
- Pick the base size for the extremes, not for 1080p. A square base (720x720) with
canvas_items+expandand Handheld Orientationsensorgives one scale for portrait and landscape (docs, Multiple resolutions). Measured: 1.5x on a 1080x2400 phone in both orientations, 3x on 4K. A 1152x648 base gives a 0.9375x canvas on the same phone and three undersized buttons [added, measured]. Godotneers' 1920x1080 base (1_OFJLyqlXI) suits desktop only. - Containers place, anchors pin. Sizing is a negotiation: the minimum size is the floor, Expand claims leftover space, Fill uses it (Godotneers 1_OFJLyqlXI 00:35:00, Karto 5Hog6a0EYa0 00:14:39). Measured in a 400 px HBox: Expand without Fill leaves the claimed space empty (sibling pushed to x 380); Fill or a stretch ratio without Expand changes nothing; ratios are summed, 1:3 gives 96 and 290 of 386 px (Karto 00:15:45). Anchor presets are relative to the parent;
set_anchors_preset()alone keeps the old offsets (a 50x50 child stays 50x50 on FULL_RECT), so useset_anchors_and_offsets_preset()(Karto 00:05:24, measured). A corner element also needs its grow direction, or longer text grows off screen [added, measured 1462 px wide in a 1152 px canvas]. - The look lives in one Theme resource built in code, with type variations instead of per-node overrides (docs, Theme type variations). StyleBoxes are shared Resources: an override reused on two nodes changes both (Karto 00:19:00).
- Focus is explicit. Nothing has focus at scene start, so
ui_downdoes nothing until something callsgrab_focus()(docs, Controller navigation; measured). Keep a menu stack that disables covered panels and returns focus to the opener (Mostly Mad Productions ecJZipjUj6k 00:08:57). - The current selection is the highest-contrast element on screen, body text comes first, two or three fonts at most, and the outro is faster than the intro (Rawb Herb, GodotCon 2025, sjmAD1ZLBcE 00:31:42, 00:21:34, 00:55:38).
- Text is keys, never literals. Named placeholders with
format(),tr_n()for plurals, context for identical English, auto translate disabled on dynamic text (docs, Internationalizing games). Fonts get fallbacks, not remaps. - HUD is passive and signal-driven. Its root and wrappers ignore the mouse; values change on signals, not in
_process(consensus of 1_OFJLyqlXI, Yuw7CK5H8eA, f90ieBOoIYQ). A new string reshapes (200 labels: 1.1 to 1.5 ms of CPU per frame); assigning the identical string is an early-out, so the cost is the changed text, not the assignment [added, measured]. In-place array mutations never call a setter (0 calls afterappend, 1 after reassigning), so state arrays emit their own signal (NoBSGodot Yuw7CK5H8eA 00:05:06, measured). - Verify at device sizes headless, then look. Headless,
root.sizetakes any size and applies the project stretch, so a layout matrix runs in seconds; a windowed capture then renders each device with the notch drawn in [added, measured].