Skip to main content
Glama

User interface

ui

Build game HUDs, menus, dialogs, and inventories from Godot Control nodes. Create themes and inspect layout issues.

Instructions

Build game UIs (HUDs, menus, dialogs, inventories) from Control nodes. 'build' creates a whole UI tree in one undoable call with anchor presets, size flags, text and theme overrides; 'menu_template' makes a ready main menu; 'theme' creates project-wide Theme resources with StyleBoxFlat styles; 'inspect' explains why a layout looks wrong. Put in-game HUDs under a CanvasLayer so they don't move with the camera.

Actions:

  • build: {spec: {type, name?, layout?, props?, text?, theme_overrides?, children: [...]} | [specs], parent?='.', scene?} build a UI subtree. layout = anchor preset: full_rect|center|top_left|top_right|bottom_left|bottom_right|top_wide|bottom_wide|left_wide|right_wide|center_top|center_bottom|center_left|center_right|hcenter_wide|vcenter_wide (+ layout_margin, resize: minsize|keep_size); only for nodes NOT inside a Container. Shortcuts per node: text, min_size [w,h], size_flags 'expand_fill'|'shrink_center' (one value = both axes)|{h,v}|[h,v], align/valign (left|center|right, begin|end for boxes), font_size, font_color, color (ColorRect color, Panel background, else text color), separation, margin (MarginContainer: n or [l,t,r,b]), panel/stylebox (StyleBox spec), texture, icon, placeholder, tooltip, unique (%Name access), groups, script, theme (res://theme.tres). Any other key is set as a property (value, max_value, columns, autowrap_mode: 'word_smart'... enum names are matched loosely) or a theme item. theme_overrides: {font_size, font_color, outline_size, separation, colors:{}, constants:{}, font_sizes:{}, fonts:{}, styles:{panel|normal|hover|pressed|fill|background: {bg_color, corner_radius, border_width, border_color, content_margin, shadow_size...}}}. Children given as plain strings become Labels. Returns every created node path (buttons flagged with their 'pressed' signal) and layout warnings. A zero-size Control scene root is stretched to full_rect automatically.

  • menu_template: {title?, subtitle?, buttons?=['Play','Options','Quit'], parent?='.', name?='MainMenu', background?: color | res://image, button_size?=[260,56], font_size?=24, title_size?=56, title_color?, spacing?=16, button_style?: {bg_color, corner_radius, ...} (hover/pressed derived) or {normal, hover, pressed}, theme?} centered main menu: full-rect Control > Background > CenterContainer > VBox(Title, Subtitle, Buttons); in an empty scene whose root is a plain Control (no name/theme given) it is built directly into the root. Buttons get unique names (%PlayButton), shared StyleBoxes and wrap-around focus neighbors. Returns {buttons: {label: path}} to connect 'pressed' signals.

  • layout: {path | paths, preset?, margin?=0, resize?: minsize|keep_width|keep_height|keep_size, size_flags?: 'expand_fill' (both axes) | {h, v} | [h, v], min_size?: [w,h]} apply an anchor preset like the editor's layout toolbar (undoable). Presets don't apply inside Containers: use size_flags/min_size there.

  • theme_override: {path | paths, overrides: {font_size: 32, font_color: '#ffd166', outline_size: 4, font_outline_color: 'black', separation: 8, styles: {panel: {bg_color: '#1d2330', corner_radius: 12}}, fonts: {font: 'res://f.ttf'}}} set per-node theme overrides; a null value removes one. Flat keys are matched to the node's theme items; unknown item names are rejected with the valid list.

  • theme: {path: res://ui/theme.tres, props: {default_font_size?, default_font?: res://font.ttf, colors?: {Button: {font_color: '#fff', font_hover_color: ...}}, constants?: {VBoxContainer: {separation: 12}}, font_sizes?: {Label: {font_size: 20}}, fonts?, icons?, styles?: {Button: {normal: {bg_color, corner_radius, content_margin: [16,8]}, hover: {bg_color}, pressed: {...}, focus: 'empty'}, Panel: {panel: {...}}}, type_variations?: {TitleLabel: 'Label'}}, replace?, assign_to?: node path | 'project'} create or extend a Theme. Type names must be Control classes or declared in type_variations first; item names are checked against what the class uses. Style states other than 'normal' inherit the normal dict, so hover only needs what changes. assign_to 'project' makes it the game-wide default (gui/theme/custom); a node path assigns it to that Control and its children. Use theme_type_variation on nodes to use a variation.

  • font: {path: res://fonts/x.ttf|.otf|.woff2, size?, assign_to?: node path | res://theme.tres | 'project', variation?: {embolden, slant, spacing, spacing_top, baseline_offset, opentype}, save_as?: res://fonts/bold.tres} load a font (imported as FontFile; a file just copied into the project is imported first), optionally as a FontVariation (saved with save_as), and assign it as a node override (+font_size), a theme's default_font or the project default font.

  • focus: {chain: [paths], axis?='vertical'|'horizontal', wrap?=true, mode?: all|click|none} link controls for keyboard/gamepad navigation in order; or {path, neighbors: {left, right, top, bottom, next, previous: path}, mode?} set individual neighbors. Call grab_focus() on the first one in _ready().

  • inspect: {path} layout debugging: rect, global rect, anchors/offsets, detected preset, size flags, min size, what positions it (container vs anchors), parent size, overrides, children rects and warnings (zero-size parents, overlays blocking clicks, collapsed wrapped labels...).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
axisNofocus chain direction: vertical (default) or horizontal.
modeNofocus mode: all, click or none.
nameNoRoot node name for menu_template.
pathNoControl node path (or res:// path for theme/font).
sizeNoFont size to apply with assign_to.
specNoUI tree spec {type, name?, layout?, text?, props?, theme_overrides?, children?} or an array of them.
wrapNofocus chain wraps from last to first (default true).
chainNoControl paths to link for focus navigation, in order.
pathsNoSeveral node paths.
propsNoTheme contents for 'theme' (default_font_size, colors, styles, ...).
sceneNores:// scene to operate on; opened in the editor if needed. Defaults to the currently edited scene.
themeNores:// Theme to apply to the built menu.
titleNomenu_template title (default: project name).
actionYesWhat to do. See the tool description for each action's parameters.
marginNoMargin in pixels for the anchor preset.
parentNoParent node path for build/menu_template (default '.').
presetNoAnchor preset name, e.g. full_rect, center, bottom_wide.
resizeNoPreset resize mode: minsize (default), keep_width, keep_height, keep_size.
buttonsNomenu_template button labels.
replaceNotheme: start from an empty Theme instead of editing the existing file.
save_asNores:// .tres path to save a FontVariation.
spacingNomenu_template space between buttons (default 16).
min_sizeNo[width, height] custom minimum size.
subtitleNomenu_template subtitle.
assign_toNoNode path, 'project', or res://theme.tres (font) to assign the theme/font to.
font_sizeNomenu_template button font size (default 24).
neighborsNo{left, right, top, bottom, next, previous}: node paths.
overridesNoTheme overrides {item: value} or grouped {colors, constants, font_sizes, fonts, styles, icons}.
title_gapNomenu_template space between title and buttons (default 24).
variationNoFontVariation settings: embolden, slant, spacing, ...
backgroundNomenu_template background color '#101522' or res:// image.
size_flagsNo'expand_fill', 'shrink_center', ['expand','fill'] or {h, v}.
title_sizeNomenu_template title font size (default 56).
button_sizeNomenu_template button [width, height] (default [260, 56]).
title_colorNomenu_template title color, e.g. '#ffd166'.
button_styleNomenu_template button StyleBox spec.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, destructiveHint=false, and openWorldHint=false, but the description adds substantial behavioral detail beyond that: calls are 'undoable', returns include created node paths with 'pressed' signals and layout warnings, 'null value removes' a theme override, unknown theme item names are rejected with the valid list, and zero-size Control scene roots are auto-stretched. No annotation contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but appropriately structured for an 8-action, 36-parameter tool: a front-loaded summary paragraph followed by a detailed action list. Most sentences carry unique information, though some parameter-level detail overlaps with the 100% schema coverage, making it slightly less tight than ideal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (8 actions, 36 params, nested objects, no output schema), the description is complete: it covers all actions, return formats, edge cases (Containers vs anchors, empty scene root behavior, theme variations, font import), and error handling. An agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds rich semantics far beyond the schema: it documents the nested spec object, lists all layout anchor presets, explains per-node shortcuts (text, min_size, size_flags, align/valign, font_size, etc.), details theme_overrides structure, and describes action-specific parameters like button_style inheritance and font import behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ('Build game UIs... from Control nodes') and then enumerates eight concrete actions (build, menu_template, theme, font, focus, inspect, etc.), each with a clear purpose. This distinguishes it from generic node/scene siblings by focusing on Control-node UI construction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear action-level usage (e.g., 'build creates a whole UI tree', 'inspect explains why a layout looks wrong') and a contextual tip ('Put in-game HUDs under a CanvasLayer so they don't move with the camera'). It does not, however, name alternative sibling tools (e.g., when to use this instead of node or scene) or explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.