Script Settings
Two ways to add user-configurable options to your script:
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.ui.*widget API (for advanced or dynamic UIs): imperative widget creation with custom tabs, buttons with callbacks, and runtime-mutable layouts. See UI.
Use settings for simple scripts with a few toggles and sliders. Use ui.* when you need dynamic widgets, custom tabs, or button callbacks.
settings declaration
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:
| Key | Required | Description |
|---|---|---|
key | yes | Config key for persistence. Must be unique within the script |
type | yes | One of: bool, int, float, combo, keybind, item_slot, font, color |
default | yes | Default value when the user hasn't set one |
label | yes | Display label in the menu |
min, max | for int/float | Slider bounds |
options | for combo | Array of strings shown in the dropdown |
depends_on | optional | Key of another setting that controls this one's visibility |
depends_value | optional | Value the controlling setting must have for this one to show |
tooltip | optional | Hover help text attached to the setting's widget in the menu. Example: { key = "speed", type = "float", default = 1.0, min = 0.1, max = 10.0, label = "Speed", tooltip = "Controls how fast the script reacts" } |
Setting types
| Type | Backing type | Notes |
|---|---|---|
bool | boolean | Renders as a checkbox |
int | integer | Renders as a slider; needs min and max |
float | number | Same as int but for fractional values |
combo | integer | Dropdown index (0-based); needs options array |
keybind | integer | VK code; renders as a "click to bind" picker |
item_slot | integer | Slot 0-7; renders as an ability-slot picker |
font | string | Font name; renders as a font picker with system font search |
color | RGBA 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:
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.
| Function | Returns | Description |
|---|---|---|
config.get_bool(key, default) | boolean | Read a bool setting |
config.get_int(key, default) | integer | Read an int, combo, keybind, or item_slot |
config.get_float(key, default) | number | Read a float setting |
config.get_string(key, default) | string | Read a font (or any other string-typed) setting |
config.get_color(key, default?) | RGBA table | Read a color setting; returns {r, g, b, a} with components 0-255. Defaults to white ({r=255,g=255,b=255,a=255}) when the key is absent and no default is provided |
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, color) save to disk the moment the user changes them in the menu or a script writes them via config.set_*.
Reading settings
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", "")
-- ...
endThe default is returned when the key isn't in the config yet. Match it to the value in your settings declaration.
Writing settings
Useful for scripts that need to mutate their own settings in response to events:
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
endPer-script isolation: writing enabled in Script A doesn't touch Script B's enabled. Each script has its own JSON file.
Cross-script config
Read or write another loaded script's persistent settings using the _of variants. The first argument is the target script's name (the name global declared at the top of the other script).
| Function | Returns | Description |
|---|---|---|
config.get_bool_of(script, key, default?) | boolean | Read a boolean from another script's config |
config.set_bool_of(script, key, value) | - | Write a boolean to another script's config and persist it |
config.get_int_of(script, key, default?) | integer | Read an integer from another script's config |
config.set_int_of(script, key, value) | - | Write an integer to another script's config and persist it |
config.get_float_of(script, key, default?) | number | Read a float from another script's config |
config.set_float_of(script, key, value) | - | Write a float to another script's config and persist it |
config.get_string_of(script, key, default?) | string | Read a string from another script's config |
config.set_string_of(script, key, value) | - | Write a string to another script's config and persist it |
There is no color_of variant.
Key behaviors:
- Reads return the default when the target script is not loaded. If the named script is not currently running,
get_*_ofreturns the default value (or the type's zero-value when no default is given) rather than erroring. - Writes only take effect when the target script is loaded. If the named script is not loaded the write is a no-op; load the script first.
- Targeting your own script name is equivalent to the plain
config.get_*/config.set_*calls.
-- A "coordinator" script that reads another script's toggle
function on_tick()
local hook_enabled = config.get_bool_of("Hook", "enabled", false)
if hook_enabled then
-- do something in response to the Hook script being active
end
end-- Disable the Dagger script's aim from a keybind in this script
function on_tick()
if input.is_key_pressed(0x70) then -- F1
local cur = config.get_bool_of("Dagger", "aim_enabled", true)
config.set_bool_of("Dagger", "aim_enabled", not cur)
end
endColor 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:
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:
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:
-- 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
endChanging the swatch in the menu updates the box color on the next tick.
Top-level globals
The full set of script-level globals you can declare:
| Global | Type | Description |
|---|---|---|
name | string | Display name shown in the scripts list |
description | string | Optional one-line tagline shown under the script name in the list |
id | integer | Hero gating. Use hero_id.any for "runs on any hero" |
settings | table | Setting declarations as above |
needs_all_particles | boolean | Set 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.