본문으로 건너뛰기
cccskills
무료GitHub에 공개

scenario-godot-ui

Use when building or fixing game UI in Godot 4.7: main menu, settings screen, HUD (health bar, ammo, minimap frame), Control layout, containers, anchors, themes in code, 'UI scales wrong on phones', 'text too small on 4K', notch or safe area, stretch mode and aspect, gamepad or keyboard menu navigation, focus lost, input rebinding screen, localization (CSV, PO, tr_n plurals, Arabic RTL, CJK fonts, pseudolocalization), screen reader accessibility, UI scale slider, or clicks not reaching the game.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

실행 점수 미검증

설치 방법 보기

포함된 파일(20)

  • SKILL.md21.7 KB
  • references/critique.md4.7 KB
  • references/expert-notes.md8.5 KB
  • references/gui-paths.md8.4 KB
  • references/procedures.md18.0 KB
  • references/sources.md7.9 KB
  • scripts/agentkit/ui/examples/build_g7.gd14.5 KB
  • scripts/agentkit/ui/hud_bar.gd1.5 KB
  • scripts/agentkit/ui/menu_stack.gd3.7 KB
  • scripts/agentkit/ui/safe_area.gd1.5 KB
  • scripts/agentkit/ui/ui_audit.gd6.8 KB
  • scripts/agentkit/ui/ui_capture.gd4.8 KB
  • scripts/agentkit/ui/ui_focus.gd4.4 KB
  • scripts/agentkit/ui/ui_layout.gd10.6 KB
  • scripts/agentkit/ui/ui_rebind.gd8.6 KB
  • scripts/agentkit/ui/ui_selftest.gd1.2 KB
  • scripts/agentkit/ui/ui_settings.gd5.0 KB
  • scripts/agentkit/ui/ui_stretch.gd6.3 KB
  • scripts/agentkit/ui/ui_theme.gd8.8 KB
  • scripts/gd_ui.py9.5 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Godot UI (UI developer)

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. If a sibling skill named here is missing from your available skills, ask the user to install it (npx skills add scenario-labs/skills --skill <name>); unattended, proceed from tool schemas and flag the gap.

REQUIRED BACKGROUND: scenario-godot-expert (channels, review loop, 6.3 traps).

Stance (the expert delta)

  1. Pick the base size for the extremes, not for 1080p. A square base (720x720) with canvas_items + expand and Handheld Orientation sensor gives 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.
  2. 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 use set_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].
  3. 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).
  4. Focus is explicit. Nothing has focus at scene start, so ui_down does nothing until something calls grab_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).
  5. 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).
  6. 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.
  7. 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 after append, 1 after reassigning), so state arrays emit their own signal (NoBSGodot Yuw7CK5H8eA 00:05:06, measured).
  8. Verify at device sizes headless, then look. Headless, root.size takes 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].

Establish first

InputChangesDefault if nobody says
Platforms and orientationsbase size, orientation, touch target sizephone portrait + landscape, desktop to 4K: base 720x720, canvas_items, expand, orientation 6 (sensor)
Art stylestretch mode and scale modevector or high-res: canvas_items + fractional; pixel art: viewport, base 640x360, integer, Exclusive Fullscreen (docs)
Input devicesfocus work, rebind screen, touch sizesmouse, keyboard, pad, touch
Languagesfonts, RTL, Text Server Data on exporten plus one long (de), one CJK (ja), one RTL (ar) for tests
Accessibility barscreen reader, UI scale slider, contrastWCAG 4.5:1 body text, UI scale 0.75 to 2.0 via content_scale_factor
Rendererupscaler choice in settingsForward+ (Jolt kept); Compatibility forces bilinear 3D scaling

Workflow

1. Project settings. Write the stretch keys explicitly: a hand-written project.godot gets disabled and keep (deltas). gd_env.set_project_setting for display/window/size/viewport_width/height, stretch/mode, stretch/aspect, handheld/orientation, gui/theme/custom. Check that 3d/physics_engine="Jolt Physics" and the renderer survived. GATE: gd_ui.stretch_math(window, base, ...) for each target gives the expected logical size and scale (port matches the engine on 224 cases, origin and scale included).

2. Theme in code. ui_theme.gd build(overrides) returns a Theme: Button states with a thick accent focus box, Label, panels, sliders, tabs, ProgressBar, variations TitleLabel, HudLabel, HudValue, PrimaryButton, HudPanel, HealthBar, TrailBar. Save it as .tres, set the default font to a SystemFont with CJK and Arabic fallbacks, two or three fonts at most. Text drawn at many scales (HUD numerals at 3x) gets MSDF: gui/theme/default_font_multichannel_signed_distance_field or the font's multichannel_signed_distance_field, both false by default (Karto 5Hog6a0EYa0 00:20:50, measured). Default Theme Scale is read once: a runtime set changed nothing (measured). In the editor a Theme edit needs a scene reload to repaint (Godotneers 00:22:10) and an override is inactive until its checkbox is ticked (Karto 00:17:25); in code only add_theme_*_override counts, and runtime Theme edits propagate at once (measured). GATE: contrast_report() body pairs >= 4.5:1 (worst measured 4.37 is the disabled state, allowed); check_variations() finds no misspelt variation.

3. Scenes in code. Root Control full rect, a safe_area.gd MarginContainer, then containers. Buttons 88 logical tall at a 720 base (132 px on a phone at 1.5x). Settings rows in ScrollContainers inside a TabContainer. HUD on a CanvasLayer, root MOUSE_FILTER_IGNORE, AspectRatioContainer for the minimap; a round minimap or portrait frame is a clip_children mask (Clip Only on a rounded Panel), but a child with another z_index escapes it (GDQuest W4j4tnQLcTA 00:03:47, measured), so keep masked content at z 0 or use a SubViewport. Toggles read "On"/"Off" as text (CoffeeCrow 9H_fN4OxyIE 00:08:11). safe_area.gd recomputes on size_changed (top margin 104 at 1.5x, 82 at 2x, measured). examples/build_g7.gd builds the whole G7 set. GATE: ui_audit.gd audit_tree() returns no hud_blocks_input, icon_keep_size, grows_offscreen_*, no_accessible_name, shared_stylebox_override, unknown_variation.

4. Layout matrix headless. gd_ui.layout_matrix(P, scene, targets, min_touch_px=..., safe_insets=..., locale=..., pseudo=True) for 8 targets (phone portrait and landscape, 4:3 tablet, 1366x768, 1080p, 21:9, 4K, 800x600). GATE: zero offscreen, outside_safe, small_target, text (clipped or overflowing), overlap and collapsed issues for each scene, in en, de and pseudolocalized at 0.4 expansion.

5. Capture matrix windowed, then look. gd_ui.capture_matrix(P, scene, targets, safe_insets=...) renders each target at its physical size with black bars and red notch bands, and builds a contact sheet. Open the sheet. GATE: image_checks flags none; by eye: selection visible, no clipped glyphs (CJK, Arabic), notch bands over background only, bars and frames intact. Never capture through an embedded Window with content_scale_*: it draws unscaled (P13, measured).

6. Focus and input. gd_ui.focus_walk(P, scene, steps) pushes ui_* actions through push_input and records the focus owner; ui_focus.graph() lists unreachable focusables. Menu stack: open, cancel, focus back on the opener. GATE: every focusable reachable from the default; first key press from no focus lands on the default; covered panels unreachable.

7. Rebinding. ui_rebind.gd: accept (no echo, no Escape, sticks over 0.5), normalize (physical keycode, device -1, axis sign), report conflicts, swap or refuse, save as ConfigFile, reset from project settings. Show the key with DisplayServer.keyboard_get_label_from_physical() (windowed only): on a French layout physical Q reads "A" (measured). Add pad buttons yourself: in 4.7.2 ui_accept and ui_cancel hold keys only (Enter, Kp Enter, Space; Escape), so add Joypad Button 0 and 1 (Mostly Mad ecJZipjUj6k 00:12:00, measured). GATE: binding matches on keyboard and on any pad after a save and load round trip.

8. Localization. CSV with a ?plural column, gd_ui.check_csv offline, --import, then gd_ui.register_translations. Run en, fr, de, ja, ar and pseudolocalization; expansion_ratio defaults to 0.0, so set 0.3 to 0.4 and call reload_pseudolocalization() (measured). --language fr is the non-persistent test. Animated text is a RichTextEffect: bbcode var plus _process_custom_fx(char_fx), options from char_fx.env (Cashew OldDew KMqYeRae6rM 00:14:01; measured [lift px=6] read 6.0), installed with install_effect(). GATE: no missing keys per locale; Arabic mirrors (anchors and HBox order); plurals right in en and fr; layout matrix clean.

9. Settings and cost. ui_settings.gd autoload applies window mode, vsync, render scale and upscaler, quality, UI scale, bus volumes, locale; saves and reloads. GATE: save and load round trip; ui_scale 1.5 turns a 1280x720 canvas into 853x480.

Numbers

ValueRelative toSource
Base 720x720, canvas_items, expand, orientation sensorphone portrait and landscape plus desktopdocs, Multiple resolutions
Scale 1.5 on 1080x2400 and 2400x1080, 3.0 on 3840x2160, 1.0672 on 1366x768base 720x720measured [added]
Base 720x1280 on a 2400x1080 phone: expand 2844x1280 at 0.844x (UI shrinks), keep_width 897 px side bars; keep_height on 1080x2400: 240 px barswhy a square base beats an aspect choicemeasured [added]
Pixel art 640x360 viewport integer; viewport at fractional 1.0672 (1366x768) resamples and blurs text720p to 4Kdocs, measured
Default Theme Scale 2.0 to 3.0 for a 4K base, 1.5 to 2.0 mobile 1080p base; read once (runtime set: no change)base sizedocs, measured
Touch target 126 px phone, 96 px tablet (48 dp at about 420 and 320 dpi)physical pixels[added]
Button 88 logical at base 720132 px on a phone[added, measured]
WCAG 4.5:1 body, 3:1 large texttext vs its backgroundWCAG 2 [added]
Damage trail: one-shot timer 0.4 s, restarted per hit; heal instanthealth changeDashNothing f90ieBOoIYQ 00:01:26
Text Server Data ~4 MBexport size, for no-space scriptsdocs
200 labels: 1.1 to 1.5 ms new text every frame, 0.17 to 0.23 ms for 10 per frame, under 0.1 ms same text (as idle)CPU per frame, headless M5 Maxmeasured [added]

Quality gates

Measurable: test_ui_live.py U1 to U15 green (compile, stretch parity, CSV, layout matrix, capture, focus, rebind, HUD, localization, engine facts, theme and settings, cost, embedded Window, round-2 layout and theme facts, clip mask and text effect); zero issues in the layout matrix for each scene and locale; audit clean; contrast >= 4.5:1 on body pairs; save and load round trips. Visual: one contact sheet per scene and locale (menu, HUD, settings ja, menu ar, settings pseudo), opened: focus visible, glyphs complete, nothing under the notch, letterbox where expected, selection still visible in grayscale (Rawb Herb).

Common mistakes

MistakeWhat it looks likeFix
1920x1080 or 1152x648 base for a phone gametiny buttons in portrait (scale 0.9375 at 1080x2400)square base 720x720 + expand
Stretch keys left out of an agent-written project.godotUI fixed size, black space on 4Kwrite mode and aspect explicitly
Full-rect Control with default STOP filter over the gameclicks never reach _unhandled_input (0 of 1)MOUSE_FILTER_IGNORE on HUD roots and wrappers
Corner preset without grow directionscore text runs off the right edgegrow_horizontal = GROW_DIRECTION_BEGIN
No grab_focus() on openpad does nothingmenu stack grabs the default on the first nav event
TextureRect left on KEEP_SIZE in a containera 512 px icon makes a 64 px row 614x512; IGNORE_SIZE with no minimum collapses to width 0EXPAND_FIT_WIDTH_PROPORTIONAL (64x64 measured) or ignore size + min size, Stretch Keep Aspect Centered (Godotneers 1_OFJLyqlXI 00:10:28)
OptionButton items as literal EnglishJapanese screen shows "Windowed"items as keys (OPT_WINDOWED)
Tabs left at theme defaulttabs too small to touchtab styleboxes with content margins; the matrix checks the TabBar
Stored binding with device 0 from a synthesized eventpad 2 or the real keyboard (device 16) do not triggernormalize to device -1
Pseudolocalization on, expansion untouched or no reloadno padding (default ratio 0.0)set expansion_ratio, TranslationServer.reload_pseudolocalization()
POT generation trusted for custom nodes in old tutorialsstrings missing (4.2 bug)fixed in 4.3 (Cashew OldDew v0tJPsNNOM8 00:08:00, not rerun); CSV keys avoid POT
Locale Test set in project settingsships in Frenchclear it; use --language fr
Hiding a container child with visible = false for an effectsiblings jump (relayout)modulate.a = 0 or offset_transform_scale (MrElipteach pK2vI2-jCH4 00:02:54)
Expecting a focus ring after a mouse clickring only on the next key or pad pressby design: gui/common/show_focus_state_on_pointer_event 1 (text inputs only)

Handoffs

  • In: state autoloads and signals (scenario-godot-architecture), input actions and values (scenario-godot-gameplay), bus names Master, Music, SFX (scenario-godot-audio), icons, panels, fonts (scenario-* skills; nine-patch margins set in code).
  • Out: render scale and upscaler contract (scenario-godot-rendering-lighting); Text Server Data, real-device safe area and touch (scenario-godot-performance-export); intro and outro tracks, offset_transform motion (scenario-godot-animation); test_ui_live.py for CI (scenario-godot-pipeline-automation).

Godot 4.7 notes

  • offset_transform_* (4.7) moves container children without relayout; offset_transform_visual_only defaults to true, so clicks hit the layout rect (measured). pivot_offset_ratio (4.7) for center pivots; grab_focus(hide_focus) (4.6).
  • AccessibilityServer (4.7), accessibility_name, FOCUS_ACCESSIBILITY (RichTextLabel default); accessibility_support 0 Auto runs only with an assistive app active.
  • auto_translate_mode replaced auto_translate; FoldableContainer (4.5), VirtualJoystick, PopupMenu.allow_search (4.7); [img] takes width_unit/height_unit. Upscalers: FSR2=2, MetalFX spatial=3, temporal=4.
  • push_input(event, true) takes logical coordinates. Godot 3 names (rect_size, add_color_override, margin_*, stretch 2d, process_custom_fx) are gone.

References

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Handle review comments received on GitHub for the current branch's PR or a given PR number or URL, by triaging each unresolved thread, fixing what is warranted, pushing, and replying in each thread, when asked to address, fix or answer PR comments. Works in any Scenario repository.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

scenario-labs/skills1.1천2026년 10월 24일 업데이트

Generate one short Conventional Commits squash message describing only the net diff between the PR's base and head, set its header as the PR title, validate it with the repository's commitlint and both copy its description to the clipboard and display it, when asked for a squash message. Works in any Scenario repository, whatever its default branch.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

scenario-labs/skills1.1천2026년 10월 24일 업데이트

Refresh the current pull request description from its net changes, following the repository's PR template, when asked to update or write the PR summary. Works in any Scenario repository, whatever its default branch.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

scenario-labs/skills1.1천2026년 10월 24일 업데이트

scenario

무료

Use when connecting an AI agent to Scenario (scenario.com) through MCP, or when a task involves generating images, video, 3D, audio, sprites, textures, or game assets. Also when picking a Scenario model, running a LoRA, refining a generation prompt, uploading reference images, waiting on generation jobs, checking credits or quota, hitting Scenario auth, scope, or Forbidden errors, or setting up mcp.scenario.com in Claude Code, Cursor, VSCode, or another agent.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

scenario-labs/skills1.1천2026년 10월 24일 업데이트

Use when generating or handling 3D assets through the Scenario MCP server, including text-to-3D or image-to-3D meshes, GPT-6 Astra 3D or Claude Opus 5.5 3D, GLB, FBX, OBJ, STL, or VOX files, PBR-textured or game-ready models, voxel models, multi-view reconstruction, editing a mesh by prompt, retexture, remesh, UV unwrap, auto-rigging a biped or quadruped, or retargeting an animation, previewing a mesh in the 3D viewer, or downloading a model for import into Unity, Unreal, Godot, or Blender.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

scenario-labs/skills1.1천2026년 10월 24일 업데이트

Use when generating navigable 3D worlds or Gaussian splat scenes on Scenario via MCP: text-to-world, image-to-world, a 360 panorama or skybox turned into a walkable splat, multi-view photos or a video walkthrough reconstructed as a splat, or one object photo to splat. Keywords: World Labs Marble 1.1, 1.1 Plus, 1.0 Draft, Hunyuan World, HY World, image-to-skybox, skybox-to-splat, multiview-to-splat, TripoSplat, gaussian splatting, 3DGS, spz, world generation, explorable scene, VR.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

scenario-labs/skills1.1천2026년 10월 24일 업데이트

scenario-labs의 스킬 모두 보기

이 스킬의 문제 신고