Skip to content

Module Development

A module gets its “decide” and “act” from three parts: properties, scripts and macros. We cover their relationship first, then module structure, decision scripts, hotkeys, properties and the editing flow.

Properties, Scripts, Macros: The Three Parts

Section titled “Properties, Scripts, Macros: The Three Parts”

A module that auto-cycles relies on three parts working together:

  • Property (input): brings an in-game value or state back to the desktop — health, cooldown, buff time left, and so on.
  • Script (decision): a desktop-side Lua script that reads properties, decides, and picks which spell to cast this instant. It is the module’s brain.
  • Macro (action): each macro is a piece of in-game macro text (e.g. /cast SpellName) bound to a hotkey; the script calls it to fire that spell.

At runtime you hold the start key and the app repeatedly runs your bound script at the APM pace; each pass the script calls the right macro based on current property values.

Part Description
Macros (150 rows) There are 150 slots. The first 105 support static macros or names and bodies generated by initialization code, using the configured hotkeys. The last 45 are reserved for target selection.
Lua scripts (50 rows) Reusable logic snippets, bound to a mouse button or hotkey to run.
Properties (90 rows) Bring one in-game value/state back to the desktop. One property per row — the inputs to your module’s decision logic.
Property library A module-local template library with 25 base templates; the editor adds native aura fields. Rows can reference library entries, whose built-in labels follow the selected language.
Class / name / version The class tag is for filtering; the version auto-increments on each save and is sent back to the game to prompt a reload when out of sync.

All hotkeys are sent by the program — you never press them — so the layout is designed to resist physical modifier-key overlap, not for ergonomics. The default table uses 30 main keys × 5 prefixes = 150 rows, split into three non-overlapping key domains:

  • Macros 1–50: NUMPAD domain
  • Macros 51–90: punctuation domain (, . / ; ' [ ] =)
  • Macros 91–105 and SelectTarget: F-key domain (F1–F12)

The default template uses these five modifier combinations. Dynamic macros keep their slot hotkeys; configure valid, distinct bindings in the editor.

ALT-SHIFT-x CTRL-SHIFT-x SHIFT-x CTRL-x ALT-x
  • Open: click “Module Editor” in the settings window; you edit a copy of the currently selected module.
  • Save: click Save or press Ctrl+S (works even while editing a cell). Saving requires login; the module is encrypted and uploaded, and the editor closes on success.
  • Clone: save the current content as a brand-new module (name gets a “clone” suffix).
  • Import / Export: back up or share a module locally via a .wa1 file. The export is clean plaintext JSON — edit it in a text editor or with an AI and import it back; an imported module is given a fresh identity and won’t overwrite anyone’s cloud entry.
  • Unsaved guard: closing, creating new, or importing with pending changes prompts for confirmation.
  • Parameter hints: hover a parameter cell in a property row to see its type and the allowed values written in the leading comment of that code (built-in entries list every unit ID, power type and so on). Describe parameters in a leading -- comment of your own code and they show up the same way.
  • Check and indent on save: “Save” in the logic and custom-code editors checks first (logic runs in an isolated client engine, game-side code is only compiled), then re-indents the code by block structure before saving. “Run Local Check” only checks and leaves the text untouched.

Each property row has a “property” dropdown that sets one of three states:

State Meaning
Off Empty placeholder row; not generated, not reported.
Custom code This row runs your own Lua. Giving the property a name enables it automatically.
Library entry References a template in the library, bringing in its code and default parameters; clicking “Edit” and changing the code detaches it into custom code.

The “parameters” column takes up to 3 comma-separated segments, injected as arg1 / arg2 / arg3: numeric segments pass through as numbers, others as strings, empty as nil. The same code reused with different parameters (e.g. player vs target).