Try it before you use it
Paste this line into your executor and a demo menu opens with every element wired to notifications. You don't have to write anything.
loadstring(game:HttpGet("https://raw.githubusercontent.com/Lilwero20/CookiesLib/main/CookiesDemo.lua"))()| Tab | What you can try |
|---|---|
| Inicio (Home) | Welcome notice, live stats (FPS, ping, players, time), paragraph, copy field and image. |
| Controles (Controls) | Buttons (normal, primary, with confirmation, in columns, disabled), toggles with keys, sliders, text boxes, keybinds and dropdowns. |
| Avanzado (Advanced) | Pill selector, range slider, number fields, progress bar, color picker, alerts and scrolling sections. |
| Avisos (Notices) | The 4 notification types, one that updates itself, dialogs, watermark, keybind list and badges. |
| Personalizar (Customize) | Theme, accent color, title, window size and the demo Key System. |
| Ajustes (Settings) | The library's settings tab: theme, accent, scale, menu key, configs and auto-load. |
The demo menu is in Spanish. The key for the demo Key System is COOKIES-DEMO. RightShift hides or shows the menu and Ctrl+F opens search.
Installation
CookiesLib loads from GitHub in one line. It works in any executor that has loadstring and game:HttpGet:
local Library = loadstring(game:HttpGet("https://raw.githubusercontent.com/Lilwero20/CookiesLib/main/CookiesLib.lua"))()Every other executor function is optional. If one is missing, the library adapts:
| Function | Used for | If it's missing |
|---|---|---|
gethui | Placing the UI in a hidden container | Uses PlayerGui |
writefile, readfile, isfolder, makefolder | Configs, saved state and remembered key | Disabled |
listfiles | Listing configs | The list is empty |
delfile | Deleting configs and the saved key | Deleting is disabled |
setclipboard | Copy fields and links | Shows the text |
request | Opening the Discord invite | Only copies the link |
Quick start
A window with one tab, one section and a toggle with a key. It's the starting point for any hub:
local Library = loadstring(game:HttpGet("https://raw.githubusercontent.com/Lilwero20/CookiesLib/main/CookiesLib.lua"))()
local Window = Library:CreateWindow({
Title = "Cookies Hub",
ToggleKey = Enum.KeyCode.RightShift,
})
local Main = Window:CreateTab("Main", "H")
local Section = Main:CreateSection("Combat")
Section:AddToggle({
Name = "Auto Farm",
Flag = "AutoFarm",
Default = false,
Keybind = "F",
Callback = function(value)
print("Auto Farm:", value)
end,
})
Window:CreateSettingsTab()When you run it:
- 1The intro plays (logo and loading bar; one click skips it) and the window appears.
- 2The floating button with the logo appears. One click opens or closes the window, and it can be dragged.
- 3RightShift shows or hides the window and Ctrl+F opens search.
- 4Next time you run it, the window comes back with the same size, position, tab and theme.
Window
Library:CreateWindow creates the main window. Every option is optional:
local Window = Library:CreateWindow({
Title = "Cookies Hub",
Subtitle = "v1.0",
Logo = "rbxassetid://76143769732706",
Width = 740, Height = 500,
ToggleKey = Enum.KeyCode.RightShift,
ConfigFolder = "CookiesHub",
Intro = { Enabled = true, Duration = 2 },
Notify = { Duration = 4, Position = "TopRight" },
Theme = { Accent = Color3.fromRGB(245, 194, 12) },
})| Option | Default | What it does |
|---|---|---|
Title / Subtitle | "Cookies Hub" / version | Top bar texts |
Logo | Cookies logo | Title and floating button image. false removes it |
Width, Height | 740, 500 | Initial size |
ToggleKey | RightShift | Key to show or hide |
FloatingButton | true | Floating button to open the window (important on mobile) |
Resizable / Draggable | true | Resize from the corner and drag from the top bar |
Searchable | true | Magnifier button and global search |
ShowProfile | true | Card with avatar and name in the sidebar |
RememberLayout | true | Remembers size, position, tab and theme between runs |
ConfigFolder | "CookiesHub" | Folder for configs and saved state |
CompactBelow | 600 | Below this width the sidebar shows icons only |
Intro
The window stays hidden while the intro plays. Configure it with Intro = { ... }: Enabled, Duration (seconds), Skippable, OncePerSession (doesn't repeat when re-running in the same game), Logo and ShowBar.
Methods
Window:Toggle() Window:Show() Window:Hide()
Window:Minimize()
Window:Resize(800, 520)
Window:SetUIScale(1.2)
Window:ResetPosition()
Window:ResetLayout()
Window:SetTitle("New title")
Window:SetSubtitle("Text")
Window:SetToggleKey(Enum.KeyCode.K)
Window:SetFloatingButton(false)
Window:AddTabCategory("Combat")
Window:GetTab("Main")
Window:SelectTab("Main")
Window:Destroy()Stop your loops on unload
When the player presses Unload UI in Settings, OnUnload tells you so you can stop your loops:
local running = true
Window:OnUnload(function() running = false end)
task.spawn(function()
while running do
task.wait(0.1)
end
end)Tabs
Create them with a name and an icon, or with a table of options. The first tab you create opens automatically.
local Main = Window:CreateTab("Main", "H")
local Combat = Window:CreateTab({
Name = "Combat",
Icon = icon("swords"),
IconColor = Color3.fromRGB(245, 194, 12),
Columns = 2,
Badge = "NEW",
})| Option | Default | What it does |
|---|---|---|
Icon | first letter | Lucide icon, asset id or a letter (see Icons) |
IconColor | accent | Icon color while the tab is active |
Columns | 2 | Section columns (1 on narrow screens) |
Badge | nil | Label next to the name, like "NEW" or a number |
Use Window:AddTabCategory("Name") to add a text separator to the sidebar, like General or Automation.
Combat:Select()
Combat:SetName("Fight")
Combat:SetIcon(icon("flame"))
Combat:SetBadge(3)
Combat:SetBadge(nil)
Combat:SetVisible(false)
Combat:ScrollToTop()
Combat:Destroy()Icons
Tabs and sections accept Lucide icons through lucide-roblox. Use size 48; the helper with pcall avoids errors when a name doesn't exist:
local Lucide = loadstring(game:HttpGet(
"https://github.com/latte-soft/lucide-roblox/releases/latest/download/lucide-roblox.luau"
))()
local function icon(name)
local ok, asset = pcall(Lucide.GetAsset, name, 48)
return ok and asset or nil
end
local Home = Window:CreateTab("Home", icon("home"))
local Combat = Window:CreateTab("Combat", icon("swords"))
local Aimbot = Combat:CreateSection({
Name = "Aimbot",
Icon = icon("crosshair"),
})| `Icon` value | Result |
|---|---|
icon("home") | Lucide icon (recommended) |
123456789 | Asset id → rbxassetid://123456789 |
"rbxassetid://123" | Asset id as text |
"H" | Letter inside a box (max. 2 characters) |
nil | Tabs: first letter of the name. Sections: colored dot |
lucide-roblox uses old Lucide names: "home" instead of "house", "line-chart" instead of "chart-line".
Sections
Sections group elements inside a tab. They spread across the columns on their own, or you can choose where each one goes:
Tab:CreateSection({ Name = "Left", Column = "Left" })
Tab:CreateSection({ Name = "Right", Column = "Right" })
Tab:CreateSection({ Name = "Wide", Full = true })
Tab:CreateSection("Name only")They collapse when you click their header. Options and methods:
local Section = Tab:CreateSection({
Name = "Aimbot",
Icon = icon("crosshair"),
Color = Color3.fromRGB(245, 194, 12),
Minimized = true,
Collapsible = true,
MaxHeight = 220,
})
Section:Minimize() Section:Expand() Section:Toggle()
Section:SetTitle("Another name")
Section:OnToggle(function(open) print(open) end)MaxHeight makes the content scroll past that height, and Minimized = true makes it start collapsed.
Several columns inside a section
local Grid = Tab:CreateSection({ Name = "Grid", Columns = 2 })
Grid:AddButton({ Name = "A" })
Grid:AddButton({ Name = "B", Column = 2 })
local left, right = Grid:AddColumns(2)
left:AddButton({ Name = "Left" })
right:AddButton({ Name = "Right" })Elements
Every element is created from a section with Section:AddXxx({ ... }). Elements with a Flag are saved in configs.
| Element | Used for | Saved |
|---|---|---|
AddButton | Running an action | — |
AddToggle | On / off, with an optional key | Yes |
AddSlider | Picking a number by dragging | Yes |
AddRangeSlider | Picking a min – max range | Yes |
AddNumber | Number with − / + buttons | Yes |
AddDropdown | Picking one or more options | Yes |
AddPlayerDropdown | Picking players in the server | Optional |
AddSegmented | Picking between 2–5 options with pills | Yes |
AddKeybind | Assigning a key | Yes |
AddTextBox | Typing text or numbers | Yes |
AddColorPicker | Picking a color | Yes |
AddProgress, AddStat | Showing progress or a value | — |
AddAlert, AddCopyField, AddImage | Notices, copyable text and images | — |
AddLabel, AddParagraph, AddDivider, AddSpacer | Text and layout | — |
Common options and methods
Almost all of them accept Name, Flag, Callback, Description (text under the name and tooltip), Tooltip, Visible and Enabled. They share these methods:
element:Set(value, silent)
element:Get()
element:SetText("New name")
element:SetVisible(true)
element:SetEnabled(false)
element:SetCallback(function(value) end)
element:OnChanged(function(value) end)
element:Destroy()Every Callback runs with task.spawn: an error in your function won't break the UI. :Set(value, true) changes the value without running the callback.
Toggle
iOS-style switch or checkbox (Style = "Checkbox"). With Keybind, a chip with the key shows up in the same row:
local esp = Section:AddToggle({
Name = "ESP",
Description = "Shows players",
Default = false,
Style = "Switch",
Keybind = { Default = "F", Mode = "Toggle", Flag = "ESPKey" },
Flag = "ESP",
Callback = function(on)
print("ESP:", on)
end,
})
esp:Set(true) esp:Toggle() esp:Get()| Key `Mode` | What it does |
|---|---|
Toggle (default) | Each press turns it on or off |
Hold | On only while the key is held |
To change the key, the player clicks the chip and presses another one. Esc cancels and Backspace removes it.
Slider
The number box on the right can be typed into too. Decimals come from Increment (0.25 → 2 decimals). The callback runs while dragging.
local speed = Section:AddSlider({
Name = "Speed",
Min = 16, Max = 100, Increment = 1, Default = 16,
Suffix = " ws",
Flag = "Speed",
Callback = function(v)
local h = game.Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
if h then h.WalkSpeed = v end
end,
})
speed:Set(50) speed:SetRange(0, 200)RangeSlider
Two handles to pick a range. The value is a { min, max } table; if you pass the values backwards they get sorted.
local levels = Section:AddRangeSlider({
Name = "Enemy level",
Min = 1, Max = 100,
Default = { 10, 60 },
Flag = "LevelRange",
Callback = function(v)
print(v[1], v[2])
end,
})
levels:Set({ 20, 80 })Number
Number field with − and +. Holding a button repeats the change. Min and Max are optional.
local amount = Section:AddNumber({
Name = "Amount",
Min = 0, Max = 99, Increment = 1, Default = 5,
Suffix = "x",
Flag = "Amount",
Callback = function(v) end,
})
amount:Set(10)Dropdown
With Multi = true the value is a table. With 7 or more options a search box appears. AllowNull = true lets the player clear the selection by clicking the chosen option.
local target = Section:AddDropdown({
Name = "Target",
Options = { "Head", "Torso", "Legs" },
Default = "Head",
Multi = false,
AllowNull = false,
Flag = "Target",
Callback = function(v) end,
})
target:Set("Torso")
target:Refresh({ "Head", "Arms" }, true)
target:AddOption("Feet") target:RemoveOption("Arms") target:Clear()PlayerDropdown
A dropdown with the server's players that updates itself when someone joins or leaves. The value is the name; GetPlayer() returns the Player object. It isn't saved in configs unless you set Savable = true.
local victim = Section:AddPlayerDropdown({
Name = "Player",
IncludeSelf = false,
Callback = function(name)
print("Picked:", name)
end,
})
local player = victim:GetPlayer()Segmented
Pills with a sliding indicator. Better than a dropdown when there are 2 to 5 options.
local mode = Section:AddSegmented({
Name = "Mode",
Options = { "Safe", "Normal", "Fast" },
Default = "Normal",
Flag = "Mode",
Callback = function(v) end,
})
mode:Set("Fast")Keybind
local aim = Section:AddKeybind({
Name = "Aim key",
Default = Enum.KeyCode.E,
Mode = "Hold",
Flag = "AimKey",
Callback = function(holding) end,
Changed = function(key) end,
})
aim:Set(Enum.KeyCode.Q) aim:SetMode("Toggle")| `Mode` | `Callback` receives |
|---|---|
Press | Nothing; it runs once per press |
Toggle | true / false, alternating on each press |
Hold | true on press and false on release |
Changed runs when the player rebinds the key. Keys don't fire while the player is typing in a text box.
TextBox
With Numeric = true the value is a number. By default the callback runs on Enter or when the box loses focus (CallbackOnBlur).
local msg = Section:AddTextBox({
Name = "Message",
Placeholder = "Type here...",
Default = "",
Numeric = false,
Flag = "Msg",
Callback = function(text) end,
})ColorPicker
Saturation and brightness picker, hue bar, hex box and optional preset colors.
local tint = Section:AddColorPicker({
Name = "ESP color",
Default = Color3.fromRGB(245, 194, 12),
Presets = { Color3.fromRGB(255, 80, 80), Color3.fromRGB(80, 200, 120) },
Flag = "ESPColor",
Callback = function(c) end,
})
tint:SetHex("#FF0000") tint:GetHex()Elements for showing information
Progress
Read-only progress bar. With ShowPercent = false it shows the raw value.
local bar = Section:AddProgress({ Name = "Loading", Min = 0, Max = 100, Default = 40 })
bar:Set(75)Stat
A row with the name on the left and the value on the right: money, level, farm status…
local money = Section:AddStat({ Name = "Money", Value = "$0", Color = Color3.fromRGB(96, 196, 124) })
money:Set("$1500")
money:SetColor(Color3.fromRGB(224, 92, 92))Alert
A highlighted notice. Type can be Info, Success, Warning or Error, and the content accepts RichText.
local warning = Section:AddAlert({
Type = "Warning",
Title = "Careful",
Content = "This option can get you <b>kicked</b>.",
})
warning:Set("New title", "New content")
warning:SetType("Success")CopyField
Text (a link, a code) with a Copy button that puts it on the clipboard.
Section:AddCopyField({
Name = "Discord",
Text = "discord.gg/cookieshub",
Callback = function(text) end,
})Image
Section:AddImage({
Image = 76143769732706,
Height = 120,
ScaleType = Enum.ScaleType.Fit,
Caption = "Text below",
})Label, Paragraph, Divider and Spacer
local info = Section:AddLabel("Info text")
Section:AddLabel({ Text = "Notice with <b>bold</b>", RichText = true, Color = Color3.fromRGB(232, 148, 58) })
local about = Section:AddParagraph({ Title = "Title", Content = "Longer description" })
about:Set("New title", "New content")
Section:AddDivider()
Section:AddDivider("Options")
Section:AddSpacer(8)Flags and configs
An element with a Flag is registered in Library.Flags and goes into configs. You can read or change it from anywhere in your script:
Library:GetFlag("ESP")
Library:SetFlag("ESP", true)
Library:GetObject("ESP")
Window:SaveConfig("my-config")
Window:LoadConfig("my-config")
Window:DeleteConfig("my-config")
Window:GetConfigs()Auto-load
A config marked as auto-load is applied by itself every time the player runs the script:
Window:SetAutoload("my-config")
Window:GetAutoload()
Window:LoadAutoloadConfig()- Configs are JSON files inside
ConfigFolder. LoadConfigruns each element's callback, as if the player had changed it.Progress,Stat,CopyFieldandPlayerDropdownaren't saved.Library.Flagsis global: use uniqueFlagnames if you have several windows.
Create the settings tab at the end of your script so auto-load finds all your flags. If you don't use it, call Window:LoadAutoloadConfig() once the menu is built.
Notifications
Type can be Info, Success, Warning or Error, each with its own icon. Duration = 0 keeps it open. The returned notification can be updated:
Window:Notify({
Title = "Cookies Hub",
Content = "Config <b>loaded</b>",
Type = "Success",
Duration = 4,
})
local download = Window:Notify({ Title = "Downloading...", Content = "0%", Duration = 0 })
for i = 1, 10 do
task.wait(0.3)
download:SetContent(i * 10 .. "%")
end
download:SetTitle("Done")- One click closes it (and runs its
Callback, if it has one). - Hovering pauses the timer.
- Position and limit:
Notify = { Position = "TopRight", Max = 5 }when creating the window.
Dialogs
A modal window to confirm actions. Without Buttons it shows Cancel and Confirm; with Buttons you can add any you like, each with its own Style.
Window:Dialog({
Title = "Teleport?",
Content = "You will go to the final boss.",
Callback = function()
print("confirmed")
end,
})
Window:Dialog({
Title = "Save changes",
Content = "You have unsaved changes.",
Buttons = {
{ Name = "Cancel" },
{ Name = "Discard", Style = "Danger", Callback = function() end },
{ Name = "Save", Style = "Primary", Callback = function() end },
},
})Dismissible = false stops it from closing when clicking outside.
Watermark and keybind list
Floating panels that can be dragged and remember their position. The list shows the toggles' keys and lights up while they're active.
local wm = Window:CreateWatermark({ Text = "Cookies Hub", ShowFPS = true, ShowPing = true, ShowTime = true })
wm:SetText("My Hub") wm:SetVisible(false)
local binds = Window:CreateKeybindList({ Title = "Keybinds", ShowAll = false })
binds:Destroy()Search and tooltips
The magnifier in the top bar (or Ctrl+F) searches tabs, sections and elements. Picking a result opens the tab, expands the section and highlights the element.
Tooltips show up by themselves when a text is cut off, or always when the element has a Tooltip.
Window:OpenSearch("speed")
Window:CloseSearch()
Section:AddToggle({ Name = "Auto Farm", Tooltip = "Farms the nearest mob" })Themes and colors
Themes apply live: the whole interface repaints without being rebuilt. There are 8 built in: Cookies, Mocha, Midnight, Ocean, Matcha, Strawberry, Grape and Graphite.
Library:SetTheme("Midnight")
Library:SetAccent(Color3.fromRGB(170, 120, 255))
Library:SetTheme({ Accent = Color3.fromRGB(255, 80, 80) })
local themes = Library:GetThemes()
local current = Library.CurrentThemeYou can also pick it when creating the window: Library:CreateWindow({ Theme = "Ocean" }).
If the player picks a theme or accent in Settings, their choice is saved and takes priority over the script's theme.
Create your own theme
Library:AddTheme("Lava", {
Background = Color3.fromRGB(20, 10, 8), Panel = Color3.fromRGB(30, 14, 10),
Element = Color3.fromRGB(38, 18, 12), Row = Color3.fromRGB(48, 22, 14),
RowHover = Color3.fromRGB(60, 28, 18), Input = Color3.fromRGB(16, 8, 6),
Stroke = Color3.fromRGB(90, 40, 24), Outline = Color3.fromRGB(10, 5, 4),
Accent = Color3.fromRGB(255, 110, 40),
Text = Color3.fromRGB(250, 236, 228), Muted = Color3.fromRGB(190, 150, 130),
Dim = Color3.fromRGB(130, 100, 86),
Success = Color3.fromRGB(96, 196, 124), Warning = Color3.fromRGB(232, 148, 58),
Error = Color3.fromRGB(224, 92, 92),
})
Library:SetTheme("Lava")The new theme also appears in the Settings picker. Use a different color for each key: if two keys share the same color, the library can't tell which one to repaint when the theme changes.
Global settings
Library:Configure changes the defaults for every window you create afterwards: animations, sizes, notifications, tooltips, intro…
Library:Configure({
Animations = true,
AnimationSpeed = 1,
Window = { Width = 740, Height = 500, Shadow = true, RememberLayout = true, UIScale = 1 },
Tab = { Columns = 2, Padding = 12, Gap = 10, IconSize = 20 },
Section = { Collapsible = true, Minimized = false },
Element = { Height = 32, Corner = 7 },
Notify = { Duration = 4, Position = "BottomRight", Max = 5 },
Tooltip = { Enabled = true, Delay = 0.55 },
Dropdown = { SearchThreshold = 7, MaxVisible = 5 },
Intro = { Enabled = true, Duration = 2, OncePerSession = true },
})Settings tab
Window:CreateSettingsTab() creates a ready-to-use tab:
- Appearance: theme, accent color and UI scale.
- Interface: menu key, floating button, animations, tooltips, watermark, keybind list, Reset Layout and Unload UI.
- Configs: save, load, delete and mark a config as auto-load.
Window:CreateSettingsTab("Settings", icon("settings"))With RememberLayout = true the library saves the size, position, open tab, theme and menu key to ConfigFolder/_ui_state.txt. Window:ResetLayout() deletes it.
Full example
An example hub with icons, live stats, sliders, toggles with keys, dialogs, a sample ESP tab and the settings tab. Copy it and run it as is:
local Library = loadstring(game:HttpGet("https://raw.githubusercontent.com/Lilwero20/CookiesLib/main/CookiesLib.lua"))()
local Lucide = loadstring(game:HttpGet(
"https://github.com/latte-soft/lucide-roblox/releases/latest/download/lucide-roblox.luau"
))()
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local function icon(name)
local ok, asset = pcall(Lucide.GetAsset, name, 48)
return ok and asset or nil
end
local Window = Library:CreateWindow({
Title = "My Hub",
Subtitle = "Demo",
ToggleKey = Enum.KeyCode.RightShift,
Theme = "Cookies",
Notify = { Position = "TopRight" },
})
local running = true
Window:OnUnload(function() running = false end)
Window:AddTabCategory("General")
local Home = Window:CreateTab("Home", icon("home"))
local Info = Home:CreateSection({ Name = "Welcome", Full = true })
Info:AddAlert({ Type = "Info", Title = "My Hub", Content = "Press <b>RightShift</b> to hide the menu." })
local Stats = Home:CreateSection({ Name = "Live", Icon = icon("line-chart"), Column = "Left" })
local sPlayers = Stats:AddStat({ Name = "Players", Value = #Players:GetPlayers() })
local sTime = Stats:AddStat({ Name = "Time", Value = os.date("%H:%M:%S") })
local Links = Home:CreateSection({ Name = "Community", Icon = icon("users"), Column = "Right" })
Links:AddCopyField({ Name = "Discord", Text = "discord.gg/xxxxxx" })
task.spawn(function()
while running do
sPlayers:Set(#Players:GetPlayers())
sTime:Set(os.date("%H:%M:%S"))
task.wait(1)
end
end)
Window:AddTabCategory("Game")
local Player = Window:CreateTab({ Name = "Player", Icon = icon("user"), Badge = "NEW" })
local Move = Player:CreateSection({ Name = "Movement", Icon = icon("footprints"), Column = "Left" })
Move:AddSlider({
Name = "Walk speed", Min = 16, Max = 200, Default = 16, Suffix = " ws", Flag = "WalkSpeed",
Callback = function(v)
local h = LocalPlayer.Character and LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
if h then h.WalkSpeed = v end
end,
})
Move:AddSegmented({ Name = "Mode", Options = { "Safe", "Normal", "Fast" }, Default = "Normal", Flag = "Mode" })
Move:AddToggle({
Name = "Infinite jump", Flag = "InfJump",
Keybind = { Default = "J", Flag = "InfJumpKey" },
Callback = function(on)
Window:Notify({ Title = "Infinite jump", Content = on and "On" or "Off", Type = on and "Success" or "Info" })
end,
})
local Tp = Player:CreateSection({ Name = "Teleport", Icon = icon("map-pin"), Column = "Right" })
local target = Tp:AddPlayerDropdown({ Name = "Target" })
Tp:AddButton({ Name = "Go to target", Primary = true, Callback = function()
local p = target:GetPlayer()
if not p then
return Window:Notify({ Title = "Teleport", Content = "Pick a player first", Type = "Warning" })
end
Window:Dialog({
Title = "Teleport?",
Content = "You will go next to <b>" .. p.DisplayName .. "</b>.",
Callback = function()
local mine = LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart")
local theirs = p.Character and p.Character:FindFirstChild("HumanoidRootPart")
if mine and theirs then mine.CFrame = theirs.CFrame * CFrame.new(0, 0, 3) end
end,
})
end })
Tp:AddButton({ Name = "Reset character", Style = "Danger", Confirm = true, Callback = function()
local h = LocalPlayer.Character and LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
if h then h.Health = 0 end
end })
local Visuals = Window:CreateTab("Visuals", icon("eye"))
local Esp = Visuals:CreateSection({ Name = "ESP", Icon = icon("scan-eye") })
local c1, c2 = Esp:AddColumns(2)
c1:AddToggle({ Name = "Boxes", Style = "Checkbox", Flag = "EspBoxes" })
c2:AddToggle({ Name = "Names", Style = "Checkbox", Flag = "EspNames" })
Esp:AddColorPicker({ Name = "Color", Default = Color3.fromRGB(245, 194, 12), Flag = "EspColor" })
Esp:AddRangeSlider({ Name = "Distance", Min = 0, Max = 5000, Default = { 0, 1000 }, Flag = "EspRange" })
Window:CreateSettingsTab("Settings", icon("settings"))
Window:Notify({ Title = "My Hub", Content = "Loaded", Type = "Success" })Common problems
- I don't see the window when I run it: the intro keeps it hidden for about 2 seconds (one click skips it). With
Intro = { Enabled = false }it appears right away. - The intro doesn't play when I re-run: that's on purpose (
OncePerSession). SetIntro = { OncePerSession = false }to always see it. - I closed the window and can't open it: use the
ToggleKeyor the floating button. On mobile, don't disableFloatingButton. - The window opens somewhere else or with another theme: the library remembers what the player left. Use Reset Layout,
Window:ResetLayout()orRememberLayout = false. - My callback runs when a config loads: that's normal for
LoadConfig. Use:Set(value, true)for silent changes. - My loops keep going after Unload UI: stop them with
Window:OnUnload. - `Lucide.GetAsset` fails: the icon doesn't exist; use the helper with
pcall.