mcpField
R
roblox-ui-hud

roblox-ui-hud

github.com/flatbedjDesign & UI060 installsUpdated 6w ago
Repository

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

  1. 01Responsive sizing across devices
  2. 02Positioning HUD elements by live height
  3. 03Panel toggling and outside-click handling
  4. 04Progress bar and status display guidance
  5. 05UI verification and layout pitfalls

Use cases

  1. 01Designing HUDs for phones, tablets, and desktop
  2. 02Preventing overlap with dynamically sized panels
  3. 03Ensuring only one panel is open at a time
  4. 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-hud

After installing, type/roblox-ui-hudin Claude Code to confirm it loaded.

Details

From the project README

Roblox 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. a fitScale helper) 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 TouchEnabled alone — 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 actual AbsoluteSize.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.Y on 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 ScreenGui per screen/panel, Enabled = false, content pre-built. Toggle .Enabled = true to 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 = true does NOT reliably sink clicks that fall through a child ScrollingFrame. Bounds-check the backdrop's InputBegan — close only when the click is OUTSIDE the panel's AbsolutePosition/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 UIListLayout ignores LayoutOrder by default — set SortOrder = Enum.SortOrder.LayoutOrder or chips render in reversed/creation order.
  • UDim2.new(0,0,1,0) (single pair set) trips a selene "use fromScale" warning — use UDim2.fromScale/fromOffset.
  • Font glyphs: Gotham renders ✕ ↻ ✦ as boxes — use X, ★, ◆, $. 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.

Comments

Markdown supported