About roblox-ui-hud
A skill for Roblox UI developers building HUDs and panels, with responsive layout guidance, interaction patterns, readability practices, and UI verification notes.
Key features
- 01Responsive sizing across devices
- 02Positioning HUD elements by live height
- 03Panel toggling and outside-click handling
- 04Progress bar and status display guidance
- 05UI verification and layout pitfalls
Use cases
- 01Designing HUDs for phones, tablets, and desktop
- 02Preventing overlap with dynamically sized panels
- 03Ensuring only one panel is open at a time
- 04Checking UI text and visibility state
MCP support
Covers considerations for verifying UI through MCP and points to the roblox-studio-mcp skill for tool and testing details.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ flatbedj/ roblox-skills --skill roblox-ui-hudAfter installing, type/roblox-ui-hudin Claude Code to confirm it loaded.
Details
From the project READMERoblox game UI / HUD patterns
Hand-built HUDs (not auto-scaled templates) that hold up across devices and read clearly.
Responsive layout across devices
UIScale(e.g. afitScalehelper) scales an element's SIZE about its anchor — NOT its position. So scaling alone doesn't reposition; recompute positions per device where it matters. Don't nest two UIScales on one element (parent + child) — it double-scales.- Device gate by MIN dimension, not by
TouchEnabledalone —math.min(vp.X, vp.Y)is orientation-proof: phone short side ≈ ≤430, tablet ≥ ~744. Branch desktop / phone (isMobile and min < 600) / tablet (isMobile and min >= 600) so a rotated tablet isn't treated as a phone. - Anchor stacked HUD elements to LIVE panel heights, not hardcoded pixel offsets. Classic bug: a boost/pill row hardcodes "panel is 104px" but the panel above it GROWS with content (
clamp(base + n*rowH, …)), so they overlap once the panel expands. Read the neighbor's actualAbsoluteSize.Y(or its formula) and position off that. - Leave room for Roblox's own mobile controls: the DynamicThumbstick capture area reaches up to ~0.75·
vp.Yon the bottom-left, and the Jump button sits bottom-right; lift bottom-anchored HUD off the edge enough to clear them WITH and WITHOUT the safe-area inset. Verify on a small phone (iPhone SE) and a large one (Pro Max) — the two worst cases.
ScreenGui panels
- Convention that tests well: one
ScreenGuiper screen/panel,Enabled = false, content pre-built. Toggle.Enabled = trueto open. (For MCP testing, enabling reveals CENTERED panels; SLIDE-IN panels sit off-screen in their closed position, so toggling shows nothing — animate them in instead.) - Only one panel open at a time: a
closeAll()that closes/hides every panel before opening the next. - Click-outside-to-close:
.Active = truedoes NOT reliably sink clicks that fall through a child ScrollingFrame. Bounds-check the backdrop'sInputBegan— close only when the click is OUTSIDE the panel'sAbsolutePosition/AbsoluteSize.
Progress bars / meters (the reusable recipe)
A rounded bg Frame + a fill Frame + a centered text overlay:
fill.Size = UDim2.fromScale(math.clamp(frac, 0, 1), 1) -- fill = fraction of the bar
fill.BackgroundColor3 = good and GREEN or AMBER -- colour conveys status at a glance
text.Text = ("%d / %d · %s"):format(done, total, statusLabel)
⚠️ Boolean-visibility bug (bit me): in Luau, local show = a and b and season.teams returns the last operand (a table), NOT true — so frame.Visible = show errors or show == true is always false. Make the condition a real boolean: end it with a comparison (… and season.teams ~= nil), or wrap it. Reserve the bar's slot even when hidden so the layout doesn't jump.
Layout gotchas (waste hours)
- Horizontal auto-size
UIListLayoutignoresLayoutOrderby default — setSortOrder = Enum.SortOrder.LayoutOrderor chips render in reversed/creation order. UDim2.new(0,0,1,0)(single pair set) trips a selene "use fromScale" warning — useUDim2.fromScale/fromOffset.- Font glyphs: Gotham renders
✕ ↻ ✦as boxes — useX,★,◆,$. Emoji are fine (🍀 👑 ⚡ ⚔️ 🏆) EXCEPT flag emoji (show as 2 letters) — draw flags with frames.
Copy & clarity (small rules, big readability)
- Prefer ICONS/glyphs over jargon words in the HUD — e.g. show currency as its icon, not "Cash/Shards/Gems"; names belong only where the reward is described (shop). Same spirit: avoid internal-system nouns in player-facing text (say the action/outcome, not "level up the X board"; say "team", not "XI").
- Keep it plain-language — read every string as a brand-new player would.
Verifying UI (MCP)
Screenshots can lie for UI — a freecam capture can leave ScreenGuis hidden, and distant SurfaceGui close-ups render blank. Cross-check by walking PlayerGui:GetDescendants() and asserting on .Text / .Visible / ImageLabel.Image / accessory counts. The MCP tools + gotchas (clicking by AbsolutePosition, the cross-VM rule, capture artifacts) are in the roblox-studio-mcp skill; the dev/test loop is in roblox-studio-workflow.