Gatherer/ is the bot: automated herbalism, mining, and fishing across expansions, driven by per-expansion node databases.
The settings UI, status text, minimap messages, and chat-facing labels display LootRoute. Internal APIs, files, config keys, and bot route/data roots still use
Gatherer / gatherer.*; framework profile and status-frame persistence now live under scripts/LootRoute/ with legacy reads from the old paths.Features
- Route following with node blacklisting/whitelisting and in-game route recording.
- Combat handling: threat and elite avoidance, melee chase for ranged attackers, flee, death and Spirit Healer recovery, mob looting and wild-node corpse harvesting.
- Flight and skyriding support (overload and vigor charges).
- Quality-of-life tasks: mailing, repair/sell, guild bank, and inn/hearthstone.
- Consumables: phials, potions, teas, foods, tool enhancements, and knowledge items, deferred while combat or nearby enemies would make item use unsafe.
- In-game settings UI with per-character settings and an optional
volvox.Theme-colored on-screen status frame.
Two layers
Framework layer
Module.lua, ModuleActions.lua, Gui.lua, GuiTabs.lua — register the bot with volvox, declare all gatherer.* config defaults, own the status frame and route/blacklist methods, and build the settings UI with volvox.GuiBuilder.Bot core
Core.lua through Routine.lua — the gathering logic, almost entirely globals over shared global state. Loads after the framework because it reads volvox.Gatherer, volvox.Config, and the GUI/toggle helpers.updateType = "none" because the core drives itself with self-rescheduling C_Timer loops rather than the frame callbacks.
Execution order is load-bearing
The bot core (Core → Routine) was originally one monolithic Gatherer.lua file, now sliced into contiguous files that execute top-to-bottom in load order. At file scope it mixes:
- Global function definitions (
scan(),Routine(), …). - Large top-level data/state initialization (node databases,
KPNodeIDs, the position/status state block, profession tables). - Roughly twenty immediate bootstrap calls that kick off self-rescheduling
C_Timerloops (Fishi(),nodecheck(),fight(),Routine(), frame/event creation) — the real driver of the bot.
loadorder.json.
File-scoped
locals are upvalues, not globals. A local and its callers must live in the same file, or the value gets promoted to volvox.Gatherer<PascalCaseName> in the file where it was local (for example volvox.GathererGuiCategory in Gui.lua).Shared tables
Gatherer/Module.lua publishes two global tables that give cross-file code a single source of truth:
GathererState— exact state/status string constants for the state machine.GathererConfigKeys— maps each short key (the part aftergatherer.) to its full dotted config key, e.g.GathererConfigKeys.enabled == "gatherer.enabled".GathererModule:GetSetting(key, default)and:SetSetting(key, value)resolve short keys through this table and read/write viavolvox.Config.
Module actions
Gatherer/ModuleActions.lua provides the route and blacklist methods on volvox.Gatherer:
| Method | Purpose |
|---|---|
:Start() | Start the bot — sets status to RUN/IDLE, persists enabled |
:Stop() | Stop the bot — pauses, halts navigation, clears the object cache, persists disabled |
:ApplyExpansion(expansion) | Point the node database globals at the active expansion tables |
:SaveWaypoint() | Legacy waypoint append helper; prefer route recording for valid route JSON |
:StartRouteRecording() | Begin recording a new route (configured name and radius) |
:AddRouteWaypoint() | Add the current position to the in-progress recording |
:SaveRecordedRoute() | Write and verify the recorded route on disk, then select and load it |
:StopRouteRecording() | Stop the in-progress recording |
:LoadRoute(routeName) | Load a route’s JSON from disk into module and bot-core globals |
:ClearRoute() | Clear the loaded route and reset the current index |
:BlacklistAdd() / :WhitelistAdd() | Append the player’s position to Blacklist.json / Whitelist.json |
:BlacklistCurrentTargetGUID() | Blacklist the current target node by GUID |
:RefreshRoutes() | Scan the route directory; returns sorted { text, value } dropdown entries |
Next steps
State machine
The
Status / State globals and the Routine() dispatcher.Configuration
Every
gatherer.* config key and its default.Routes and data
Route files, blacklists, and node databases.
File map
Per-file responsibilities in load order.
.png?fit=max&auto=format&n=yZatCT6YQ7S22QWv&q=85&s=bb502db827d4362d1268445c3b70d21d)