Scripting overview
Opusbot embeds Lua 5.4 (via sol2) on a background thread. Scripts never call client code directly; actions that need the GUI/main thread are queued and executed on the next client tick.
Scripts can:
- React to game events (
Game.registerEvent) - Run per-tick logic (
function onTick()) - Schedule work (
Timer.new/setInterval/setTimeout) - Draw a HUD (text, rectangles, real item sprites)
- Control bot modules (Cavebot, Healing, Targeting, Spells, Loot, …)
- Talk, use items, walk, trade with NPCs, manage waypoints
The public surface is intentionally ZeroBot-compatible: namespaced modules such as Game, Player, Map, Client, Engine, HUD, Timer, Enums, plus flat natives for lower-level control.
How to load a script
In-client GUI (recommended)
- Open the Opus overlay window in the client.
- Open the Scripts tab.
- You see every
.luafile next to the bot DLL, with a loaded / off badge. - Click Load or Unload per file.
- Reload all re-runs every currently loaded script (picks up file edits).
- Browse .lua… copies a script from disk into the bot folder so it appears in the list.
Config file
In opusbot_cmd.txt (same folder as opusbot.dll):
lua_scripts=my_script.lua,another.lua
Comma-separated. Paths are relative to the DLL directory unless absolute.
From Lua (loader API)
Engine.loadScript("my_script.lua")
Engine.unloadScript("my_script.lua")
Engine.reloadScript() -- reload the whole active set
Engine.isScriptLoaded("my_script.lua")
IPC / pipe (power users)
SCRIPTS
DO scriptload my_script.lua
DO scriptunload my_script.lua
DO scriptreload
DO scriptbrowse
Script lifecycle
- On load, the file is compiled and executed once (top-level code runs).
- If a global
onTickexists, it is called every bot tick (~background poll). - Timers fire on the same thread.
- Events are drained into registered callbacks.
- On unload / full reload, the engine rebuilds the Lua set and clears script HUD elements.
:::note Shared global state
All scripts currently share one Lua global environment. Unload removes the name from lua_scripts and triggers a reload of the remaining set; there is not yet full per-script isolation of event handlers.
:::
Sandbox limits
| Limit | Value | Notes |
|---|---|---|
| Memory | 64 MB | Hard cap against runaway allocation |
| Load budget | 15 s | Wall-clock for initial chunk execute |
| Tick / timer / event budget | 1 s | Wall-clock per callback entry |
| OS library | Disabled | Use getTick(), os.clock shim, os.time shim |
wait(ms) | Allowed | Sleeps in C; still counts against wall-clock budget |
Coordinates (HUD)
HUD coordinates are pixels relative to the game window client area (top-left origin), matching ZeroBot.
- Module toggle bar (Cave / Heal / Target / Spells / Loot) sits near the top-left (
hud_anchor=tl,hud_top_marginin config). - Prefer placing script HUDs below the module bar (e.g. start at
y >= 120) so they do not cover the buttons.