ZorbitBot v1.50.3 · Lua 5.1

API documentation

Everything your scripts can do with ZorbitBot — bot control, player state, creatures, items, actions, events and the zorbitKit UI library.

150+ documented calls Lua 5.1 / LuaJIT OTClient Scripts window
Nothing matched — try a shorter phrase.

Getting started

Scripts are plain Lua files run by the bot's Scripts module.

Documents\ZorbitBot\scripts\

Put your .lua files in this folder. They show up in the Scripts window (with an editor and console), and you run them with one click. Errors land in the console, not in a crash.

-- my_script.lua — runs every time you click it in the Scripts window
local x, y, z = zorbitGetPos()
zorbitLog("hello from " .. x .. "," .. y .. "," .. z)

How scripts run

Your script gets one context object with everything pre-wired.

Every script runs inside the client's own Lua environment, wrapped by the bot's compatibility layer. That means you get the bot's zorbit* functions plus the game interface of your client (g_game, g_map, g_ui…) in the same script, with errors routed to the Scripts console instead of crashing your session.

scheduler

macro(timeout, fn) repeats your function every timeout ms; schedule(ms, fn) runs it once after a delay. Never busy-loop — use the scheduler.

state shortcuts

Read-only fields like hp, mana, pos, cap are refreshed every tick — plain variables, zero setup.

events

Override an on*Callback (e.g. onTalk, onTextMessage) to react to game events instantly.

Engine & toggles

Turn the bot and its modules on and off, and read the status line shown in the UI.

zorbitSetToggleset

Enables or disables one engine toggle. Returns true if the name is valid.

zorbitSetToggle(name, on) → bool
zorbitSetToggle("heal", true)   -- enable the Healbot engine
zorbitSetToggle("cavebot", false) -- stop walking the route
zorbitGetToggleget

Reads a toggle's current state. Returns true or false.

zorbitGetToggle(name) → bool
if zorbitGetToggle("alarm") then zorbitLog("alarms are on") end
zorbitGetStatusget

Returns the engine's status line — the same text the UI shows.

zorbitGetStatus() → string
zorbitMasterToggleset

The master switch — turns the whole bot engine on or off at once.

zorbitMasterToggle(on) → void
namecontrols
"heal"healbot rules
"mana"mana rules
"target"targeting
"loot"looting
"cavebot"walking waypoints
"antiIdle"anti-idle
"alarm"alarms module
"conditions"conditions module
"friendhealer"friend healer module
"follow"following a player

Character & profile

Read where you are, switch profiles and manage following.

zorbitGetPosget

Returns your position as three values. When offline you get 0, 0, 0.

zorbitGetPos() → x, y, z
local x, y, z = zorbitGetPos()
zorbitLog("pos: " .. x .. "," .. y .. "," .. z)
zorbitGetProfile / zorbitSetProfilegetset

Profiles are numbered sets of settings (rules, waypoints, priorities). zorbitGetProfile() returns the active number, zorbitSetProfile(n) switches to profile n (1-based).

zorbitGetProfile() → number
zorbitSetProfile(n) → bool
-- swap to the second profile for a different hunt spot
zorbitSetProfile(2)
zorbitGetFollowName / zorbitSetFollowNamegetset

The name of the player the Follow module walks after.

zorbitGetFollowName() → string
zorbitSetFollowName(name) → bool
zorbitGetCavebotStateget

Cavebot runtime state — which waypoint is active, whether the bot is walking or on a delay.

zorbitGetCavebotState() → string -- e.g. "wp 3/12 walking"

Targeting

Priority order of creature names used by targeting.

zorbitGetTargetPriority / zorbitSetTargetPrioritygetset

A comma-separated list of creature names — the bot attacks in this order. Unknown names fall last.

zorbitGetTargetPriority() → string
zorbitSetTargetPriority(csv) → bool
zorbitSetTargetPriority("Demon, Dragon Lord, Dragon")

Player state

Live fields and condition checks about your own character. All of them are plain values — read them straight from the script context.

context fieldsfields

Refreshed every engine tick. Use them directly — if hp < 50 then ... end.

fielddescription
namecharacter name
hp / hpmax / hpercenthealth, max health and health percent
mana / manamax / manapercentmana, max mana and mana percent
cap / maxcap / freecapcapacity, max capacity and free capacity
level / lvl / explevel, alias and experience points
mlev / mlevel / magicmagic level and its aliases
soulsoul points
speedwalk speed
staminastamina (seconds)
directionfacing direction (see Directions below)
pos / posx / posy / poszposition as a table or separate numbers
skullskull type (0 = none)
outfitcurrent outfit table
voc / vocationvocation name
blessings / blessesblessing count / bitfield
condition checksget

Each returns true/false — perfect for alarms and auto-reactions in your scripts.

hasHaste() · hasManaShield() · hasPz() · hasPzLock() · hasPzBlock() · hasSwords() · isInFight() · isInPz() · isInProtectionZone() · isBurning() · isBleeding() · isDrunk() · isEnergized() · isHungry() · isParalyzed() · isPoisioned()
-- refresh haste whenever it drops
macro(500, "autoHaste", function()
  if hpercent > 80 and not hasHaste() then
    say("utani hur")
  end
end)

Creatures

Find and inspect players, monsters and NPCs around you.

getSpectatorsget

Returns every creature visible around you — players, monsters and NPCs included.

getSpectators() → table of creatures
-- warn when an unknown player walks into your screen
macro(1000, "playerWatch", function()
  for _, c in ipairs(getSpectators()) do
    if c:isPlayer() and not c:isLocalPlayer() then
      zorbitLog("player nearby: " .. c:getName())
    end
  end
end)
getPlayerByName / getCreatureByName / getCreatureById / getDistanceBetweenget

Look up a specific creature by name or id, and measure distances between two positions.

getPlayerByName(name) → creature
getCreatureByName(name) → creature
getCreatureById(id) → creature
getDistanceBetween(posA, posB) → number
creature objectfields

Methods available on any creature you hold.

calldescription
:getName()creature name
:getHealthPercent()health percent (0–100)
:getPosition()position table {x, y, z}
:getDirection()facing direction
:isPlayer() / :isMonster() / :isNpc()kind checks
:isLocalPlayer()true for yourself
:isDead()dead flag

Items & containers

Search your inventory and open containers, count supplies and move items.

findItem / getInventoryItem / getSlotget

Find an item anywhere in open containers, or read a specific equipment slot. findItem(itemId) returns an item you can pass to use / usewith.

findItem(itemId) → item
getInventoryItem(slot) → item
getSlot(slot) → item
getContainers / getContainer / getPurseget

List every open container (or a specific one by index) and read your money pouch.

getContainers() → table
getContainer(index) → container
getPurse() → item
-- count strong health potions across all open backpacks
local function countPot(id)
  local n = 0
  for _, c in ipairs(getContainers()) do
    for _, it in ipairs(c:getItems()) do
      if it:getId() == id then n = n + it:getCount() end
    end
  end
  return n
end
zorbitLog("SHP left: " .. countPot(236))
moveToSlotset

Move an item into a specific equipment slot — e.g. swap amulets, rings or the ammo slot.

moveToSlot(item, slot) → bool
slot constantsconst

Equipment slots usable with getInventoryItem / moveToSlot.

InventorySlotHead · InventorySlotNeck · InventorySlotBack · InventorySlotBody · InventorySlotRight · InventorySlotLeft · InventorySlotLegs · InventorySlotFeet · InventorySlotRing · InventorySlotAmmo (= SlotAmmo) · InventorySlotPurse (= SlotPurse)

Map & movement

Walk, path and inspect tiles around you.

autoWalk / findPath / findAllPaths / getPathset

Walk somewhere with the client's pathfinder, or plan first and decide later. findAllPaths returns several alternatives; translateEveryPathToPath / translateAllPathsToPath normalize path formats.

autoWalk(pos) → bool
findPath(from, to) → path
findAllPaths(from, to) → table of paths
getPath(from, to) → path
-- walk to the depot one screen away
autoWalk({ x = posx + 8, y = posy - 6, z = posz })
turnset

Turn your character in place without stepping.

turn(dir) → bool
Directionsconst

Numeric directions for turn, direction fields and path steps.

North = 0 · East = 1 · South = 2 · West = 3 · NorthEast = 4 · SouthEast = 5 · SouthWest = 6 · NorthWest = 7
g_map tile infoadvanced

For deeper checks, the client's map module is available: g_map.getTile(pos) (then tile:getThings(), tile:getTopCreature(), tile:isWalkable()) and g_map.isSightClear(from, to) to see if a straight shot is unobstructed.

g_map.getTile(pos) → tile
g_map.isSightClear(fromPos, toPos) → bool

Actions

Everything your character can actively do — from scripts or macros.

say / saySpellset

say(text) speaks on the default channel; saySpell(text) is the spell-flavored variant that respects the spell timeout.

say(text) → void
saySpell(text) → void
use / usewith / useRuneset

Use an item, use it on a target, or throw a rune at a creature.

use(item | thing, subtype?) → void
usewith(item, target, subtype?) → void -- alias useWith
useRune(itemId, target) → void
-- emergency SMP from the script layer
local smp = findItem(237)
if smp then use(smp) end

-- throw an SD at your current target
useRune(3155, target)
attack / follow / cancel*set

Combat control — attack a creature, follow a player, and cancel either or both.

attack(creature) → bool
follow(creature) → bool
cancelAttack() · cancelFollow() · cancelAttackAndFollow()
logout / safeLogout / canLogoutset

Leave the game when you decide to — safeLogout waits for a safe moment, canLogout tells you whether the server allows it right now.

canLogout() → bool
logout() · safeLogout()
doScreenshot / screenshotset

Save a screenshot of the client window — nice for level-up moments or evidence after a bug.

doScreenshot() → void -- alias screenshot

Events

React to the game as it happens: assign a function to any of these callbacks. Events arrive on the client thread — keep handlers short and wrap risky work in pcall.

player eventsevent
calldescription
onPlayerHealthChangeyour HP changed (heals and damage)
onManaChangeyour mana changed
onPlayerPositionChangeyou stepped or teleported
onPlayerInventoryChangean equipment slot changed
onStatesChangeicon states changed (poison, burning, PZ…)
onSpellCooldown / onGroupSpellCooldownspell cooldown started
onAttackingCreatureChangeyour attack target changed
onTurn / onWalkyou turned or completed a step
onUse / onUseWithan item use happened
creature eventsevent
calldescription
onCreatureAppeara creature entered your view
onCreatureDisappeara creature left your view
onCreatureHealthPercentChangea creature's HP% changed
onCreaturePositionChangea creature moved
chat & UI eventsevent
calldescription
onTalkanyone spoke in any channel
onTextMessageserver text messages (loot, info, warnings)
onChannelEvent / onOpenChannel / onCloseChannel / onChannelListchannel lifecycle
onGameEditTextreadable text windows (books, letters)
onModalDialogNPC dialogs / server dialogs
onAnimatedText / onStaticText / onMisslefloating texts and projectiles
container, input & market eventsevent
calldescription
onContainerOpen / onContainerClose / onContainerUpdateItembackpack lifecycle and item updates
onAddItem / onRemoveItem / onAddThing / onRemoveThingthings appearing or vanishing on tiles
onKeyDown / onKeyPress / onKeyUpkeyboard events
onMarketBrowse / onMarketReadOffermarket data
onImbuementWindow / onImbuementItem / onOpenImbuementWindow / onCloseImbuementWindowimbuement dialog data
-- auto-responder for the NPC trade phrase
function onTalk(name, level, mode, text, channelId, pos)
  if text == "hi" and name == "Jack Staff" then
    schedule(600, function() say("trade") end)
  end
end

Scheduling & storage

Repeat work, delay it, and keep values between ticks and sessions.

macro / schedule / scheduleEvent / removeEventset

macro(timeout, name, fn) runs fn every timeout ms — the heartbeat of most scripts (it also appears on the dashboard as a toggleable hotkey entry). schedule(ms, fn) fires once. removeEvent cancels a scheduled event.

macro(timeoutMs, name, callback) → handle
schedule(delayMs, callback) → void -- alias scheduleEvent
removeEvent(handle) → void
-- every 2 s: log stamina drops below 14 h
macro(2000, "staminaWatch", function()
  if stamina > 0 and stamina < 14 * 3600 then
    zorbitLog("stamina low!")
  end
end)
delay / now / timeget

delay(ms) sleeps the current coroutine, now() / time() give you current engine and wall-clock timestamps.

delay(ms) · now() → number · time() → number
hotkey / singlehotkey / listenset

Register your own hotkeys inside the bot's hotkey panel: hotkey(text, fn) adds a switch, singlehotkey fires once per press, listen taps chat lines.

hotkey(label, callback) → handle
singlehotkey(label, callback) → handle
listen(text, callback) → void
storage / saveConfiggetset

storage is a free-form Lua table that survives script restarts and is autosaved with the bot config. Call saveConfig() to force a save.

storage.myTable = { tries = 3 }
saveConfig() → void
-- remember the last deposit position between sessions
storage = storage or {}
storage.lastDepot = storage.lastDepot or { x = 0, y = 0, z = 0 }
zorbitLog("last depot: " .. storage.lastDepot.x)
zorbitStorageWrite / zorbitStorageReadsetget

The bot's own session key–value store — values live in memory for the current session only.

zorbitStorageWrite(key, value) → bool
zorbitStorageRead(key) → string
zorbitGetExtra / zorbitSetExtragetset

Key–value pairs persisted with the bot settings — a permanent place for your script's options.

zorbitGetExtra(key) → string
zorbitSetExtra(key, value) → void

Healbot

Two layers: quick band rules (legacy, simplest) and the priority list the Healbot window edits.

zorbitAddRuleset

Adds a spell rule for kind "heal" or "mana". The spell fires when HP (or MP) drops below maxPct; minPct is the lower band edge. Cooldown is in milliseconds (default 1000).

zorbitAddRule(kind, minPct, maxPct, spell, cooldownMs) → bool
zorbitAddRule("heal", 0, 70, "exura gran mas res", 1000)
zorbitAddRule("mana", 0, 60, "utani gran hur", 1000)
zorbitGetRules / zorbitClearRulesgetset

Read or clear the band rules for "heal" / "mana". zorbitGetRules returns one rule per line, e.g. 0-70%: exura gran mas res.

zorbitGetRules(kind) → string
zorbitClearRules(kind) → bool
zorbitHealGetRules / zorbitHealSetRulesgetset

The full priority list behind the Healbot window — one row per line, in priority order (line 1 fires first). Each row: trig|mode|value|kind|action|cooldown|manaCost, where trig is hp|mp, mode is b (below) or a (above), kind is spell|item, and action is the spell words or the item id.

zorbitHealGetRules() → string
zorbitHealSetRules(rows) → bool
-- hp below 70% → cast exura gran mas res (1 s cooldown, 20 mana)
local rows = "hp|b|70|spell|exura gran mas res|1000|20\n" ..
             "hp|b|50|item|266|1000|0"
zorbitHealSetRules(rows)

Cavebot & waypoints

Build routes programmatically and read them back.

zorbitAddWaypointset

Appends a waypoint to the active profile. Returns false for invalid arguments (e.g. a 0,0,0 position).

zorbitAddWaypoint(kind, x, y, z, text) → bool
paramdescription
kind"node" / "stand" — walk to (or stand at) x, y, z · "say" says text · "goto" jumps to a labelled waypoint · "delay" waits x milliseconds
x, y, zcoordinates for node/stand; for delay only x (ms); ignored for say/goto
textchat text for say, waypoint label for goto
local x, y, z = zorbitGetPos()
zorbitAddWaypoint("node", x, y, z)
zorbitAddWaypoint("stand", x + 3, y, z)
zorbitAddWaypoint("say", 0, 0, 0, "hi")
zorbitAddWaypoint("delay", 2000)
zorbitGetWaypoints / zorbitClearWaypointsgetset

zorbitGetWaypoints() returns a numbered list, one waypoint per line ("1. Stand 32310,32220,7"). zorbitClearWaypoints() empties the route and resets the cavebot index.

zorbitGetWaypoints() → string
zorbitClearWaypoints() → bool

Loot list

Item IDs the bot should pick up.

zorbitAddLootId / zorbitGetLootIds / zorbitClearLootIdsgetset

Manage the loot ID list. IDs come back as a comma-separated string.

zorbitAddLootId(itemId) → bool
zorbitGetLootIds() → string -- e.g. "266, 237"
zorbitClearLootIds() → bool
zorbitAddLootId(3031) -- gold coin
zorbitAddLootId(3035) -- platinum coin

Alarms

17 alarms with sounds and anti-GM detection. Each alarm has a key, an on/off flag and a numeric parameter (threshold, seconds, item id…).

zorbitAlarmGetget

Returns the state of every alarm as rows of key|on|param — handy to snapshot and restore configurations.

zorbitAlarmGet() → string
zorbitAlarmSetset

Sets one alarm. Important: pass on as a number (1/0), not a boolean. The param meaning depends on the alarm (see the table below).

zorbitAlarmSet(key, on, param) → bool
zorbitAlarmSet("hp", 1, 50)   -- low health alarm at 50%
zorbitAlarmSet("posc", 1, 0)  -- player on screen: on
zorbitAlarmNotifyset

Fires the sound of an alarm right now — useful for custom triggers in your scripts.

zorbitAlarmNotify(key) → bool
zorbitAlarmTestset

Plays the alarm's sound like zorbitAlarmNotify but bypasses the enabled check — handy for testing volumes.

zorbitAlarmTest(key) → bool
zorbitAlarmSetFriends / zorbitAlarmSetCmsgset

setFriends takes a comma-separated whitelist — names on it are not counted as enemies (the "enemy" alarm ignores them). setCmsg sets the phrase the Custom message alarm watches for in default chat.

zorbitAlarmSetFriends(csvNames) → bool
zorbitAlarmSetCmsg(phrase) → bool
zorbitAlarmSetFriends("Tankmaster, Bestfriend")
zorbitAlarmSetCmsg("sell")
keyalarmparam
"disc"Disconnected—
"dmg"Damage taken—
"hp"Low healthHP % threshold
"mp"Low manaMP % threshold
"cap"Low capacitycapacity threshold
"pm"Private message—
"dmsg"Default message—
"cmsg"Custom messagephrase via zorbitAlarmSetCmsg
"posc"Player on screen—
"mosc"Monster on screen—
"stuck"Player stuckseconds without movement
"skull"Player with skull—
"gm"GM detected—
"gmitem"Detect IDitem id watched in the viewport
"gmtp"Teleport detect—
"enemy"Enemy (not on the friends list)—
"flash"Flash client taskbar—

Conditions

Extra reactions with a switch, threshold and option each.

zorbitCondGetget

Returns every condition as rows of key|on|param|opt — the keys match the Conditions window.

zorbitCondGet() → string
zorbitCondSetset

Sets one condition. Pass on as a number (1/0). Valid keys are whatever zorbitCondGet() lists for your version.

zorbitCondSet(key, on, param, opt) → bool

Friend Healer

Healing rules for other players — party and friends.

zorbitFHGetget

Returns the Friend Healer state — rule rows, healing mode and the friends list — as CSV.

zorbitFHGet() → string
zorbitFHSetset

Sets one Friend Healer entry (switch, rule parameter or option). Pass on as a number (1/0); keys match zorbitFHGet() output.

zorbitFHSet(key, on, param, opt) → bool

Scripts & files

Drive the Scripts module from code and keep small session values.

zorbitListScripts / zorbitReadScript / zorbitExecScript / zorbitOpenScriptsFoldergetset

Work with files from Documents\ZorbitBot\scripts\: list them, read a source, execute one by name, or open the folder in Explorer.

zorbitListScripts() → list
zorbitReadScript(name) → string
zorbitExecScript(name) → bool
zorbitOpenScriptsFolder() → void
zorbitExecScript("hunt_rotworms")
zorbitLogset

Writes a line to the bot log — your best friend while debugging scripts.

zorbitLog(message) → void

Settings & extras

Persistence and user key–value extras.

zorbitSaveSettings / zorbitLoadSettings / zorbitOpenSettingsFoldersetget

Force-save the current profile, reload settings from disk, or open the settings folder in Explorer.

zorbitSaveSettings() → void
zorbitLoadSettings() → void
zorbitOpenSettingsFolder() → void
zorbitStartCaptureadvanced

Starts key capture for the settings window's hotkey fields — the next key (or mouse-wheel move, for kind "MW") is recorded; Escape cancels. Normally driven by the settings UI itself.

zorbitStartCapture(kind) → bool

Script UI helpers

Build a quick control panel for your script — switches, buttons and labels land in your script's own panel in the bot UI.

addSwitch / addButton / addLabel / addTextEdit / addSeparator / addTab / addIconset

One call per widget — no layout math. Switches and buttons take callbacks; addTab groups widgets on a named tab.

addSwitch(text, onChange, on)
addButton(text, onClick)
addLabel(text)
addTextEdit(text, onChange)
addSeparator()
addTab(name)
addIcon(itemId, onClick)
local extraHeal = false
addSwitch("Extra heal", function(on) extraHeal = on end, false)
addButton("Reset loot list", function()
  zorbitClearLootIds()
  zorbitLog("loot cleared")
end)
setupUI / importStyle / displayGeneralBoxadvanced

setupUI(ui, parent) builds a whole UI from a table definition, importStyle(name) loads an extra OTUI style, and displayGeneralBox pops a Tibia-style message box.

setupUI(uiDef, parent) → widget
importStyle(name) → bool
displayGeneralBox(title, message, buttons) → void

UI Kit (advanced)

The library the bot's own windows are built with — use it to add Tibia-styled widgets to your script windows. Widget work must happen in the bot's UI context; keep it simple and pcall everything.

zorbitKitadvanced
calldescription
zorbitKit.window(id, w, h)creates a miniwindow docked in the client's panel
zorbitKit.panel(parent, w, h, bg, x, y)opaque panel
zorbitKit.button(parent, text, x, y, w, h, onClick)button with client styling
zorbitKit.label(parent, text, color, x, y, w, h)text label
zorbitKit.edit(parent, text, x, y, w)single-line text edit
zorbitKit.vscroll(parent, x, y, w, h, onValue)vertical scrollbar (13 px, Tibia-like)
zorbitKit.radio(parent, text, x, y)round radio/checkbox — read with :zorbitGet(), set with :zorbitSet(on)
zorbitKit.dim(w, dim)enable/disable + fade a widget (grey-out)
zorbitKit.place(w, x, y)absolute placement helper
zorbitKit.make({names}, parent)creates widgets from client style names with fallbacks
zorbitKit.importStyles()imports the bot's embedded styles once per session (called automatically)
local win = zorbitKit.window("myScriptWin", 220, 120)
local btn = zorbitKit.button(win, "Loot+", 10, 30, 80, 22, function()
  zorbitAddLootId(3031)
  zorbitLog("gold coin added to loot")
end)

g_game / g_map bridge

The client's own game interface, proxied safely into your script. These are the low-level calls the bot modules themselves use — reach for them when the shortcuts above aren't enough.

g_game — most useful callsadvanced
calldescription
g_game.isOnline()true while logged into a character
g_game.getLocalPlayer()your LocalPlayer object (then :getHealth(), :getMana(), :getLevel(), :getFreeCapacity(), :getStamina(), :getSoul(), :getSpeed(), :getPosition(), :getInventoryItem(slot)…)
g_game.getCreatures()every creature known to the client
g_game.getContainers()all open containers
g_game.findItemInContainers(itemId, subType)first item matching the id (-1 = any subtype)
g_game.talk(text)say on the default channel
g_game.use(thing) / g_game.useWith(item, thing)use / use-on
g_game.useInventoryItem(id) / g_game.useInventoryItemWith(id, thing)use an inventory item directly
g_game.look(thing) / g_game.lookAt(pos, stack)look at things and ground objects
g_game.move(thing, toPos, count)move items between tiles/containers
g_game.walk(dir) / g_game.turn(dir) / g_game.stop()movement control
g_game.attack(creature) / g_game.follow(creature)combat & follow
g_game.cancelAttack() / g_game.cancelFollow() / g_game.cancelAttackAndFollow()stop combat / following
g_game.isAttackingAlive() / g_game.isFollowing()current combat state
g_game.open(thing) / g_game.openParent(container)open containers and corpses
g_game.getPing() / g_game.getWorldName()connection info
other client modulesadvanced

Beyond g_game and g_map, the proxied context exposes g_ui (create widgets), g_keyboard (bind hotkeys), g_settings, g_resources, g_sounds, g_things and modules (all loaded client modules). Power-tools: handle with care and pcall everything.

g_ui.createWidget(style, parent)
g_keyboard.bindKeyPress(key, fn)
modules.game_console -- …and every other client module

Recipes

Three complete scripts you can paste into Documents\ZorbitBot\scripts\ and run right away.

panic_button.lua

A hotkey that stops everything and plays the alarm — for when you come back to a surprise.

-- stops the bot and screams when you press the "PANIC" hotkey
singlehotkey("PANIC", function()
  zorbitMasterToggle(false)
  cancelAttackAndFollow()
  zorbitAlarmNotify("gm")
  zorbitLog("PANIC — bot stopped, target cleared")
end)
supply_watch.lua

Counts your potions every 5 s, logs a warning and flashes the taskbar when you run low.

local function countPot(id)
  local n = 0
  for _, c in ipairs(getContainers()) do
    for _, it in ipairs(c:getItems()) do
      if it:getId() == id then n = n + it:getCount() end
    end
  end
  return n
end

macro(5000, "supplyWatch", function()
  if countPot(266) < 10 then
    zorbitLog("LOW SUPPLIES: strong health potions!")
    zorbitAlarmNotify("cap")
  end
end)
safe_spots.lua

Switches to profile 2 (a safe, passive setup) whenever an unknown player appears on screen, and back when the screen is clear.

macro(1500, "safeSpot", function()
  local intruder = false
  for _, c in ipairs(getSpectators()) do
    if c:isPlayer() and not c:isLocalPlayer() then
      intruder = true
      break
    end
  end
  if intruder and zorbitGetProfile() ~= 2 then
    zorbitSetProfile(2)
    zorbitLog("player detected — safe profile ON")
  elseif not intruder and zorbitGetProfile() == 2 then
    zorbitSetProfile(1)
    zorbitLog("screen clear — normal profile ON")
  end
end)