Skip to main content
Load-time only. Calling ui.* from a callback errors.

Tabs and groups

Elements can be organized into tabs and groups.
These tabs appear inside your script’s page, not in the main menu bar. Members take a dot. Groups lay out across two columns in declaration order. Skip either level and it falls back to something named after your script:
The tab bar hides itself when there is only one tab.

Elements

Every element exists on ui and on every group handle. Every element except TextInput and Hotkey gets a right-click hotkey automatically.

IDs

Saved values and keybinds are matched by tab, group and label, so renaming a label loses them. To keep them across a rename, pass a table with an id instead of a name:
Values saved before you added the id are picked up once by the old label.

Expandable groups

ExpandableGroup adds a checkbox row that expands to show the elements inside it, like the menu’s own expandable rows.
The returned value works two ways: default sets whether the checkbox starts ticked, and defaults to false. Hiding it with SetVisible(false) hides everything inside too. The path of an element inside one includes the row’s label: scripts.<script>.<tab>.<group>.<expandable>.<label>.

Handles

Get and Set take a colon.
At load time, Get() returns the declared default. Restored values are applied after loading. MultiCombo also takes Set(table) with a whole array of booleans.

Labels

handle:SetLabel(text) changes the text shown in the menu. It works on every element except Divider.

Change callbacks

handle:OnChange(fn) calls fn with the new value whenever the element’s value changes. It works on Checkbox, SliderInt, SliderFloat, Combo, MultiCombo, ListBox, ColorPicker and Hotkey. For TextInput, use OnSubmit.
It fires for changes from the menu, hotkeys and config loads, including the restore right after your script loads. Changes made from Lua don’t fire it. Sliders and color pickers fire once, when you let go of the mouse. OnChange returns the handle for chaining. Pass nil to remove the handler. It can be called from callbacks.

Hotkeys

Hotkey is a standalone keybind row.
handle:GetKey() returns the bound virtual-key code, 0 when unbound. handle:SetKey(code) binds a new one. Set(bool) changes the toggle state; in hold mode the key overrides it on the next frame.

Color modes

Script color pickers offer solid, rainbow and pulse. Get() returns two values: the color as it currently shows (animated for rainbow and pulse) and the mode, "solid", "rainbow" or "pulse".
Set takes the mode after the color. Leave it out to keep the current mode.

Next to a checkbox, combo or expandable group

handle:AddColorPicker(r, g, b[, a]) or handle:AddColorPicker(Color(...)) puts a color swatch at the end of a Checkbox, Combo or ExpandableGroup row, like the visuals tab. It returns a ColorPicker handle. At load time only.
Its path is the row’s path plus .color, then .color2, .color3 and .color4.

Per-item colors

handle:AddItemColors([colors]) gives every item of a MultiCombo its own swatch, drawn on the item’s row in the dropdown. At load time only, once per element. It returns an array of ColorPicker handles, 1-based like the item list.
Each one’s path is the multi-combo’s path plus the item’s name: scripts.<script>.<group>.flags.armor.

Folder buttons

handle:AddFolderButton(path[, hint[, root]]) adds a folder icon to a Checkbox, Combo or ExpandableGroup row, like the skybox row in the visuals tab. Clicking it opens path in Explorer, creating the folder first if it is missing. hint shows when you hover the icon. At load time only. Returns the handle for chaining.
path follows the same rules as file paths, except that it may be empty to open the root itself. A bad path raises an error. Nothing happens on click if a file sits where the folder would be.

Lists

ListBox is an always-open scrolling list with one selected row. handle:SetItems(table) replaces the whole list from any callback — that is how you build a list that grows.
SetItems accepts only strings. Selection stays at the same index when possible, clamps when the list shrinks, and becomes -1 when empty.

Text

TextInput is a one-line field. Read it with Get, or take handle:OnSubmit(fn) to be called when the user presses enter or leaves the field.
OnSubmit returns the handle for chaining. Pass nil to remove the handler. It can be called from callbacks.

Showing and hiding

handle:SetVisible(bool) on any handle, including Label and Divider. Siblings reflow, the group shrinks. Call it from a paint callback to drive it off another element:
Elements start visible. Hiding an element does not change its value.

Controls by path

ui.Get and ui.Set read and write controls by path. They work on the cheat’s own controls and on any script’s controls.
Both error if no control matches the path.

Script controls

A script control’s path is scripts.<script>.<tab>.<group>.<label>. The tab is optional. <script> is the file name without .lua. Auto tabs and auto groups use the script’s name, the same as the menu shows.
Values have the same shapes as the handle’s Get and Set, with two exceptions: MultiCombo reads and writes the whole array of booleans, and a ColorPicker returns its saved color rather than the animated one.

Color modes

On a color picker, ui.Get returns two values: the color and its mode. The mode is "solid", "gradient", "rainbow" or "pulse".
ui.Set takes the mode as an optional third argument. Leave it out to keep the current mode. A picker that doesn’t offer the mode you pass falls back to solid. Setting "gradient" keeps the picker’s existing second color.

Buttons

Buttons have no value. Use ui.Click(path) to activate one.
Errors if nothing matches the path, or if the path matches a control that is not a button. The button callback runs on the thread that called ui.Click.