Skip to content

UI ​

Add custom widgets to the menu. Tabs and sections are created implicitly: every widget call takes (tab, section, name, ...) as its first three arguments, and the engine creates the tab and section on first reference.

Every widget call returns a ref string. You don't get the value back directly. To read or write a widget's value, use ui.get(ref) and ui.set(ref, value) against the ref. State is persisted between sessions automatically.

Quick example ​

lua
local on        = ui.checkbox("My ESP", "Boxes", "Enabled", true)
local thickness = ui.slider_int("My ESP", "Boxes", "Thickness", 1, 5, 2)
local color     = ui.color_picker("My ESP", "Boxes", "Color")

ui.button("My ESP", "Boxes", "Reset", function()
    print("reset clicked")
end)

function on_tick()
    if not ui.get(on) then return end
    for _, p in ipairs(get_players()) do
        if p:is_enemy() and p:is_alive() then
            local b = p:screen_box()
            if b then
                draw.rect(b.x, b.y, b.x + b.w, b.y + b.h,
                          ui.get(color), ui.get(thickness))
            end
        end
    end
end

The first three arguments ("My ESP", "Boxes", the widget name) determine where the widget appears in the menu. Reuse the same tab+section across calls to group widgets together.

Custom tab labels ​

By default, the tab name you pass to widget calls doubles as both the internal ID (used to group widgets) and the display label shown in the menu's tab bar. If you want them to differ, typically so the on-screen label can have spaces or fancy characters while the ID stays clean for code, declare the tab explicitly with ui.new_tab:

lua
ui.new_tab("toast_demo", "Toast Demo")

ui.button("toast_demo", "styles", "Default", function()
    toast("Hi", 2)
end)
FunctionReturnsDescription
ui.new_tab(id, label)-Register a tab where the internal id (used by every widget call's first argument) differs from the display label shown in the menu. Calling this is optional, if you skip it, the first widget call referencing a tab implicitly creates one with id = label

Widgets ​

FunctionReturnsDescription
ui.checkbox(tab, section, name, [default])refToggle. default is a bool
ui.slider_int(tab, section, name, min, max, [default])refInteger slider
ui.slider_float(tab, section, name, min, max, [default])refFloat slider
ui.dropdown(tab, section, name, options, [default_index])refDropdown. options is an array of strings; selection returned as 1-based index
ui.multiselect(tab, section, name, options)refMulti-select. Returns an array of selected indexes
ui.color_picker(tab, section, name)refColor picker. Stored as ABGR uint32
ui.input_text(tab, section, name, [default])refText input
ui.keybind(tab, section, name, [default_vk])ref"Click to bind" keybind picker. Stored as VK code
ui.font_picker(tab, section, name, [default_font])refFont picker with system font search. Stored as font name string. See Draw > Fonts
ui.button(tab, section, name, callback)refButton. callback runs when pressed
ui.label(tab, section, text)refStatic wrapped text label. Useful for headings, instructions, or status readouts

Each widget also has a ui.new_* alias (ui.new_checkbox, ui.new_slider_int, etc.) for consistency with older script styles. The aliases are identical to the unprefixed versions.

Reading and writing values ​

FunctionReturnsDescription
ui.get(ref)variesCurrent value of the widget. Type depends on the widget
ui.set(ref, value)-Override the widget's current value
ui.set_visibility(ref, bool)-Show or hide the widget
lua
local mode = ui.dropdown("Misc", "General", "Mode", {"Off", "Casual", "Tryhard"}, 1)

function on_tick()
    if ui.get(mode) == 3 then
        -- Tryhard mode
    end
end

-- Set programmatically:
ui.set(mode, 2)

Use ui.set_visibility for conditional UI without re-creating widgets:

lua
local advanced = ui.checkbox("Misc", "General", "Advanced mode")
local detail   = ui.slider_int("Misc", "General", "Detail level", 1, 10, 5)

function on_tick()
    ui.set_visibility(detail, ui.get(advanced))
end

Return value types ​

Widgetui.get returns
checkboxboolean
slider_int, keybindinteger
slider_floatnumber
dropdowninteger (1-based index)
multiselecttable of integers
color_pickerinteger (ABGR uint32)
input_text, font_pickerstring
buttonnothing meaningful (use the callback)
labelnothing meaningful (display-only)

settings vs ui ​

For most scripts, declare config in the settings = { ... } table instead. It's simpler, auto-renders below your script in the menu, and uses the config.* namespace for reading/writing.

Use ui.* when you need:

  • Custom tabs and sections (settings render only inline under the script)
  • Buttons with callbacks
  • Runtime-mutable visibility via ui.set_visibility
  • Widgets created or destroyed during script execution

Both styles can coexist within the same script.

Not affiliated with Valve Corporation.