Skip to main content

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

  1. Open the Opus overlay window in the client.
  2. Open the Scripts tab.
  3. You see every .lua file next to the bot DLL, with a loaded / off badge.
  4. Click Load or Unload per file.
  5. Reload all re-runs every currently loaded script (picks up file edits).
  6. 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

  1. On load, the file is compiled and executed once (top-level code runs).
  2. If a global onTick exists, it is called every bot tick (~background poll).
  3. Timers fire on the same thread.
  4. Events are drained into registered callbacks.
  5. 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

LimitValueNotes
Memory64 MBHard cap against runaway allocation
Load budget15 sWall-clock for initial chunk execute
Tick / timer / event budget1 sWall-clock per callback entry
OS libraryDisabledUse getTick(), os.clock shim, os.time shim
wait(ms)AllowedSleeps 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_margin in config).
  • Prefer placing script HUDs below the module bar (e.g. start at y >= 120) so they do not cover the buttons.