Skip to content
Back to skills

Gohud

ASecurity

Build Godot 4.7+ game UI with gohud (res://addons/gohud; tested on Godot 4.7, officially supports 4.7 and newer): main menus, pause menus, settings screens, inventories, HUDs with HP/MP bars, quick slots and a virtual joystick, dialogs, bottom sheets, forms, snackbars, prompt cards, coach-mark tours, and looks from presets (default, sci-fi, medieval), JSON themes, skins and icon sets — touch-safe, safe-area aware, RTL and translation ready. Use whenever someone writes GDScript UI, HUD, menu o...

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 2, 2026
toolspythongobashnodegitapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 19 files and shows the line behind each finding

Scanned October 2, 2026

npx -y skills add thruthesky/gohud --skill gohud --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Gohud?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Gohud
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/thruthesky-gohud/badge)](https://www.skillsdirectory.com/skills/thruthesky-gohud)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: gohud
description: >-
  Build Godot 4.7+ game UI with gohud (res://addons/gohud; tested on Godot 4.7, officially supports 4.7 and newer): main menus, pause menus, settings screens,
  inventories, HUDs with HP/MP bars, quick slots and a virtual joystick, dialogs, bottom sheets, forms,
  snackbars, prompt cards, coach-mark tours, and looks from presets (default, sci-fi, medieval), JSON
  themes, skins and icon sets — touch-safe, safe-area aware, RTL and translation ready. Use whenever
  someone writes GDScript UI, HUD, menu or GUI code in a Godot project, mentions gohud or any Go* class
  (GoUi, GoStyle, GoSurface, GoSheet, GoDialogs, GoForm, GoHudAnchor, GoBar, GoSlot, GoJoystick, GoNotice,
  GoPromptCard, GoCoachMark, GoTheme, GoSkin, GoIconSet, GoConfig), wants to install gohud, or runs
  /gohud preview, /gohud features (plugin form: /gohud:preview, /gohud:features, /gohud:gohud).
license: MIT
metadata:
  author: JaeHo Song
  homepage: https://thruthesky.github.io/gohud/
  repository: https://github.com/thruthesky/gohud
---

# gohud — game UI for Godot 4.7+

gohud is a pure-GDScript HUD & UI kit, tested on Godot 4.7 and officially supported on Godot 4.7
and newer. Every class is global once the folder sits at `res://addons/gohud/`;
widgets are made with `.new()` + `add_child()` and styled by one theme, one skin and one icon set.
This skill carries the whole API (`references/`), runnable screen templates (`assets/templates/`) and a
preview launcher (`scripts/gohud_preview.py`).

Arguments given: `$ARGUMENTS`

## 1. Route the request

| First word of the arguments | Do |
|---|---|
| `preview` | §6 — launch the preview with the remaining arguments |
| `features` | Read `references/features.md` and present it grouped (one line of code per feature). If an area follows (`features theming`), also read that area's reference and go deeper |
| `update` | Read `references/setup.md` §7 and follow `commands/update.md` — update the add-on in the project **and** this skill, then verify the two agree |
| anything else / empty | §2 — build or change UI with gohud |

Reply in the language the user writes in; keep code identifiers as they are.

## 2. Workflow for building UI

1. **Check the project.** `test -f project.godot`, `test -f addons/gohud/plugin.cfg`, `godot --version` (needs 4.7+).
   Note the gohud version (`version=` in `plugin.cfg`) — rules 4, 5 and 7 differ for 1.0.3 and older.
   Missing add-on → install it (`references/setup.md` §1), then `godot --headless --path . --import`.
2. **Pick the look first.** `GoUi.use_preset(GoThemePresets.SCIFI_DARK)` (or the project setting) before any widget
   is built. Nodes keep the theme they were built with; switching later means rebuilding the screen.
3. **Choose the widget for the job** — table in `references/surfaces.md` §7: blocking question → `GoDialogs`,
   list over the game → `GoSheet`, side panel on a wide screen → `GoDrawer`, window → `GoSurface`,
   full-screen menu/login/settings → root Control + `GoForm`, **message with an Undo button → `GoSnackbar`**,
   fixed notice panel the HUD owns → `GoNotice`, optional question → `GoPromptCard`,
   **info card next to a slot → `GoPopover`**, HUD pieces → `GoHudAnchor`.
   Lists and forms: sortable/selectable rows → `GoTable`, pages → `GoPagination`, searchable picker →
   `GoCombobox`, a field that can show an error → `GoField`, input welded to a button → `GoInputGroup`.
   Waiting → `GoSpinner` (`GoSpinner.busy(button, true)` also blocks the double press).
   A list the player scans (quests, mail, a shop) → rule 15 in §3 and the recipe in `references/recipes.md` §16.
4. **Start from a template** when one fits (§5): copy it into the project (e.g. `res://ui/`), rename, adjust, wire
   its signals. Otherwise compose with `GoStyle` factories (`references/style.md`).
5. **Follow the rules in §3.** Look up exact signatures in the references before using a member you are not sure
   of — do not guess APIs.
6. **Verify without a window:** `python3 ${CLAUDE_SKILL_DIR}/scripts/gohud_preview.py res://ui/my_screen.tscn --check`
   (or `godot --headless --path . --quit-after 120 res://ui/my_screen.tscn` and scan for `SCRIPT ERROR`,
   `Parse Error`, `ERROR: Failed`). Open a visible window only when the user asks to see it (§6).

## 3. Rules that prevent the real bugs

1. **Sizes and colours come from tokens**, never literals: `GoUi.metric(GoTheme.GAP)`, `GoUi.color(GoTheme.MUTED)`,
   `GoStyle.*` factories. Literals break when the preset, breakpoint or touch size changes.
2. **Text vs keys.** `GoStyle.label()/button()` show text as written; `label_key()/button_key()` hold translation
   keys. `list_button()`, `foldable()`, `section()`, `toggle()`, `checkbox()` translate by default — pass
   `translate = false` for literal strings.
3. **Surfaces go in a `CanvasLayer`, and the owner closes them.** `GoSurface` only emits `close_requested`.
   Layers: HUD 5 · `GoSheet` 10 · your popups 50 · `GoDialogs` 100.
4. **Per-page sheet buttons go through `sheet.add_footer(button)`** — the next `open()` removes them. `open()` only
   hides `footer()`, so children added with `footer().add_child()` stay (right for a sheet-wide snackbar, wrong for a
   Close button re-added on every open). gohud 1.0.3 and older have no `add_footer()`: remove your footer children first.
5. **Assemble `GoForm → GoScroll → column` before the form enters the tree.** `_ready` runs inside `add_child`; a
   scroll added later is never found (no keyboard follow), and `%BackButton` (Android Back routing) is looked up once
   there. In code: name the button `BackButton`, add it, set `back.owner = form` and `back.unique_name_in_owner = true`,
   then `add_child(form)`. gohud 1.0.3 and older clear that owner when the scroll moves — there, own the whole branch
   from a holder (`owner = holder` on every descendant; the templates do this, and it works on every version).
6. **HUD root: `mouse_filter = MOUSE_FILTER_IGNORE`.** Transient anchors (toasts, prompts, joystick) use
   `reserve_space = false`; toasts at `TOP_CENTER` use `avoid_peers = true`. Put a `GoStyle.floating()` panel
   behind HUD text that floats over content.
7. **`await` dialogs.** `{placeholders}` in the title and body are filled only from `args` (gohud 1.0.3 and older
   format only the body — build the title string yourself there). Irreversible confirms use `destructive = true`
   (last argument).
8. **Bars use fill tokens** (`GoTheme.DANGER_FILL`, `INFO_FILL`, `WARNING_FILL`, `SUCCESS_FILL`); text colours
   look dull as fills on light themes.
9. **Touch:** icon-only buttons get a tooltip (`GoStyle.icon_button(icon, action, -1, &"Menu")`) — it is also the
   accessible name. Side-by-side `GoIconButton`s / `GoSlot`s need `touch_peers`.
10. **Config:** after changing a plain `GoConfig` field in code call `GoUi.refresh()`; `theme`/`icons` refresh
    themselves. `use_preset()` clears explicit `theme`/`skin`/`icons` — set overrides after it.
11. **Gameplay input pauses while a window is open:** `if GoSurface.is_any_open(): return`.
12. **Widgets that draw text inside a non-container parent must not wrap.** A `Label` with autowrap laid
    out at zero width freezes its minimum height at 1 dp and the text disappears while the panel still
    paints — this is why table cells, key caps and code cells set `AUTOWRAP_OFF`. When you place a child by
    anchors, set `offset_*`, not `position`: `Control.position` is parent-space and ignores the anchors.
13. **Containers are 80% opaque; things you press are not.** Panels (`GoSurface`/`GoSheet`/`GoDialogs`/cards/
    HUD panels/alerts/snackbars) fade their **face only** — never use `modulate.a` for this, it fades the text too.
    Five layers decide the value, most specific first: the `alpha` argument or field at that call →
    `GoConfig.container_alpha_overrides[GoTheme.BOX_*]` → `metric_overrides[<kind>_alpha]` →
    `GoConfig.container_alpha` → theme `GoHud/constants/<kind>_alpha`. 🔑 **Every one of them is a ratio
    `0.0–1.0`** (negative = not set), including `@export` fields such as `dialogs.alpha` and `drawer.alpha` —
    same units everywhere, so there is nothing to memorise per widget. 🛑 The **two exceptions are the theme's
    constants and `metric_overrides`**, which are percent integers (`80`) because a `Theme` constant cannot hold
    a float. Call `GoUi.refresh()` after changing it from code. Read the resolved value with
    `GoUi.surface_alpha(variant)`; apply it to a panel gohud did not build with `GoStyle.fade_panel(node)` (after
    `add_child`). A `GoSkin` subclass overriding `surface_box`/`floating_box`/`alert_box` **must carry the `alpha`
    parameter** or the script will not parse. 🔑 **Drag it before you argue about the number**: the opacity lab
    (`examples/gallery/opacity_lab.gd`) is hosted by the gallery, the guided tour (chapter 16), the home screen
    and the medieval example — it shows the four ways to set the value on one screen, over a pattern, because a
    value check cannot tell you whether the text is still readable. Details: `references/theming.md` §4.
14. **Never hand-edit gohud's generated themes**; recolour through `color_overrides`, a Theme copy in your project,
    a project-local `GoThemePreset`, or the JSON theme tools (`references/theming.md`).
15. **Lists must scan** — a list the player reads (quests, mail, a shop, a roster) is judged by numbers, not taste.
    ① **Space outside a row > space inside it ≥ space between its lines:** rows at least `GAP_SMALL` (8) apart
    (`GAP` 12 when there is room), a two-line row padded 8 above and below and 12 at the sides, its two lines
    `GAP_TINY` (4) apart — `list_button()` already pads its row this way. A cramped panel that used 4 for all three
    ran its rows together. ② **The heading must be a size above the row titles.** Rows are `ROLE_BODY` (16) with a
    `ROLE_CAPTION` (13) second line in `MUTED`; the heading the player reads first is `ROLE_SUBTITLE` (22). A
    `GoSurface` or `GoSheet` short of height (or `compact`) drops **its own** title to `body`, so a list under it
    becomes one size — put that heading in the body instead. ③ Say a thing once: no header line repeating the first
    row. ④ Warning colours and warning icons only on rows where something is wrong; a level gate is a `LOCK` and
    `MUTED` text (never `modulate.a` — rule 13). A badge that repeats on every row carries nothing — drop it; an icon
    that states each row's own state (a lock, a check) may repeat. ⑤ A value at a row's end (`0 / 1`, a price)
    is a label with `SIZE_SHRINK_END` — `GoStyle.label()` expands by default and would split the width with the
    title. `list_button()` has no text slot at the end: build that row yourself and keep its padding and
    `GoStyle.fit_content_height()`. ⑥ Your spacing does not survive everywhere: `GoStyle.form()` (every `GoForm`)
    sets each box's `separation` to `GAP` unless it carries `set_meta(&"go_own_spacing", true)`, and a
    `wrap_row()` forces everything inside it — all the way down — to natural width with wrapping off, so never put a
    card or a row with an expanding title in one. **See it before you build it:** the gallery's List rows section
    opens a lab (`examples/gallery/list_lab.gd`) with a cramped quest panel next to the same panel built by this
    rule, each measured from its own nodes. Recipe: `references/recipes.md` §16.

More traps with their causes: `references/pitfalls.md`.

## 4. Minimal screen

```gdscript
extends Control

var dialogs: GoDialogs

func _ready() -> void:
	GoUi.use_preset(GoThemePresets.DEFAULT_DARK)
	set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
	theme = GoUi.theme()
	RenderingServer.set_default_clear_color(GoUi.color(GoTheme.BACKGROUND))
	var form := GoForm.new()
	var scroll := GoScroll.new()
	var column := GoStyle.column()
	form.add_child(scroll)
	scroll.add_child(column)
	column.add_child(GoStyle.label("Hello gohud", GoTheme.ROLE_TITLE))
	column.add_child(GoStyle.button("Open dialog", _on_open, GoStyle.Tone.PRIMARY))
	add_child(form)
	dialogs = GoDialogs.new()
	add_child(dialogs)

func _on_open() -> void:
	if await dialogs.confirm("Delete save", "This cannot be undone.", "Delete", "", "", {}, true):
		print("deleted")
```

## 5. Templates — `assets/templates/`

Each is a complete, headless-tested script with no scene file. Copy, then connect signals.

| File | Extends | Builds | Public API |
|---|---|---|---|
| `main_menu.gd` | Control | Title, Continue / New game / Settings / Quit rows, confirm dialogs, a Continue button that becomes a spinner | signals `continue_requested` `new_game_requested` `settings_requested` `quit_confirmed` · `build()` · `set_loading(waiting)` |
| `game_hud.gd` | CanvasLayer (5) | HP/MP/XP panel, menu button with an unread badge, 4 quick slots, FOLLOW joystick, toast, prompt card, snackbar | signals `menu_requested` `slot_used(index)` `move_input(vector)` · `set_health/set_mana/set_experience(v, max)` · `toast(msg, tone)` · `await say(msg, actions, tone)` · `set_unread(count)` · `ask(title, subtitle, accept_text, accept, decline_text, decline)` |
| `pause_menu.gd` | CanvasLayer (50) | Centred GoSurface, pauses the tree, Escape opens/closes, a key cap that reads the real binding, quit confirm | signals `resumed` `settings_requested` `quit_to_title_requested` · `open()` `resume()` `toggle()` `is_open()` |
| `inventory_sheet.gd` | Node | GoSheet with search + category filter, long-press menu on each row, detail page with Back, Use / Drop with Undo | signals `item_used(item)` `item_dropped(item)` · `items` · `open()` `show_list()` `show_item(item)` |
| `settings_menu.gd` | Control | GoForm, foldable Display/Audio/Controls/Language sections built from `GoField` (so a row can show its own error), draft + Save/Reset, discard check | signals `closed(saved)` `settings_changed(values)` · `settings` · `save()` `request_back()` `reset_to_defaults()` |

Wiring them together and more screens (login, shop, quest log, character sheet, dropdown menus, tutorial tour):
`references/recipes.md`.

## 6. Preview — `/gohud preview` (plugin: `/gohud:preview`)

Run from the user's project folder so their `addons/gohud` is used (otherwise the bundled copy or a clone):

```bash
python3 ${CLAUDE_SKILL_DIR}/scripts/gohud_preview.py <arguments>      # Windows: python
```

If `${CLAUDE_SKILL_DIR}` is not expanded, use the first existing path of
`${CLAUDE_PLUGIN_ROOT}/skills/gohud/scripts/gohud_preview.py`, `~/.claude/skills/gohud/scripts/gohud_preview.py`,
`.claude/skills/gohud/scripts/gohud_preview.py`.

| Arguments | Opens |
|---|---|
| *(none)* / `gallery` · `--preset scifi_dark` · `--phone` · `--size 1920x1080` | Every widget, preset picker, icon set; **List rows → Readable lists** opens the before/after list lab |
| `medieval` | Character sheet, satchel, quest journal |
| `icons` | Buttons from the 1,000-icon library: toolbar, text + icon, toggles, menu rows, segmented, a group, live search |
| `demo` · `demo --explore hud` | 23-chapter guided tour / one chapter (`list` shows keys) |
| `res://ui/main_menu.tscn` | A scene of the user's project, inside that project |
| `list` · `--check` · `--dry-run` · `--godot PATH` | Keys · headless smoke test · print command · Godot binary |

gohud's examples run in a sandbox project under the user cache, so the user's project is not modified. The script
detaches and prints the process id and log path. Exit 2 = Godot 4.7+ not found or bad arguments; exit 1 = import
or launch error (it prints the error lines). A visible window is what `/gohud preview` is for; for your own checks
use `--check`.

## 7. References — read the one you need

| File | Read when |
|---|---|
| `references/features.md` | `/gohud features`, or "what can gohud do" — catalogue of every feature with one-line code |
| `references/setup.md` | Installing, **updating (§7 — add-on and skill, `/gohud update`)**, enabling the plugin, every `GoConfig` field and default, boot order, layers, project settings, headless verification, gohud's tool commands |
| `references/surfaces.md` | `GoSurface` (placements, anchored menus, sub-pages), `GoSheet`, `GoDialogs` (layouts, destructive, args), `GoForm`, `GoScroll`, subclass hooks, which widget to use |
| `references/hud.md` | `GoHudAnchor` spots and avoidance, `GoBar`, `GoSlot`, `GoJoystick`, `GoIconButton`, `GoNotice`, `GoPromptCard`, `GoCoachMark`, composing a HUD |
| `references/style.md` | Every `GoStyle` factory signature: structure, text, buttons and tones, inputs, select/dropdown/segmented/tabs, cards, chips, tables, styleboxes, helpers |
| `references/theming.md` | Presets and resolution order, all tokens, **container opacity (§4)**, overrides, JSON themes (`new_theme.py`/`make_theme.py`), skins and dials, custom StyleBoxes, project-local presets, contrast |
| `references/platform.md` | Icons — the 84 default names, the game set (187) and the icon library (1,000) with `GoUi.add_icons()`, search and groups, custom icon sets/fonts/folders, localization and RTL, sound and haptics, accessibility, safe area, breakpoints, dp scale, Android Back |
| `references/recipes.md` | Full screens and wiring: game scene with HUD + pause + inventory, login, shop, quest log, a quest list that scans (§16), character sheet, context menu, tutorial, theme switcher |
| `references/pitfalls.md` | Symptoms → cause → fix for layout, text, input, theme and lifecycle traps |

Web (same content, with screenshots): overview https://thruthesky.github.io/gohud/ ·
install https://thruthesky.github.io/gohud/install.html · AI skill https://thruthesky.github.io/gohud/ai.html ·
widgets https://thruthesky.github.io/gohud/widgets.html · theming https://thruthesky.github.io/gohud/theming.html

Files in this skill

  • SKILL.md17.5 KB
  • assets/templates/game_hud.gd8.7 KB
  • assets/templates/inventory_sheet.gd6.5 KB
  • assets/templates/main_menu.gd4.5 KB
  • assets/templates/pause_menu.gd3.4 KB
  • assets/templates/settings_menu.gd8.7 KB
  • commands/features.md1.6 KB
  • commands/preview.md2.5 KB
  • commands/update.md3.8 KB
  • references/features.md15.3 KB
  • references/hud.md23.3 KB
  • references/pitfalls.md19.8 KB
  • references/platform.md21.6 KB
  • references/recipes.md24 KB
  • references/setup.md15.8 KB
  • references/style.md24.5 KB
  • references/surfaces.md21.3 KB
  • references/theming.md20.6 KB
  • scripts/gohud_preview.py16.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…