/godot-ui-control
Build Godot 4.7 user interfaces with Control nodes: anchors and offsets for responsive layout, Container nodes (VBox/HBox/Grid/Margin) for automatic arrangement, Theme resources for consistent styling, and keyboard/gamepad focus navigation. Use when laying out a HUD, menu, or UI
$ npx -y skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-ui-control --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/godot-ui-control
Context preview
The summary Claude sees to decide when to auto-load this skill.
Build Godot 4.7 user interfaces with Control nodes: anchors and offsets for responsive layout, Container nodes (VBox/HBox/Grid/Margin) for automatic arrangement, Theme resources for consistent styling, and keyboard/gamepad focus navigation. Use when laying out a HUD, menu, or UI
SKILL.md
godot-ui-control.SKILL.mdname: godot-ui-control
description: >
Build Godot 4.7 user interfaces with Control nodes: anchors and offsets for
responsive layout, Container nodes (VBox/HBox/Grid/Margin) for automatic
arrangement, Theme resources for consistent styling, and keyboard/gamepad focus
navigation. Use when laying out a HUD, menu, or UI in a Godot project, working
with Control/Container nodes, anchors, themes, or focus in a .tscn.
Godot UI / Control nodes (4.x)
Lay out responsive UI with `Control` anchors and `Container` nodes, style it with a `Theme`, and make it navigable by keyboard and gamepad. Targets **Godot 4.7**.
When to use
- Use when building HUDs, menus, inventories, dialog boxes, or settings screens with
`Control`-derived nodes; arranging UI that adapts to window size; theming; or wiring focus navigation for controller/keyboard.
**When *not* to use:** in-world 2D nodes (`Node2D`/sprites) → `godot-nodes-scenes`; animating UI transitions → `godot-animation` (Tween); genre UIs like card hands → `card-game`/`visual-novel`. For full input rebinding → `input-systems`.
Core workflow
1. **Use `Control` nodes for UI**, not `Node2D`. Controls have a rect (position + size), anchors, and participate in focus/theming. 2. **Anchor for responsiveness.** Anchors are fractions (0–1) of the parent rect that the Control's edges stick to. Use the editor's **Layout** presets (Top-Left, Full Rect, Center, etc.) instead of hand-placing pixels. 3. **Let Containers position children.** Put children in a `VBoxContainer`, `HBoxContainer`, `GridContainer`, `MarginContainer`, etc. — the container sets their position/size; you control flow with `size_flags`. Don't set child anchors inside a container (it overrides them). 4. **Style with a `Theme`.** Assign a `Theme` resource on a top Control; children inherit it. Override per-node with theme overrides only when necessary. 5. **Wire focus** so gamepad/keyboard can move between buttons; set a default focused control and define neighbors or rely on auto-neighbor. 6. **Connect signals** (`pressed`, `toggled`, `text_submitted`, `value_changed`).
Patterns
1. Responsive layout with anchors (code form)
extends Control
func _ready() -> void:
# Stretch this panel to fill its parent (equivalent to the "Full Rect" preset).
anchors_preset = Control.PRESET_FULL_RECT
# Or set anchors manually: all four edges at the parent's far corners.
# anchor_left = 0; anchor_top = 0; anchor_right = 1; anchor_bottom = 12. A menu built from containers + button signals
extends VBoxContainer # children stack vertically, auto-sized
func _ready() -> void:
for child in get_children():
if child is Button:
child.pressed.connect(_on_button_pressed.bind(child.name))
# Give the first button focus so a gamepad can navigate immediately.
if get_child_count() > 0:
(get_child(0) as Control).grab_focus()
func _on_button_pressed(which: StringName) -> void:
match which:
"PlayButton": get_tree().change_scene_to_file("res://game.tscn")
"QuitButton": get_tree().quit()3. Size flags: make one child expand to fill leftover space
# In a HBoxContainer: a label on the left, a spacer that eats remaining width.
func _ready() -> void:
$Label.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
$Spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL # grows to fill4. Theme override for one node (without a full Theme resource)
func _ready() -> void:
# Per-node overrides: use add_theme_* (type-specific setters).
$Title.add_theme_font_size_override("font_size", 32)
$Title.add_theme_color_override("font_color", Color.GOLD)
$Panel.add_theme_stylebox_override("panel", preload("res://ui/panel.stylebox.tres"))Pitfalls
- **Mixing manual position with Containers.** A child of a `Container` cannot set its own
position/anchors — the container owns layout. To free-place, take the node out of the container or use a plain `Control`/`PanelContainer` wrapper.
- **Anchors vs offsets.** Anchors are fractions of the parent; offsets are pixel deltas
from the anchored point. Set anchors via presets, then nudge with offsets. Setting only position while anchors are at 0 makes UI not scale with the window.
- **`Node2D` for UI.** Buttons/labels parented under a `Node2D` won't theme or take focus
correctly. Keep UI under a `CanvasLayer`/`Control` subtree.
- **Focus lost on gamepad.** If nothing is focused, directional input does nothing. Call
`grab_focus()` on an initial control and ensure `focus_mode` is not `FOCUS_NONE`.
- **Theme vs theme override.** A `Theme` resource styles a whole subtree; `add_theme_*`
overrides one node. Overusing per-node overrides defeats centralized theming.
- **`rect_*` properties are renamed.** Godot 3's `rect_size`/`rect_position`/`rect_min_size`
are now `size`/`position`/`custom_minimum_size` in 4.x.
- **`mouse_filter`** on a full-rect Control can swallow clicks meant for nodes beneath it;
set `MOUSE_FILTER_IGNORE` on purely decorative panels.
References
- For the anchor/offset math, every Container type, building/extending Theme and StyleBox
resources, focus neighbor wiring, and `CanvasLayer` for HUDs, read `references/layout-and-theming.md`.
Related skills
- `game-ui-ux` — cross-engine UI/UX: responsive scaling, safe areas, focus navigation, screen flow.
- `godot-animation` — Tween-based UI transitions and juicing.
- `godot-signals-groups` — connecting UI events to game logic.
- `input-systems` — rebindable input and multi-device focus.
- `card-game` / `visual-novel` — UI-heavy genre templates.
Read more
name: godot-ui-control description: > Build Godot 4.7 user interfaces with Control nodes: anchors and offsets for responsive layout, Container nodes (VBox/HBox/Grid/Margin) for automatic arrangement, Theme resources for consistent styling, and keyboard/gamepad focus navigation. Use when laying out a HUD, menu, or UI in a Godot project, working with Control/Container nodes, anchors, themes, or focus in a .tscn.
Godot UI / Control nodes (4.x)
Lay out responsive UI with `Control` anchors and `Container` nodes, style it with a `Theme`, and make it navigable by keyboard and gamepad. Targets **Godot 4.7**.
When to use
- Use when building HUDs, menus, inventories, dialog boxes, or settings screens with
`Control`-derived nodes; arranging UI that adapts to window size; theming; or wiring focus navigation for controller/keyboard.
**When *not* to use:** in-world 2D nodes (`Node2D`/sprites) → `godot-nodes-scenes`; animating UI transitions → `godot-animation` (Tween); genre UIs like card hands → `card-game`/`visual-novel`. For full input rebinding → `input-systems`.
Core workflow
1. **Use `Control` nodes for UI**, not `Node2D`. Controls have a rect (position + size), anchors, and participate in focus/theming. 2. **Anchor for responsiveness.** Anchors are fractions (0–1) of the parent rect that the Control's edges stick to. Use the editor's **Layout** presets (Top-Left, Full Rect, Center, etc.) instead of hand-placing pixels. 3. **Let Containers position children.** Put children in a `VBoxContainer`, `HBoxContainer`, `GridContainer`, `MarginContainer`, etc. — the container sets their position/size; you control flow with `size_flags`. Don't set child anchors inside a container (it overrides them). 4. **Style with a `Theme`.** Assign a `Theme` resource on a top Control; children inherit it. Override per-node with theme overrides only when necessary. 5. **Wire focus** so gamepad/keyboard can move between buttons; set a default focused control and define neighbors or rely on auto-neighbor. 6. **Connect signals** (`pressed`, `toggled`, `text_submitted`, `value_changed`).
Patterns
1. Responsive layout with anchors (code form)
extends Control
func _ready() -> void:
# Stretch this panel to fill its parent (equivalent to the "Full Rect" preset).
anchors_preset = Control.PRESET_FULL_RECT
# Or set anchors manually: all four edges at the parent's far corners.
# anchor_left = 0; anchor_top = 0; anchor_right = 1; anchor_bottom = 12. A menu built from containers + button signals
extends VBoxContainer # children stack vertically, auto-sized
func _ready() -> void:
for child in get_children():
if child is Button:
child.pressed.connect(_on_button_pressed.bind(child.name))
# Give the first button focus so a gamepad can navigate immediately.
if get_child_count() > 0:
(get_child(0) as Control).grab_focus()
func _on_button_pressed(which: StringName) -> void:
match which:
"PlayButton": get_tree().change_scene_to_file("res://game.tscn")
"QuitButton": get_tree().quit()3. Size flags: make one child expand to fill leftover space
# In a HBoxContainer: a label on the left, a spacer that eats remaining width.
func _ready() -> void:
$Label.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
$Spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL # grows to fill4. Theme override for one node (without a full Theme resource)
func _ready() -> void:
# Per-node overrides: use add_theme_* (type-specific setters).
$Title.add_theme_font_size_override("font_size", 32)
$Title.add_theme_color_override("font_color", Color.GOLD)
$Panel.add_theme_stylebox_override("panel", preload("res://ui/panel.stylebox.tres"))Pitfalls
- **Mixing manual position with Containers.** A child of a `Container` cannot set its own
position/anchors — the container owns layout. To free-place, take the node out of the container or use a plain `Control`/`PanelContainer` wrapper.
- **Anchors vs offsets.** Anchors are fractions of the parent; offsets are pixel deltas
from the anchored point. Set anchors via presets, then nudge with offsets. Setting only position while anchors are at 0 makes UI not scale with the window.
- **`Node2D` for UI.** Buttons/labels parented under a `Node2D` won't theme or take focus
correctly. Keep UI under a `CanvasLayer`/`Control` subtree.
- **Focus lost on gamepad.** If nothing is focused, directional input does nothing. Call
`grab_focus()` on an initial control and ensure `focus_mode` is not `FOCUS_NONE`.
- **Theme vs theme override.** A `Theme` resource styles a whole subtree; `add_theme_*`
overrides one node. Overusing per-node overrides defeats centralized theming.
- **`rect_*` properties are renamed.** Godot 3's `rect_size`/`rect_position`/`rect_min_size`
are now `size`/`position`/`custom_minimum_size` in 4.x.
- **`mouse_filter`** on a full-rect Control can swallow clicks meant for nodes beneath it;
set `MOUSE_FILTER_IGNORE` on purely decorative panels.
References
- For the anchor/offset math, every Container type, building/extending Theme and StyleBox
resources, focus neighbor wiring, and `CanvasLayer` for HUDs, read `references/layout-and-theming.md`.
Related skills
- `game-ui-ux` — cross-engine UI/UX: responsive scaling, safe areas, focus navigation, screen flow.
- `godot-animation` — Tween-based UI transitions and juicing.
- `godot-signals-groups` — connecting UI events to game logic.
- `input-systems` — rebindable input and multi-device focus.
- `card-game` / `visual-novel` — UI-heavy genre templates.
<img src="docs/assets/banner.png" width="820" alt="awesome-gamedev-agent-skills — game-dev skills for AI coding agents.
Repo: gamedev-skills/awesome-gamedev-agent-skills
Other skills on awesome-gamedev-agent-skills.
- /audio-design
Implement game audio practice — bus/mixer architecture and gain in decibels, ducking (sidechain), adaptive/dynamic music via layering and re-sequencing, SFX variation, and beat synchronization. Engine-neutral. Use when the user mentions audio mixing, audio buses,
Open skill - /camera-systems
Build game cameras that feel good — 2D follow with a deadzone, look-ahead, smoothing, and level-bounds clamping; 3D third-person orbit with collision and first-person look; plus multi-target framing and a shake hook. Engine-neutral techniques that pair with the engine's camera
Open skill - /create-game-assets
Plan, generate, source, normalize, and validate cohesive visual game assets. Use for art direction, style bibles, sprites, tilesets, backgrounds, UI art, icons, textures, concept art, or 3D asset briefs.
Open skill - /dialogue-systems
Build branching dialogue and narrative — a node/choice graph with conditions, variables, and localization hooks — and choose between authoring tools Ink and Yarn Spinner or a custom data-driven runner. Engine-neutral. Use when the user mentions dialogue system, branching
Open skill - /game-ai
Design NPC and enemy decision-making with finite state machines, behavior trees, steering behaviors, and A* pathfinding — engine-neutral algorithms that pair with the detected engine's navigation API. Use when building enemy AI, an FSM or behavior tree, steering/flocking, or
Open skill - /game-feel
Add "juice" and game feel that makes actions satisfying — screen shake, hit-stop/freeze frames, tweened/eased motion, squash & stretch, knockback, and layered audio-visual feedback — as engine-neutral techniques that pair with the detected engine's tween, particle, and camera
Open skill

