Lua / 60 MIN READ
Lua in RGXbot: complete course and API reference
Learn to write Action and Lua waypoints. Learn all the functions, variables, forms and practical examples.
Basic course + full API catalog · 12/11/2026
Introduction
You'll learn three places to use Lua, write your first condition, prepare an options form, and connect it to a route. Below the course you will find a full catalog of functions, aliases, variables and setting paths available in RGXbot. Content status: November 12, 2026. This is its own subset of Lua, so ready-made scripts from other bots require customization.
1. Choose a place of execution
Action runs recurring tasks. On the Action tab, click Add, enter a name, enable the action and set an interval in milliseconds, for example 1000. Paste the code, use Test Lua, then Save in Action. Start starts the module. File → Save saves the configuration to XML. Saving code and starting the module are separate steps.
Waypoint Action executes the code at a given point in the route. In the waypoint editor, select the type Action and enter the code. Use it to check supplies, switch tabs, or single sequence NPCs. Prepare labels before triggering the jump. Cyclic Action itself has no waypoint position.
Script configuration → Lua / JSON definition creates a settings form. Declare controls in this editor; it does not control the game. Use Apply, then File → Save. Form code is separate from Action code.
Do not paste the entire course into one field. Each block is a separate example; the block marked "Form" goes only to the form definition.
2. The first script without game commands
This example only calculates the values. Paste it into a new action and select Test Lua with the character loaded. No scheduled commands is the correct result here. Do not use print(): the interpreter does not support it.
-- $... to odczyty RGXbot. local to własna zmienna.
local minimumCap = 150
local lowCapacity = $cap < minimumCap
local healthPercent = $hppc
local missingMana = max(0, $maxmp - $mp)local stores a value only during the current invocation. The next Action cycle starts the code again. $hp is a health-point count, while $hppc is a percentage. Assigning a value to a variable does not heal the character. Reads in Test Lua require the appropriate client context.
3. Conditions, nil and units
if starts a condition, elseif checks another possibility, and else handles the remaining cases. Each block ends with end. Compare with ==, assign with =, and write inequality as ~=. Combine conditions with and, or, not. Only false and nil are false; 0 is true.
local state = "gotowy"
if $stamina == nil then
state = "brak odczytu staminy"
elseif $stamina < 1200 then
state = "stamina ponizej 20 godzin"
else
state = "stamina wystarcza"
endStamina has a unit of minutes: 1200 is 20 hours. wait(1000) represents one second and spellcooldown() returns seconds. Never compare an unknown reading nil with a number. Statuses $poisoned and similar may also be nil. No data means no knowledge, not a safe state or a zero balance.
4. First cyclic rule
The following code plans to stop modules upon death or when stamina is below the sample limit. First, view the plan in Test Lua, then select the threshold for your own session. The built-in panel stop conditions still apply; do not replace them with the script itself. stopbot() ends the current script.
if $dead then
stopbot("Smierc postaci")
end
if $stamina ~= nil and $stamina < 1200 then
stopbot("Limit staminy: ponizej 20 godzin")
endLua test shows a plan and does not execute commands in the client. Does not prove a successful stop, spell cast, or purchase. Only after checking the plan, run the appropriate module and confirm the result in the panel and the game. In the absence of stamina, the example does not make decisions based on this reading.
5. A spell with resource control
Choose a known spell, vocation and mana cost for your character. Below is an example condition for a character that knows exura. The 70% threshold and 20 mana cost are example settings. Do not run competing healing rules together without checking their configuration.
if not $dead and not $pz and $hppc < 70 and $mp >= 20 then
if spellcooldown("exura") == 0 then
spell("exura")
end
endspell() is a command and returns nil; do not write if spell(...) then. Evaluate HP and mana after execution. The reads refresh after the command, but the local variable retains the previously calculated value. For potions use useself() and itemcooldown(), and for runes on the target also check $target ~= 0.
6. A form for multiple characters
Paste the block below into the form definition, use Apply and check the fields in Script configuration. ID 268 is an example supply; adjust the ID, quantities and label name to your own route. The form does not buy potions by itself.
addmenu("return", "Powrot i zapasy")
addcheckbox("return_enabled", "Kontroluj powrot", true)
addspinbox("min_cap", "Minimalny cap", 150, 0, 10000)
addtextbox("return_label", "Etykieta powrotu", "refill")
addsupply("mana", "Mana potion", 268, 50, 300)Then create a refill label on the route and add waypoint Action with the code below. needsrefill() takes into account return enablement, minimum cap and enabled stock minimums. supplyneed() counts the miss against the target, not the minimum. Counters include equipment and open containers.
if needsrefill() then
gotolabel(getuseroption("return_label"))
endgotolabel() terminates script: no further lines are executed. Set the options to From Script or Custom for Character so that the common XML has different thresholds for different characters. Save the profile and XML, then check for reload.
7. Order, waiting and loops
Commands execute in order. wait() pauses the current script; pausewalking() pauses walking. With supported optional input, the shared Healer can run while waiting. Avoid long, infinite loops: use the Action interval for regular checks. Loops are limited to 10,000 iterations and nesting to 32 levels.
local attempt = 0
while attempt < 3 do
attempt = attempt + 1
if $target ~= 0 then
break
end
wait(200)
endDon't automatically retry a purchase or transfer after an unknown result. submitted means the input is sent and confirmed means the observer confirms the effect. Remember inputactionid() before wait() if you are tracking a specific operation: healing may change the last record.
8. NPC, bank i depozyt
First, lead your character to the correct NPC on the same floor. npcsay("hi") starts conversation; please check npcisopen(), npcname() and npcmessage() response before proceeding. Trade needs an open offer, money, space and the right name of the item. Buying and selling support at most 100 pieces per call.
checkbank() asks for the balance, and bankbalance() reads it. Do not add npcyes() after bankwithdraw(): confirmation is handled automatically. depositall() deposits coins in the bank. depositer() stores loot in the depot, while deposititems() stores all stacks of the specified IDs. stashcount() requires an open Supply Stash read.
The reference below contains full signatures and separate examples for banking, trading, ammunition, transfers, depot and Stash. Container numbers are current window IDs; do not store them permanently across sessions. Item slots in containers start at 0.
9. Reconnect and execution control
reconnect() must be the first instruction of the cyclic Action if it is to work without reading the PLAYER. Uses the reconnect settings and the same character selected in the panel. Does not bypass death, 2FA or limits; error stops further code. In a waypoint, the call only works when the engine executes that waypoint. Does not start the route automatically after disconnection.
reconnect()
local character = $character
local currentHealth = $hpAfter each new script, check the syntax through Test Lua, read the plan, do one controlled test, and observe the result. In case of error, use log Action and Diagnostics. Keep the function name, arguments, and error message. An unknown function usually means a typo, a different case, or a piece of full Lua that this interpreter does not support.
10. What you know and where to look next
You can select context, read $..., check nil, create conditions, control entities, build a form, and direct a route. The API directory below includes all runtime function names, math aliases, form declarations, and variables. Search for e.g. $stamina, buyitems, addspinbox or priority.targeting. For each group, also read the requirements and restrictions, not just the signature itself.
The interpreter does not support function, for, repeat, table creation, pairs, ipairs, print, require, or file, network, and system libraries. The exception to the lack of tables are ready-made range values from the JSON form: their fields from and to can be read. Use examples compatible with RGXbot.
Introduction
Complete RGXbot API reference. Covers Action and Action waypoints; form declarations use a separate context.
How scripts execute
Commands in a running script execute in order. After a command, the engine refreshes the state: the next itemcount() or $hp uses a fresh read. Local variables keep their own values until that invocation ends. They do not retain state between separate Action script runs.
Lua test shows the plan, without executing commands in the client. Does not simulate purchasing or treatment results. Therefore, the condition after planned purchase may give a different result than during actual execution with status refresh.
Reads return numbers, strings or logical values. Commands such as spell(), buyitems(), and checkbank() return nil to Lua code; the result of the operation is checked with the next read, and errors are included in the logs. Do not write if buyitems(...) then: this is not a success function.
Commands use the selected input. memory means optional keyboard and mouse simulation; it does not switch the default native backend. UI reads and some window operations require a running client and an available memory controller, regardless of where the script runs.
Re-login: reconnect()
reconnect()No arguments: re-logs the same character selected in the panel. Uses the existing login controller and system account vault. It does not log out a character that is already properly online and does not restart the game client. Further script instructions execute only after a live character with the correct name is confirmed; they then refresh the readings from the new session. The result for Lua is nil, as with other control commands.
In the Action module, place reconnect() as the first instruction so it can run even when PLAYER reads are unavailable. A condition using $hp or $name before it still requires a character read. In Action waypoints, the function is available when the engine executes that waypoint; it does not automatically start the waypoint after a disconnection.
The function respects the panel's reconnect settings and limits the entire wait to a maximum of 10 minutes. Stopping or changing the client, backend, or selected character interrupts the operation. 2FA, death, incompatible character, missing account details or exceeded limit stops further instructions; they do not bypass security measures and do not automatically reset the attempt counter. Error Action requires an explicit retry. Statuses are visible in the Reconnect… window and the script log. Native mode maintains native gameplay controls; only login uses the existing UI bridge.
Syntax and units
Supported are local, assignments, if/elseif/else/end, while/do/end, break, return, comments -- and --[[ ... ]], strings in both types of quotation marks, numbers, true, false, nil, + - * / % ^ actions, == ~= < <= > >= comparisons, .. and and/or/not concatenation. Semicolons are optional. Function names are case-sensitive. Only false and nil are false: the number 0 is true.
Custom definitions function, for/repeat loops, tables, pairs/ipairs, print, require, file, network and system libraries are not supported. local does not provide the full scope semantics of complete Lua. Loop has a limit of 10,000 iterations and nesting has a limit of 32 levels.
| Value | Unit/range |
|---|---|
wait, pausewalking, $hunt_time, $target_time, $stand_time | milliseconds |
spellcooldown, itemcooldown, $food | seconds |
| HP/mana in percent | 0–100 |
| Item ID | integer 1–65535 |
| x/y coordinates and z floor | x/y 0–65535, z 0–15 |
| open container number | current window ID, usually 0–255; not the position on the screen |
| container slot | an index of 0 |
| depot box number | 1–21 |
| quantity in item commands | usually 1–100000; buy/sell maximum 100 per call |
In signatures, [argument] means an optional argument; do not type the square brackets in code. A nil container in moveitem() means equipment. Protected reads, including blessings, cooldowns and banking, raise an error for an unknown state. isitemontile() only checks the snapshot: a missing tile gives false.
Equipment slots: 1 head, 2 neck, 3 backpack, 4 armor, 5 hand/shield, 6 hand/weapon, 7 legs, 8 boots, 9 ring, 10 secondary slot, 11 Store Inbox. Arrows and bolts are refilled into the quiver, not directly into slot 10.
Character variables
| Variables | Meaning |
|---|---|
$name, $level, $exp | name, level, experience |
$character | character recognized and assigned to the panel; identity also used for relog |
$hp, $maxhp, $hppc | HP, maximum HP, HP percentage |
$mp, $maxmp, $mppc | mana, maximum mana, mana percentage |
$cap | available carrying capacity |
$x, $y, $z | world position |
$posx, $posy, $posz | item aliases |
$soul, $speed | soul, client speed |
$stamina | current stamina in minutes: 0–2520; nil when reading is not correct |
$food, $hungry | food counter; hungry is true with counter 0 |
$pz, $pzblock | Protection Zone and PZ lock |
$target, $followed | ID of the attacked / followed target; 0 means none |
$attacked | whether the ID of the attacked target is set, not "is someone hitting me" |
$dead, $deathcount | death and death counter in the current death policy session |
$route | name of the active route tab |
$statusknown, $statusflags | read availability and raw state mask; mask is nil if no data is available |
$poisoned, $paralyzed, $burning, $hasted, $bleeding, $drunk, $mana_shield | boolean or nil if the agent does not provide a mask |
$hunt_time, $target_time, $stand_time | time of hunting, current target and standing still |
$stamina works in Cavebot waypoints and Lua actions. 1200 means 20 hours, and 2520 is a full 42 hours. The value refreshes with the script context, including after wait(). A missing read does not mean zero.
if $stamina ~= nil and $stamina < 1200 then
gotolabel("rest")
endNot every context has an active waypoint, target or hunting timer. Unavailable start times produce 0. The $... variables describe reads; assigning your own value does not change the character's state in the game.
Reads and calculations
Items, map and position
inputstatus([id]), inputaction([id]), and inputactionid([id]) read the status, name, and operation ID of an optional input. Without an argument, they apply to the last operation. Missing record (also in native) gives nil. The history has a maximum of 64 entries, separately for the controller; the record does not contain arguments, typed text, or error details.
The states are started, submitted, completed, confirmed, failed, cancelled, uncertain. submitted means input was sent; completed means the function finished without separate confirmation of the effect. failed and cancelled describe execution ending, not undoing earlier events. confirmed requires an explicit observer of the effect. ListedLoot and transfers inside Game.deposit_all assign this state only after checking exact changes and the same character session. A depot sequence has a separate record for each transfer, not one confirmation for the entire sequence. Banking and trading in optional input also assign confirmed when their observer checks the balance/cash or items/amount respectively and the handler finishes in the same session. A function response alone does not promote the status. moveitem() does not automatically start such an observer.
local operation = inputactionid()
local status = inputstatus(operation)
local action = inputaction(operation)The ID allows you to check an older transfer after another action. Results are consistent across the Lua snapshot and refreshed after dispatch. They are not intended to automatically repeat unconfirmed purchases or transfers.
actionbarcount() returns the number of recognized non-empty actionbar entries. hasitemhotkey(id) checks whether an item has a keyboard shortcut assigned to it, and hasspellhotkey("formuła") does the same for the exact spell formula (insensitive to case and extra spaces). No hash gives false; missing or failing to read the client is a script error. An entry without a shortcut can still be click-activated by the entry module. The shortcut itself does not confirm item inventory, spell availability, target, or cooldown.
-- Te zapytania tylko czytają konfigurację bieżącego klienta.
local entries = actionbarcount()
local healthBound = hasitemhotkey(266)
local healBound = hasspellhotkey("exura")Continue to use useself(), usetarget() or spell() to execute. Maintains target/cooldown control and priority of recognized buttons before formula entry. The bar reading is shared within the Lua snapshot and refreshed after the action; names or abbreviations are not remembered globally between clients.
| Function | Result and action |
|---|---|
itemcount(id [, lokalizacja]) | number in equipment and open containers; the location filter matches part of the name without case |
groundcount(id, x, y, z) | the sum of confirmed numbers of physical items in the read field |
isitemontile(id, x, y, z) | presence of ID in the current map snapshot; does not indicate range of use or lifting ability |
canshoot(x, y, z) | true/false for known local firing line; unknown state reports an error |
getfacing() | "north", "east", "south" or "west" |
islocation([zakres]) | whether the character is near the current Action waypoint on the same floor; default range 0; returns false outside such a waypoint |
getlurelocation(nazwa) | whether the named location exists; returns a bool, not coordinates |
getoption(nazwa) | script option value or nil if absent |
itemcount() does not search closed backpacks or the bank. Open corpse or deposit windows may enter the total sum; use the name filter when you need a specific source. Container numbers can be reused after closing: do not hardcode them between sessions.
Cooldowny, okna, NPC, bank i Stash
| Function | Result and requirements |
|---|---|
spellcooldown(formuła) | self and spell group cooldown remaining, in seconds |
itemcooldown() | common multi-use cooldown remaining, in seconds |
windowcount() | number of visible dialogue/menu roots, not number of all sidebars |
windowexists(tytuł) | whether a window with the exact title given is visible |
npcisopen() | whether the NPC conversation is visible |
npcname() | name from an open conversation or an empty string |
npcmessage() | last recognized NPC response, no time/name prefix; blank string when none |
npccontains(tekst) | whether the last reply contains the text, case-insensitive |
bankbalance() | last confirmed balance in the entry context; do checkbank() first |
stashcount(id) | quantity in the available open Supply Stash read; a closed Stash means unknown state |
bankbalance() does not ask the banker by itself. An unknown state is not a zero balance. Player messages are not NPC replies. canshoot() is a conservative assessment of the local map, not a guaranteed hit.
Death and blessings
| Function | Result |
|---|---|
isdead() | bool: correct max HP and current HP ≤ 0 |
deathcount() | session death counter like $deathcount |
hasblessing(nazwa_lub_id) | whether the character has the indicated blessing |
hasblessings() | whether he has at least one of the seven ordinary blessings |
hasallblessings() | whether he has all seven ordinary blessings |
blessingscount() | number of regular blessings, excluding Adventurer and Twist |
blessings() / blessingnames() | names of owned blessings as one comma-separated string |
| Customer ID | Name assumed by hasblessing |
|---|---|
| 1 | Adventurer's Blessing |
| 2 | Twist of Fate |
| 4 | Wisdom of Solitude |
| 8 | Spark of the Phoenix |
| 16 | Fire of the Suns |
| 32 | Spiritual Shielding |
| 64 | Embrace of Tibia |
| 128 | Heart of the Mountain |
| 256 | Blood of the Mountain |
Names can omit the The prefix and are case-insensitive. These are not sequential indices 1–9: use names or exact IDs from the table. An unavailable blessing read raises an error rather than falsely reporting none.
Character states
| Function | Result |
|---|---|
statusknown() | bool: Whether the snapshot contains a valid state mask |
statusflags() | number: raw 32-bit mask, also with unrecognized bits |
hascondition("poisoned") | bool: whether the indicated state is active |
conditions() | text: active names separated by commas; empty when no conditions are active |
ispoisoned(), isparalyzed(), isburning() | abbreviations for poisoning, paralysis and arson |
ishasted(), isbleeding(), isdrunk() | shortcuts for haste, bleeding and drunkenness |
iselectrified(), iscursed(), ismanashielded() | abbreviations for electrification, curse and magic shield |
Names for hascondition: poisoned, burning, electrified, drunk, mana_shield, paralyzed, hasted, in_fight, drowning, freezing, dazzled, cursed, party_buff, pz_block, protection_zone, bleeding, hungry. Accepted aliases: poison, burn, fire, energy, paralyze, paralysed, haste, manashield, pz, pzblock.
All functions except statusknown() raise an error when the read is unknown. An unsupported name is also an error. A missing status field in an old agent means unknown state, while explicit status=0 means no active conditions. $hungry still uses the food counter; check the hunger icon with hascondition("hungry"). Unknown high bits are preserved only in statusflags(). The bit map comes from the PlayerStates enum in the OTClient source. Fully confirming every effect in the current client version requires observing each one live.
if statusknown() and ispoisoned() and $level >= 10 and $mp >= 30 then
if spellcooldown("exana pox") == 0 then
spell("exana pox")
end
endif statusknown() and hascondition("paralyzed") and $mp >= 10 then
if spellcooldown("exura infir ico") == 0 then
spell("exura infir ico")
end
endSuch scripts schedule regular spells through a selected input. Merely sending a spell does not remove the effect. The built-in Condition Healer confirms the disappearance of a flag in the same session, uses shared cooldowns and a priority queue. It does not add any active rule by default.
Mathematics and drawing
| Function | Result |
|---|---|
min(a, ...) / math.min(a, ...) | minimum of 1–32 numbers |
max(a, ...) / math.max(a, ...) | maximum of 1–32 numbers |
abs(x) / math.abs(x) | absolute value |
floor(x) / math.floor(x) | rounding down |
ceil(x) / math.ceil(x) | round up |
random() / math.random() | a number from 0 inclusive to 1 only |
random(maximum) / math.random(maximum) | integer from 1 to maximum, both inclusive |
random(minimum, maximum) / math.random(minimum, maximum) | total number in a closed range |
Control commands
Movement, combat, spells and items
| Function | Behavior |
|---|---|
move(kierunek) | movement consistent with the selected input mode |
turn(kierunek) | rotation without walking; only north/east/south/west |
facetarget(id) | turn toward the active target |
attack(id) | select the attacked target; 0 cancels your own targeting |
follow(id) | following a goal; 0 cancels |
stop() | stop using a supported hotkey/Esc in keyboard and mouse mode; does not click the Stop button |
cancel() | cancel the current action |
loot() | configured quick loot via selected input |
hotkey(skrót) | e.g. "F1" or "Ctrl+F2"; uses the current client assignment |
spell(formuła) | spell, with cooldown control and preference for recognized action bar |
spelltarget(formuła, id [, zasięg]) | spell on active target; default range 3, range 1–7 |
useitem(id) | item use |
useself(id) | use on your own character |
ensureaol([maksymalna_cena]) | keeps the established AoL or obtains and installs the missing one; limit 1–70000 gp, default 70000 |
usetarget(id, cel) | using a rune/item on an actively attacked target on the map |
useinventory(slot, id) | using an item from your inventory |
usecontainer(kontener, slot, id) | using an item from an open container |
useworld(x, y, z, id) | use of an object in the world field |
moveitem(id [, ilość, źródło, slot_źródła, cel, slot_celu]) | transfer; nil means equipment; specify the full source and destination |
pickupitem(id, x, y, z, kontener [, ilość, slot]) | pick up into a backpack; defaults to the largest available stack, slot selected automatically |
refillammo(id [, minimum, ilość, kołczan]) | replenishment below the minimum to the specified quantity; defaults to 50/100 and the only open quiver |
Movement directions: north, east, south, west, ne, se, sw, nw. move() is not an arbitrary coordinate command; the route is marked by waypoints. After setting the target, the status is checked by $target.
spelltarget, facetarget and usetarget require a valid active target. Out of range, target change, or blocked/unknown firing line interrupts appropriate use. The mere consumption of a rune or mana does not prove the damage dealt. Match the spell to the character's profession, level and learned skills.
The defaults for moveitem() are quantity 1, source/target nil and slots 0. This does not automatically search for the source; most often all six arguments are needed. If the quantity is greater than the source stack, the command may be rejected. Do not retry in a transfer loop with an unknown result. Replenishing ammo requires an open quiver and a supply in open backpacks. For several quivers, give his number. The function does not buy ammunition, does not open the quiver and does not equip it.
Chat, NPCs and trading
| Function | Behavior |
|---|---|
chat_on() / chaton() | enable typing in chat |
chat_off() / chatoff() | disabling chat typing |
say(tekst) | ordinary local message |
npcsay(tekst) | send a message to the correct NPC conversation window |
npcdialog(akcja) | action yes, no, bye, trade or close |
npcyes() / npcno() | reply using the yes/no button |
npctrade() | open trading |
npcbye() / npcclose() | say goodbye / close the window |
buyitems(nazwa, ilość) | purchase 1-100 pieces; checking the price and both status changes |
sellitems(nazwa, ilość) | sale 1-100 pieces with item and money confirmation |
Use lowercase letters for NPCs. say("hi") can start a conversation, but send further replies via npcsay(). The hotkey() hash does not check the intent of a specific assignment; prefer semantic commands for spells and potions. npcsay("hi") and npcsay("hello") also work on a fresh client without the NPCs tab: the greeting itself then uses Local Chat. Other messages require an existing conversation or NPCs channel. Sending a greeting does not prove a response: check npcisopen(), npcname() and npcmessage() before proceeding. The NPC must be within conversation range on the same floor. On client 15.33.124f6c Native sends responses via the typed method of the NPC open window controller. Requires a current conversation and the same NPC within range. It doesn't use keyboard focus or the old protobuf setter. Gustavo's answer to "goblins" was confirmed in-game. In keyboard and mouse mode, the items you need must be accessible through a recognized action bar, inventory, or open windows.
Bank, depozyt i Supply Stash
| Function | Behavior |
|---|---|
checkbank() | asks the banker about the balance; then read bankbalance() |
bankdeposit([kwota]) | deposit an amount or all available coins |
bankwithdraw(kwota) | paycheck; the module itself sends yes after the appropriate question and confirms the balance/coins |
depositall() | depositing all coins into bank, alias bankdeposit() behavior |
opendepot() | opening a nearby depository |
opendepotbox([numer]) | opening the deposit box; default 1 |
deposit(id [, skrzynka, ilość]) | store an item; defaults to box 1, quantity 1 |
withdraw(id [, skrzynka, ilość]) | retrieve into a backpack; defaults to 1 and 1 |
depositer([nazwa, depot(x,y,z), box(n)]) | putting aside the loot specified in the Looting configuration from all stacks |
findfreedepot([depot(x,y,z)]) | choose a free reachable tile in front of a locker and open your own depot |
reachnpc(nazwa [, dystans]) | approach the current position of an NPC with the exact name; default distance 3 tiles; range 1–3 |
deposititems(id, ... [, nazwa, depot(x,y,z), box(n)]) | store all stacks of the specified IDs |
box(n) | box marker for depositer/deposititems, n=1–21 |
depot(x,y,z) | position marker for high-level put away |
openstash() / closestash() | open / close Supply Stash |
retrievestash(id [, ilość]) | download; default quantity 1 |
stowitem(id [, ilość]) | store in Stash; defaults to 1 |
stash(nazwa_plecaka) | high-level Stash support for designated open backpack |
depositall() is for the bank; depositer() stores loot in the depot — they are different functions. Do not manually add npcyes() after bankwithdraw(): confirmation is already handled and checked. A large quantity in deposit/withdraw does not automatically loop through all containers; use depositer and deposititems for all stacks. These operations require depot access and the correct open backpacks. Coordinates alone do not bypass walls, distance or interaction requirements.
findfreedepot() checks the fresh map and characters, moves directly to the access square, then checks for occupancy again and opens the deposit. The optional item limits the search to the neighborhood of a given deposit. If there is no free station, it repeats readings for up to 30 seconds and then pauses the sequence. Does not confirm deposit or purchases without success. In a live script, it can be followed by a call to depositer(box(1)).
Click on Look
| Tutorial function Native | Behavior |
|---|---|
buttonexists(napis) | observing clear dialogue buttons |
clientbutton(napis [, tytuł_okna]) | clicking the button selected after the text and optional window title |
tutorialhint() | current tutorial tip; blank text means no hint |
tutorialhintcontains(tekst) | matches the current hint, case-insensitive |
tutorialclick(oczekiwana_wskazówka [, przycisk]) | click the current tutorial highlight; left/right button |
tutorialdrag(oczekiwana_wskazówka) | dragging the only visible item to the empty target indicated by the tutorial |
tutorialuse(oczekiwana_wskazówka) | clicking the highlighted tool, then the second tutorial objective, e.g. using a rope |
classiccontrols() | set Classic Controls in the client, Apply and reopen options to verify saving; requires Native, closed dialogs and no monsters on screen |
choosevocation(nazwa) | select and confirm a vocation in the tutorial window; Confirm must belong to that vocation's card |
Dragging selects the source from the item read in the slot, not the position of the hint text. Multiple destinations, two occupied slots or a missing item abort the operation. The mouse is released even after an error. These functions use the agent's existing Qt bridge and do not move the system cursor or switch input to memory.
In Native mode, buttonexists("Start") reads visible client dialog buttons and clientbutton("Start") selects one unambiguous button after its text. Does not select action bar items or click fixed coordinates. No read, multiple matching buttons, death or session change abort the operation. Simply sending a click does not confirm that you have completed the tutorial; read the next screen/item before the next action. Memory mode does not automatically switch to this operation Native.
| Function | Behavior |
|---|---|
opencontainer(id) | opening the equipped backpack from the default slot 3; to search inside use openitem() |
openitem(id_lub_nazwa [, źródło, nowe_okno, indeks]) | searching and opening; default new window=true, index=1; source is name or ground(x,y,z) |
ground(x,y,z) | position marker for openitem() |
closecontainer(numer) | close the specified open container |
containerup(numer) | open the parent container in this window |
minimizecontainer(numer) / maximizecontainer(numer) | set the window state; repeating it does not toggle it back |
closewindows([limit]) | Esc for dialogs/menus, default 6, maximum 8; does not automatically close the death window |
lookinventory(slot, id) | Look at an equipped item |
lookcontainer(numer, slot, id) | Look in a specific container |
lookworld(x,y,z) | Look on top of the world box |
lookcreature(id) | Look at the specified character/NPC/monster |
deathdialog([akcja]) | defaults to revive; character_list opens the character list |
Look waits for a new customer response; in Lua it does not return description text. No fresh result is a no-retry error. Closing/up/collapsing the container checks the actual identity of the window. containerup() with no parent available is not automatically treated as a success.
Command aliases
In addition to table names, npc_dialog(), use_item(), use_self(), use_inventory(), use_container(), use_world(), move_item(), and open_container() work, with the same arguments as their compact counterparts.
Route and configuration
Script configuration and character profiles
The Script configuration tab contains options and supplies, the single backpack rule editor and a separate Lua definition editor. After editing, click Apply. Cavebot and Action use the same values on the next read; restarting the route is unnecessary. File → Save stores the complete configuration in XML: the form definition (setup_code) and default option values (script_api.options). Each option can use From script or Custom for character. Only explicitly selected overrides go into the selected character profile, preserving XML defaults. Save as… creates a copy without modifying the previous script. setsettings() and Apply change the current configuration; saving XML requires Save or enabling automatic saving in File. Selecting another script does not carry over the previous script's options.
The form definition is performed offline. The following declarations, local variables, conditions, limit loops, and basic calculations are allowed. Game commands, client reads, wait() and setting changes are rejected in this editor. Control declarations are not intended for waypoints or circular Action.
The Lua / JSON definition editor also accepts a JSON form in the style of WindBot User Options: a single group, an array of groups or comma-separated groups. Supported types are group, lineedit, checkbox, combobox, spinbox, doublespinbox and rangespinbox. Groups have children, column (1 or 2) and optional checkable. The description fields provide tooltips; text fields support placeholder, and numeric fields support prefix and suffix. A group's checkbox disables editing of its children; the script should check the group's value before performing related actions. This is not an importer for entire WindBot scripts.
rangespinbox stores two bounds as [od, do]; a single value sets both bounds equally. getuseroption("wait_spawn") returns a table with from and to fields, for example:
if getuseroption("wait_spawn") then
local bounds = getuseroption("wait_spawn")
wait(random(bounds.from, bounds.to))
endThe Insert Sample JSON button contains a set of basic controls. The JSON form and its values are stored in the same XML and profiles as the Lua form. Changing the format does not trigger any game commands.
| Declaration in the form editor | Behavior |
|---|---|
addmenu(klucz, tytuł) | create or select a group/menu for subsequent controls |
addcheckbox(klucz, etykieta, domyślna) | checkbox with a true/false value |
addspinbox(klucz, etykieta, domyślna, minimum, maksimum [, krok]) | number field, default step 1; for fractions, enter a step smaller than 1 |
addtextbox(klucz, etykieta, domyślna) | text field |
addcombobox(klucz, etykieta, domyślna, wybory) | list; selections are text, e.g. "safe|normal" |
addlabel(tekst) | description in the current menu |
addsupply(klucz, etykieta, id, minimum, cel) | four fields supplies.KLUCZ.enabled/id/minimum/target; the minimum must not exceed the target |
addbackpack(nazwa, id [, rodzic, przeznaczenie]) | adds a missing rule to the existing backpack manager; does not overwrite a saved rule with the same name; purpose: loot/gold/supplies/other |
Default backpack rules are added once per character configuration. Later renaming or deleting a rule in a profile does not recreate the old rule from the template.
Control keys must be unique; ASCII letters, numbers, underscore, period and dash are allowed. Maximum of 200 controls, 30 menus and 50 backpack rules per definition. Definition example (paste into Lua Definition):
addmenu("return", "Powrót i zapasy")
addcheckbox("return_enabled", "Kontroluj powrót", true)
addspinbox("min_cap", "Minimalny cap", 150, 0, 10000)
addtextbox("return_label", "Etykieta powrotu", "refill")
addsupply("mana", "Mana potion", 268, 50, 300)
addmenu("hunt", "Polowanie")
addcombobox("hunt_mode", "Tryb", "normal", "safe|normal")
addlabel("Dostosuj zapasy i nazwy plecaków do postaci.")
addbackpack("Backpack", 2854, "", "supplies")| Function available in Cavebot and Action | Result / behavior |
|---|---|
getuseroption(klucz) | alias of getoption(); returns the saved value or the form default |
setuseroption(klucz, wartość) | alias setoption(); validates the type and scope of the declared control |
getsettings(ścieżka) | read a form option or actual settings from the table below |
setsettings(ścieżka, wartość) | value recording; execution refreshes the context before the next command |
getsetting(ścieżka) / setsetting(ścieżka, wartość) | aliasy getsettings/setsettings |
caplow() | whether $cap is below the min_cap option; a missing threshold means 0 |
supplycount(klucz) | count of the item ID from addsupply(); equipment and open containers |
supplyneed(klucz) | how much is missing from the target quantity, not less than 0 |
supplieslow() | whether any enabled stock is below the minimum |
needsrefill() | return_enabled i (caplow lub supplieslow); brak return_enabled oznacza true |
| Getsettings/setsettings path | Value |
|---|---|
setup.min_cap, setup.return_label, setup.supplies.mana.target | form options; options/useroptions prefixes are equivalent; the key itself is also allowed |
navigation.pass_players_outside_pz, navigation.ignore_players_path, navigation.enter_echo_raids | true/false, actual navigation configuration |
looting.enabled, looting.quick_loot, looting.eat_food, looting.auto_echo_loot, looting.own_kills_only | true/false, existing LootConfig |
containers.Backpack.keep_open, containers.Backpack.item_id, containers.Backpack.parent, containers.Backpack.purpose | properties of an existing rule called Backpack; also the remaining ContainerRule fields except name |
priority.targeting, priority.looting, priority.cavebot | priority 1–10; lower wins |
You may use / instead of . as a separator. An unknown module path, missing backpack rule or incorrect type is an error. This is not full compatibility with arbitrary historical WindBot paths. The functions do not change input configuration or login data, or start GUI modules. looting.enabled changes module configuration, not its start switch. Likewise, reading supplies does not buy items or search closed backpacks. Purchases/retrievals require explicit Lua code on the route.
Example of waypoint Action using the form:
if needsrefill() then
gotolabel(getuseroption("return_label"))
endExample of changing settings during execution:
setsettings("setup.min_cap", 200)
setsettings("navigation.enter_echo_raids", false)
setuseroption("hunt_mode", "safe")In Test Lua, setting changes are only a plan; actual values remain unchanged. Saving a profile and applying a form do not perform game actions.
The form pattern is based on the manufacturer's WindBot Cavebot User Options mechanism. RGXbot uses its own declaration syntax and settings paths.
Route and options control
| Function | Behavior |
|---|---|
gotolabel(etykieta [, sekcja]) | jump to a labeled waypoint; ends the current script |
gototab(nazwa) | switching the route tab; ends the current script |
reachgrounditem(id [, dystans]) | approach a visible object; default distance 1, range 0–18; ends the script |
wait(ms) | current script wait, 0–3600000 ms |
stopbot([powód]) | stops all modules and ends the script; optional reason up to 200 characters |
pausewalking(ms) | pause of walking only, 0–3600000 ms |
setoption(nazwa, wartość) | writing script option; is not an arbitrary call to GUI settings |
setlocation(nazwa, x,y,z) | save a named location |
setlurelocation(nazwa, x,y,z) | location save alias |
addspecialarea(nazwa, x,y,z) | adding a named field excluded from the route |
removespecialarea(nazwa) | deleting such a field |
setpriority(moduł, priorytet) | targeting/looting/cavebot priority, number 1–10; lower wins |
In optional control mode, wait leaves the client available for treatment. During pause, the scheduler checks the same character session and supports shared Healer enabled; the next statement is still waiting for the end of the pause. Cancellation, death, or change of the session interrupts further instructions from this script. Treatment may change the last input operation during wait: to track a previous transfer, keep its inputactionid() before pausing.
Technical key cavebot stands for the route module. Locations and options supports runtime scripts; are not local Lua variables. Jump features require an existing route/tag. getlurelocation() only checks for the presence of a name. openitem() and stash() also end the current script. In the Test Lua plan, the findfreedepot/depositer/deposititems operations end the plan, while in the live execution they can continue after the confirmed operation.
Examples
Each block below is a separate example. Adjust item IDs, container numbers, spells, labels and coordinates for your character.
Knighta healing with mana and cooldown control
if not $dead and $hppc < 70 and $mp >= 10 then
if spellcooldown("exura infir ico") == 0 then
spell("exura infir ico")
end
endFor permanent healing, use primarily Healing rules. The example shows a function call; the spell must be available to this character.
Potion and mana replenishment
if $mppc < 40 and itemcount(268, "bag") > 0 then
if itemcooldown() == 0 then
useself(268)
end
endRune on the active target
if $target > 0 and not $pz then
if itemcount(21352) > 0 and itemcooldown() == 0 then
usetarget(21352, $target)
end
endID 21352 means Lightest Missile Rune in the current directory. For another rune, check the ID and requirements. The position and line of fire are checked by the action.
Food and explicit chat mode
if $hungry and itemcount(3578) > 0 then
useitem(3578)
end
chat_off()Bank: checking and safe withdrawal
checkbank()
if bankbalance() >= 100 then
bankwithdraw(100)
end
npcclose()Stand by the banker. The withdrawal itself confirms yes; do not add a second confirmation. bankdeposit() deposits all coins without argument.
Buy missing potions
local brakuje = 5 - itemcount(266, "bag")
if brakuje > 0 then
buyitems("health potion", min(brakuje, 100))
endStand near the correct seller with an available offer, money and space. A purchase does not automatically travel to a shop. The following separate example sells one vial only after a read confirms ownership:
if itemcount(285, "bag") > 0 then
sellitems("empty potion flask", 1)
endNPC conversation
say("hi")
if npcisopen() and npcname() == "Aurelia" then
npctrade()
endDo not replace npcsay() with plain say() in subsequent replies. npccontains("balance") checks the response, not the history of its own statements.
Completing the quiver
refillammo(3447, 50, 100)Requires exactly one open quiver. If there are several, select the current ID:
refillammo(3447, 50, 100, 2)Move one item into equipment
moveitem(3338, 1, 0, 2, nil, 6)The example assumes the Bone Sword in container 0, slot 2. Slot 6 is the weapon hand. The source state and actual window number must be determined before running. Do not run this repeatedly when the result of the first operation is not confirmed.
Saving loot and downloading from Stash
opendepotbox(2)
deposititems(3031, 3272, box(2))openstash()
local brakuje = 5 - itemcount(266, "bag")
if brakuje > 0 and stashcount(266) >= brakuje then
retrievestash(266, brakuje)
end
closestash()Containers and Look
maximizecontainer(0)
lookinventory(6, 3338)
lookcontainer(0, 0, 285)
minimizecontainer(0)The example requires a vial in slot 0 of container 0. You can separately use containerup(0), closecontainer(0), lookworld($x, $y, $z) or lookcreature($target) with a positive and visible ID.
Return to a label when supplies are low
if itemcount(266, "bag") < 2 or $cap < 40 then
gotolabel("depo")
endThe route must have the label depo. This is a route switch, not an independent combat escape system and not a guarantee of a safe route.
Checking blessings and death
local liczba = blessingscount()
local twist = hasblessing("Twist of Fate")
local komplet = hasallblessings()
local nazwy = blessings()if isdead() then
deathdialog("revive")
return
endFor an automatic response after death, prefer the death policy settings. A script does not change its death limit or its decision to resume.
Options, field lock and random pause
setoption("tryb_testowy", true)
setlocation("baza", $x, $y, $z)
addspecialarea("pole_do_ominiecia", $x + 1, $y, $z)
setpriority("targeting", 1)
pausewalking(random(200, 400))Remove the block later with removespecialarea("pole_do_ominiecia"). Randomness in this example affects time; mouse movement and walking behavior are configured separately in the optional input module.
A loop with an explicit limit
local i = 0
while i < 3 do
i = i + 1
if $dead then
break
end
wait(100)
endDon't create an endless healing or trading loop. The Action script can be called periodically by the module and the state is refreshed between actions.
Errors and limitations
Unknown cooldown, blessy, balance or Stash is a read error, not a zero.
Wrong number of arguments, ID 0, non-integer number and unknown function name are rejected. Exceptions such as
attack(0)are described separately.Altered window, missing item, unconfirmed transfer or purchase require condition checking. Don't repeat the operation blindly.
The Lua test does not check item availability, spell learning, or result server. The final result is confirmed by readings during live performance.
Opening backpacks, trading, and Look may require visible controls inside the client, also when the client itself runs on a hidden virtual screen.
Related descriptions: ranged combat, healing scheduler, input module.