Use when building Roblox user interfaces - ScreenGui, Frame, TextLabel, TextButton, ImageLabel, UIListLayout, tweening, feedback effects, HUD design, shop UI, or any StarterGui work. Triggers on GUI, ScreenGui, Frame, UDim2, AnchorPoint, UICorner, TweenService, or layout mentions.
Build polished, responsive Roblox interfaces using native GUI components. Focus on clarity, feedback, and mobile-friendly layouts.
Core principle: Every action needs feedback. Players should never wonder "did that work?"
Use for:
Skip for: Game logic (use roblox-studio-expert), design decisions (use roblox-game-designer)
StarterGui/
├── HUD/ -- Always visible during gameplay
│ ├── ScoreDisplay
│ ├── XPBar
│ ├── StreakCounter
│ └── ChallengeTracker
├── ShopGui/ -- Modal overlay
│ ├── Background
│ ├── ItemGrid
│ └── CloseButton
├── ResultsGui/ -- End-of-round modal
└── DailyRewardGui/ -- Popup modal
| Type | Use | Behavior |
|---|---|---|
| ScreenGui | 2D overlays | Always renders on screen |
| SurfaceGui | 3D surfaces | Renders on parts |
| BillboardGui | 3D floating | Always faces camera |
local screenGui = Instance.new("ScreenGui")
screenGui.ResetOnSpawn = false -- Persist across respawns
screenGui.IgnoreGuiInset = true -- Use full screen (ignore topbar)
screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling -- Predictable layering
screenGui.DisplayOrder = 1 -- Higher = renders on top
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0.3, 0, 0.4, 0) -- 30% width, 40% height
frame.Position = UDim2.new(0.5, 0, 0.5, 0) -- Center of screen
frame.AnchorPoint = Vector2.new(0.5, 0.5) -- Anchor at center
frame.BackgroundColor3 = Color3.fromRGB(30, 30, 40)
frame.BorderSizePixel = 0
UDim2.new(ScaleX, OffsetX, ScaleY, OffsetY)
-- Examples:
UDim2.new(1, 0, 0, 50) -- Full width, 50px height
UDim2.new(0.5, -100, 0.5, 0) -- 50% + adjustment
UDim2.fromScale(0.5, 0.5) -- Shorthand for scale-only
UDim2.fromOffset(200, 100) -- Shorthand for pixel-only
-- AnchorPoint determines what part of the element Position refers to
frame.AnchorPoint = Vector2.new(0, 0) -- Top-left (default)
frame.AnchorPoint = Vector2.new(0.5, 0.5) -- Center
frame.AnchorPoint = Vector2.new(1, 1) -- Bottom-right
-- Common pattern: Center an element
frame.Position = UDim2.fromScale(0.5, 0.5)
frame.AnchorPoint = Vector2.new(0.5, 0.5)
local label = Instance.new("TextLabel")
label.Text = "Score: 0"
label.Font = Enum.Font.GothamBold
label.TextSize = 24
label.TextColor3 = Color3.new(1, 1, 1)
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextYAlignment = Enum.TextYAlignment.Center
label.BackgroundTransparency = 1 -- No background
label.TextScaled = false -- Fixed size (prefer over TextScaled)
local button = Instance.new("TextButton")
button.Text = "Play"
button.Font = Enum.Font.GothamBold
button.TextSize = 20
button.TextColor3 = Color3.new(1, 1, 1)
button.BackgroundColor3 = Color3.fromRGB(0, 170, 127)
button.AutoButtonColor = true -- Built-in hover/press states
button.Activated:Connect(function()
-- Activated fires for clicks AND touch
print("Button pressed!")
end)
local image = Instance.new("ImageLabel")
image.Image = "rbxassetid://123456789" -- Asset ID
image.ScaleType = Enum.ScaleType.Fit -- Fit, Crop, Stretch, Tile
image.BackgroundTransparency = 1
local layout = Instance.new("UIListLayout")
layout.FillDirection = Enum.FillDirection.Vertical
layout.HorizontalAlignment = Enum.HorizontalAlignment.Center
layout.VerticalAlignment = Enum.VerticalAlignment.Top
layout.Padding = UDim.new(0, 10) -- 10px between items
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Parent = containerFrame
-- Children are sorted by LayoutOrder property
child1.LayoutOrder = 1
child2.LayoutOrder = 2
local grid = Instance.new("UIGridLayout")
grid.CellSize = UDim2.fromOffset(100, 100) -- Each cell 100x100px
grid.CellPadding = UDim2.fromOffset(10, 10)
grid.FillDirection = Enum.FillDirection.Horizontal
grid.FillDirectionMaxCells = 4 -- Max 4 per row
grid.Parent = containerFrame
-- Keep element square regardless of parent size
local aspect = Instance.new("UIAspectRatioConstraint")
aspect.AspectRatio = 1 -- Width:Height ratio
aspect.AspectType = Enum.AspectType.FitWithinMaxSize
aspect.Parent = frame
local padding = Instance.new("UIPadding")
padding.PaddingTop = UDim.new(0, 20)
padding.PaddingBottom = UDim.new(0, 20)
padding.PaddingLeft = UDim.new(0, 20)
padding.PaddingRight = UDim.new(0, 20)
padding.Parent = frame
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 8) -- 8px radius
corner.Parent = frame
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.new(1, 1, 1)
stroke.Thickness = 2
stroke.Transparency = 0.5
stroke.Parent = frame
local gradient = Instance.new("UIGradient")
gradient.Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, Color3.fromRGB(50, 50, 80)),
ColorSequenceKeypoint.new(1, Color3.fromRGB(30, 30, 50))
})
gradient.Rotation = 90 -- Vertical gradient
gradient.Parent = frame
local TweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(
0.3, -- Duration
Enum.EasingStyle.Quad, -- Easing style
Enum.EasingDirection.Out, -- Easing direction
0, -- Repeat count (0 = no repeat)
false, -- Reverses
0 -- Delay
)
local tween = TweenService:Create(frame, tweenInfo, {
Position = UDim2.fromScale(0.5, 0.4),
BackgroundTransparency = 0
})