Your first window
Build a real script UI from scratch — sections, controls, callbacks and reading values back.
The installation page got a window on screen. This page builds something you would actually ship, and explains each piece as it goes.
Create the window
Every script starts with one Ember.new call. Everything else hangs off the
window it returns.
local Ember = loadstring(game:HttpGet('https://rbx.lol/ember.lua'))()
local win = Ember.new({
Title = "Bloxburg Helper",
Subtitle = "v2.1",
Icon = "house",
Size = Vector2.new(720, 470),
Keybind = Enum.KeyCode.RightControl,
})Title and Subtitle show in the top-left. Keybind is what hides and shows
the window — it defaults to RightShift. Every option is listed under
Ember.new.
Add sections
A section is a tab in the left rail. Give it a name and an icon name.
local main = win:Section("Main", "house")
local farming = win:Section("Farming", "zap")
local visuals = win:Section("Visuals", "eye")
local config = win:Section("Settings", "settings")The first section you create is the one shown when the window opens.
Put controls on them
Controls are methods on the section. Each takes one table of options.
main:Title({ Text = "MOVEMENT", Icon = "compass" })
main:Toggle({
Text = "Infinite jump",
Description = "Jump again while already in the air.",
Default = false,
Callback = function(on)
infiniteJump = on
end,
})
main:Slider({
Text = "Walk speed",
Min = 16,
Max = 250,
Default = 16,
Suffix = " studs/s",
Callback = function(value)
local char = game.Players.LocalPlayer.Character
if char and char:FindFirstChild("Humanoid") then
char.Humanoid.WalkSpeed = value
end
end,
})Read values back
Every stateful control returns a handle. Keep it if you need to read or change the value later.
local speed = main:Slider({
Text = "Walk speed", Min = 16, Max = 250, Default = 16,
})
print(speed:Get()) --> 16
speed:Set(120) --> moves the knob and fires the callbackThe shape of every control#
Once you have seen one control you have seen all of them. They all take a single table, and they all understand the same handful of options:
| Option | Type | Default | What it does |
|---|---|---|---|
Text | string | — | The label on the left. Every control has one. |
Description | string | — | A smaller second line under the label. Use it instead of a comment nobody reads. |
Icon | string | — | An icon name shown before the label. |
IconColor | Color3 | — | Overrides the icon's colour. Defaults to the theme's. |
IconSize | number | — | Icon size in pixels. |
LayoutOrder | number | — | Forces a position on the page. Rarely needed — order of creation is the default. |
Callback | function | — | Called when the value changes. The argument is the new value. |
Save | string | boolean | — | Persists this control to disk under the given key. See Saving settings. |
Flat | boolean | false | Drops the card surface. Set automatically inside a group. |
Beyond those, each control has its own options — a slider has Min/Max, a
dropdown has Options. They are all on the individual
control pages.
A complete script#
Everything above, plus saving, put together:
local Ember = loadstring(game:HttpGet('https://rbx.lol/ember.lua'))()
local win = Ember.new({
Title = "Bloxburg Helper",
Subtitle = "v2.1",
Icon = "house",
SaveLayout = true,
})
local state = { fly = false, speed = 16 }
local main = win:Section("Main", "house")
main:Title({ Text = "MOVEMENT", Icon = "compass" })
main:Toggle({
Text = "Fly",
Description = "Hold space to rise, shift to drop.",
Save = "fly",
Callback = function(on)
state.fly = on
end,
})
main:Slider({
Text = "Walk speed",
Min = 16, Max = 250, Default = 16,
Suffix = " studs/s",
Save = "speed",
Callback = function(value)
state.speed = value
local char = game.Players.LocalPlayer.Character
local hum = char and char:FindFirstChild("Humanoid")
if hum then hum.WalkSpeed = value end
end,
})
main:Separator()
main:Button({
Text = "Reset character",
ButtonText = "Reset",
ButtonIcon = "refresh-cw",
Danger = true,
Callback = function()
game.Players.LocalPlayer.Character:BreakJoints()
win:Notify({ Title = "Reset", Text = "Character reset.", Icon = "check" })
end,
})
local settings = win:Section("Settings", "settings")
settings:Dropdown({
Text = "Theme",
Options = Ember.ThemeNames(),
Default = "Dark",
Save = "theme",
Callback = function(name) Ember.SetTheme(name) end,
})That script remembers itself
Because three controls have a Save key and the window has SaveLayout = true,
closing and re-running restores the toggle, the slider, the theme, and where the
window was on screen.
Cleaning up#
When your script is done, tear the window down. This disconnects every event, stops every animation and removes the GUI:
win:Destroy()If you need to run your own cleanup at the same time, register it:
win:OnDestroy(function()
myConnection:Disconnect()
end)See Lifecycle and cleanup for the full picture.