Skip to content

Script Settings ​

Two ways to add user-configurable options to your script:

  1. settings = { ... } declaration (recommended for most scripts): declarative table at script load time. Auto-renders inline under your script in the menu, auto-persists to a per-script JSON config, auto-restores on next launch.
  2. ui.* widget API (for advanced or dynamic UIs): imperative widget creation with custom tabs, buttons with callbacks, and runtime-mutable layouts. See UI.

Neither is deprecated. Use settings for simple scripts where users just need a few toggles and sliders. Use ui.* when you need dynamic widgets, custom tabs, or button callbacks.

settings declaration ​

lua
name = "My Script"
id = hero_id.any

settings = {
    { key = "enabled", type = "bool",  default = true,  label = "Enabled" },
    { key = "speed",   type = "float", default = 1.0,   min = 0.1, max = 10.0, label = "Speed" },
    { key = "count",   type = "int",   default = 5,     min = 1,   max = 20,   label = "Count" },
    { key = "mode",    type = "combo", default = 0,     label = "Mode",
      options = { "Off", "Conservative", "Aggressive" } },
    { key = "hotkey",  type = "keybind",   default = 0, label = "Hotkey" },
    { key = "slot",    type = "item_slot", default = 0, label = "Item Slot" },
    { key = "font",    type = "font",      default = "", label = "Draw Font" },
    { key = "tint",    type = "color",     default = {r=255, g=80, b=80, a=255}, label = "Tint" },
}

Each entry is a table with these keys:

KeyRequiredDescription
keyyesConfig key for persistence. Must be unique within the script
typeyesOne of: bool, int, float, combo, keybind, item_slot, font, color
defaultyesDefault value when the user hasn't set one
labelyesDisplay label in the menu
min, maxfor int/floatSlider bounds
optionsfor comboArray of strings shown in the dropdown
depends_onoptionalKey of another setting that controls this one's visibility
depends_valueoptionalValue the controlling setting must have for this one to show

Setting types ​

TypeBacking typeNotes
boolbooleanRenders as a checkbox
intintegerRenders as a slider; needs min and max
floatnumberSame as int but for fractional values
combointegerDropdown index (0-based); needs options array
keybindintegerVK code; renders as a "click to bind" picker
item_slotintegerSlot 0-7; renders as an ability-slot picker
fontstringFont name; renders as a font picker with system font search
colorRGBA table{r, g, b, a} with components 0-255; renders as an inline swatch that opens a full RGBA picker on click. default must be a four-key table

Conditional visibility ​

Hide a setting unless another one has a specific value:

lua
settings = {
    { key = "auto_dispel", type = "bool", default = false, label = "Auto Dispel" },
    { key = "dispel_threshold", type = "float", default = 2.0,
      min = 0.5, max = 5.0, label = "Threshold (seconds)",
      depends_on = "auto_dispel", depends_value = 1 },
}

depends_value = 1 for booleans means "controlling setting must be true." For combo, it's the option index (0-based).

config namespace ​

Read and write your script's persisted setting values at runtime.

FunctionReturnsDescription
config.get_bool(key, default)booleanRead a bool setting
config.get_int(key, default)integerRead an int, combo, keybind, or item_slot
config.get_float(key, default)numberRead a float setting
config.get_string(key, default)stringRead a font (or any other string-typed) setting
config.get_color(key)RGBA tableRead a color setting; returns {r, g, b, a} with components 0-255
config.set_bool(key, value)-Write a boolean. Auto-saves to disk
config.set_int(key, value)-Write an integer. Auto-saves to disk
config.set_float(key, value)-Write a float. Auto-saves to disk
config.set_string(key, value)-Write a string. Auto-saves to disk
config.set_color(key, {r,g,b,a})-Write a color. Auto-saves to disk

Values persist per-script in a JSON file. All setting types, bool, int, float, combo, keybind, item_slot, font, and color, save to disk the moment the user changes them in the menu or a script writes them via config.set_*. No manual save call required.

Reading settings ​

lua
function on_tick()
    if not config.get_bool("enabled", true) then return end

    local speed = config.get_float("speed", 1.0)
    local mode  = config.get_int("mode", 0)
    local font  = config.get_string("font", "")
    -- ...
end

The default argument is used when the key isn't in the config yet (e.g. first launch before the user touches the menu). Match the default in config.get_* to the default you declared in settings to avoid surprises.

Writing settings ​

Useful for scripts that need to mutate their own settings in response to events:

lua
function on_tick()
    if input.is_key_pressed(0x70) then  -- F1
        local was = config.get_bool("enabled", true)
        config.set_bool("enabled", not was)
        toast(not was and "ON" or "OFF")
    end
end

Per-script isolation: writing enabled in Script A doesn't touch Script B's enabled. Each script has its own JSON file.

Color picker ​

The color type renders as an inline color swatch in the menu. Clicking it opens a full RGBA picker, hue ring, saturation/value square, alpha slider, and direct hex/RGB number entry. The picked value persists like every other setting.

The default value is a table with four numeric keys, each 0-255:

lua
settings = {
    { key = "alert_color", label = "Alert Color", type = "color",
      default = {r = 255, g = 0, b = 0, a = 255} },
}

Read the current value with config.get_color. Write a new one with config.set_color:

lua
local c = config.get_color("alert_color")
-- c.r, c.g, c.b, c.a, all 0-255

config.set_color("alert_color", {r = 0, g = 255, b = 0, a = 255})

The returned RGBA table plugs directly into the Draw namespace via draw.color(c.r, c.g, c.b, c.a). Here's a complete script that uses a color picker to draw 3D boxes around enemies:

lua
-- Color Picker Test
-- Draws 3D boxes on enemies using color picker
name        = "Color Picker Test"
description = "3D box ESP with color picker"

settings = {
    { key = "box_color", label = "Box Color", type = "color", default = {r=255, g=50, b=50, a=255} },
}

function on_tick()
    local c = config.get_color("box_color")
    local col = draw.color(c.r, c.g, c.b, c.a)
    for _, p in ipairs(get_players()) do
        if p:is_enemy() and p:is_alive() then
            local pos = p:get_position()
            local head = p:get_head_world()
            local height = head.z - pos.z + 14
            local width = 30
            draw.box3d(vec3(pos.x, pos.y, pos.z + height * 0.5), width, width, height, col, 1.5)
        end
    end
end

Changing the swatch in the menu while the script is running updates the box color on the next tick. No reload, no restart.

Top-level globals ​

The full set of script-level globals you can declare:

GlobalTypeDescription
namestringDisplay name shown in the scripts list
descriptionstringOptional one-line tagline shown under the script name in the list
idintegerHero gating. Use hero_id.any for "runs on any hero"
settingstableSetting declarations as above
needs_all_particlesbooleanSet to true if you need ability/tower/environment particle events. Default false

Plus the event callbacks (on_tick, on_kill, on_modifier_added, on_modifier_removed, on_ability_cast, on_item_used, on_particle_create, on_particle_destroy). See Events.

Not affiliated with Valve Corporation.