MacroAI API Reference
Image Recognition
image_find(tmpl, region?, threshold?) -> ImageMatchResult | nil
image_wait(tmpl, timeout?, region?, threshold?) -> ImageMatchResult | nil
image_find_all(tmpl, region?, threshold?) -> table | nil
image_wait_all(tmpl, timeout?, region?, threshold?) -> table | nil
image_save_template(img, path) -> void
Parameters:
- tmpl (string) — template image filename (e.g. "button.png"), must be uploaded in Image Manager; also supports variable references (e.g. var_get('btn_name')) or function parameter names
- region (table, optional) — search area {left, top, width, height}, defaults to full screen
- threshold (number, optional) — match threshold 0~1, default 0.85, lower = more tolerant
- timeout (number, optional) — timeout in seconds, default 10
- img — image data (numpy array)
Return Value (ImageMatchResult):
- .success (boolean) — whether found
- .x, .y (number) — top-left corner of match
- .center_x, .center_y (number) — center of match
- .width, .height (number) — match dimensions
- .confidence (number) — confidence score
- .rect (table) — {left, top, width, height}
- .template_name (string) — the matched template filename (useful in multi-template search to identify which template matched)
Example:
local r = image_find("login_btn.png", {100, 200, 800, 600}, 0.8)
if r and r.success then
mouse_click(r.center_x, r.center_y)
end
Returning all matches:
image_find_all(tmpl, region?, threshold?) -> table | nil
image_wait_all(tmpl, timeout?, region?, threshold?) -> table | nil
- Returns a table (array) of all match results, or
nilif no matches found - Each element has the same fields as
ImageMatchResult - Useful when multiple instances of the same template exist on screen
image_wait_allpolls until at least one match is found, then returns all matches
Example (find and click all matches):
local results = image_find_all("icon.png")
if results then
for _, r in ipairs(results) do
mouse_click(r.center_x, r.center_y)
wait(500) -- pause between clicks
end
end
Multi-template example:
local r1 = image_find("btn_ok.png", nil, 0.85)
local r2 = image_find("btn_cancel.png", nil, 0.85)
local best = nil
local best_conf = 0
for _, r in ipairs({r1, r2}) do
if r and r.success and r.confidence > best_conf then
best = r
best_conf = r.confidence
end
end
if best then
if best.template_name == "btn_ok.png" then
-- OK button found
else
-- Cancel button found
end
end
OCR
ocr_recognize(region?, lang?) -> string
ocr_compare(text, region?, threshold?, lang?) -> OcrCompareResult
ocr_find_text(text, region?, lang?) -> number, number
ocr_log(msg) -> void
Parameters:
- region (table, optional) — recognition area {left, top, width, height}, defaults to full screen
- lang (string, optional) — language code, e.g. "zh-CN", "en-US", defaults to system language
- text (string) — text to match
- threshold (number, optional) — similarity threshold, default 0.8
- msg (string) — log message
Return Value (OcrCompareResult):
- .matched (boolean) — whether text matched
- .found_text (string) — recognized text
- .similarity (number) — similarity score
- .confidence (number) — confidence score
ocr_find_text returns:
- Success: center_x, center_y (number, number)
- Failure: nil, nil
Example:
local text = ocr_recognize({100, 100, 500, 100}, "en-US")
ocr_log("Recognized: " .. text)
local r = ocr_compare("Submit", {100, 100, 500, 100})
if r and r.matched then
log("Match found, similarity: " .. r.similarity)
end
local x, y = ocr_find_text("OK", {100, 100, 500, 100})
if x then mouse_click(x, y) end
Mouse
mouse_click(x?, y?, button?, clicks?) -> void
mouse_move(x?, y?) -> void
mouse_double_click(x?, y?) -> void
mouse_right_click(x?, y?) -> void
mouse_scroll(clicks, x?, y?) -> void
mouse_drag(sx, sy, ex, ey, button?, duration?) -> void
Parameters:
- x, y (number, optional) — screen coordinates, uses current position if omitted
- button (string, optional) — mouse button: "left" (default), "right", "middle"
- clicks (number) — scroll wheel clicks, positive = up, negative = down
- sx, sy (number) — drag start point
- ex, ey (number) — drag end point
- duration (number, optional) — drag duration (seconds), default 0.3
Example:
mouse_click(500, 300) -- left click at (500,300)
mouse_click(500, 300, "right") -- right click
mouse_double_click(500, 300) -- double click
mouse_move(100, 200) -- move to (100,200)
mouse_drag(100, 100, 500, 300) -- drag from (100,100) to (500,300)
mouse_scroll(3) -- scroll down 3 clicks
Keyboard
key_press(key) -> void
key_type(text) -> void
key_hotkey(key1, key2, ...) -> void
key_shortcut(combo) -> void
Parameters:
- key (string) — key name, e.g. "enter", "tab", "escape", "a", "ctrl"
- text (string) — text to type, newlines are converted to Enter
- key1, key2, ... (string...) — sequential key combination, e.g. ("ctrl", "c")
- combo (string) — shortcut notation, e.g. "ctrl+c", "alt+tab"
Example:
key_press("enter") -- press Enter
key_type("Hello, World!") -- type text
key_hotkey("ctrl", "c") -- Ctrl+C (sequential)
key_shortcut("ctrl+c") -- Ctrl+C (chord)
Screen
screen_capture(region?) -> Image (numpy array)
screen_size() -> width, height
Parameters:
- region (table, optional) — capture area {left, top, width, height}, defaults to full screen
Example:
local w, h = screen_size()
log("Screen resolution: " .. w .. "x" .. h)
local img = screen_capture({0, 0, 100, 100}) -- capture top-left 100x100
image_save_template(img, "screenshot.png")
Wait
wait(milliseconds) -> void
wait_seconds(seconds) -> void
Example:
wait(1000) -- wait 1000 ms (1 second)
wait_seconds(2.5) -- wait 2.5 seconds
Variables
var_set(name, value, scope?) -> void
var_get(name) -> any
var_has(name) -> boolean
Parameters:
- name (string) — variable name
- value (any) — variable value (string, number, boolean, table)
- scope (string, optional) — variable scope: "local" (default, script-local), "global" (shared across scripts)
Example:
var_set("count", 10)
var_set("name", "MacroAI", "global")
local c = var_get("count")
log("count = " .. c)
if var_has("name") then
log("name variable exists")
end
Regions
region_set(name, left, top, width, height) -> void
region_get(name) -> Region | nil
getRegion(name?) -> {left, top, width, height} | nil
to_runtime_region(region) -> {left, top, width, height}
to_runtime_point(x, y) -> number, number
Parameters:
- name (string) — region name
- left, top, width, height (number) — region rectangle (design-space coordinates)
- region (table) — {left, top, width, height} format
Notes:
- region_get returns a Region object with .left, .top, .width, .height properties
- getRegion returns a Lua table; omit name or use "__effective__" for the default search area
- to_runtime_region / to_runtime_point convert design-space coordinates to runtime (for multi-resolution support)
Example:
region_set("dialog", 100, 200, 500, 300)
local r = region_get("dialog")
if r then
log("Region: " .. r.left .. "," .. r.top)
end
local rt = getRegion("dialog") -- {left, top, width, height}
local eff = getRegion() -- default search area
local px, py = to_runtime_point(500, 300) -- convert to runtime coordinates
Change Detection
detect_change(kwargs?) -> table
wait_change(kwargs?) -> table
wait_bar_change(kwargs?) -> table
detect_change / wait_change Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
region |
table | full screen | detection area {left, top, width, height} |
block_size |
number | 50 | grid block size (pixels) |
threshold |
number | 30.0 | change threshold (grayscale diff) |
min_area |
number | 900 | minimum change area |
timeout |
number | 30 | timeout in seconds (wait_change only) |
interval |
number | 1.0 | poll interval in seconds (wait_change only) |
track_frames |
number | 10 | tracking frames for cyclic filtering (wait_change only) |
cyclic_ratio |
number | 0.7 | cyclic filter ratio (wait_change only) |
wait_bar_change Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
region |
table | full screen | detection area |
timeout |
number | 30 | timeout in seconds |
interval |
number | 0.5 | poll interval in seconds |
min_change |
number | 0.1 | minimum change ratio |
match_threshold |
number | 0.85 | template similarity threshold |
orientation |
string | "auto" | bar orientation: "horizontal", "vertical", "auto" |
reset |
boolean | false | reset all tracking (use when switching scenes) |
colors |
table[] | required | template configurations (see below) |
colors format:
{
{
label = "hp_full", -- template name (also filename)
template_path = "resources/bar_templates/hp_full.png",
color_swatch = {255, 50, 50} -- auto-computed, can omit
},
{
label = "hp_half",
template_path = "resources/bar_templates/hp_half.png",
color_swatch = {50, 50, 255}
}
}
Return Values:
- detect_change / wait_change return an array of changed regions:
lua
{
{ center_x = 350, center_y = 250, rect = {340, 240, 20, 20} },
...
}
- wait_bar_change returns an array of bar changes:
lua
{
{
rect = {100, 200, 300, 20}, -- bar bounding box
center_x = 250, -- bar center X
center_y = 210, -- bar center Y
color = "hp_full", -- matched template label
state = "changed", -- changed/resized/disappeared/appeared
delta = 0.5, -- width ratio change (new label / old label)
reference_value = 1.0, -- old label width ratio
curr_value = 0.5, -- new label width ratio
orientation = "horizontal"
},
...
}
Example:
-- Detect bar value change (upload two templates with different widths)
local bar_changes = wait_bar_change({
region = {100, 50, 300, 20},
timeout = 15,
colors = {
{
label = "full",
template_path = "resources/bar_templates/full.png",
},
{
label = "half",
template_path = "resources/bar_templates/half.png",
}
}
})
-- Filter: only process real changes, ignore enter/leave
for _, bc in ipairs(bar_changes) do
if bc.state == "changed" or bc.state == "resized" then
log("bar changed: " .. bc.color .. " delta=" .. bc.delta)
end
end
reset_bar_detector() -> void
Reset all bar tracking cache. Call before entering a new scene to prevent stale state from interfering.
| Parameter | Type | Description |
|---|---|---|
| none | - | - |
Example:
-- Reset tracking when entering a new scene
reset_bar_detector()
local bars = wait_bar_change({
region = {100, 50, 300, 20},
colors = {
{ label="full", template_path="resources/bar_templates/full.png" },
{ label="half", template_path="resources/bar_templates/half.png" },
}
})
Audio
play_warning(sound_type, custom_file?) -> void
play_music(filepath) -> void
is_music_playing() -> boolean
Parameters:
- sound_type (string) — sound type:
- System sounds: "ding", "error", "warning", "question", "info"
- Windows media: "startup", "shutdown", "chimes", "tada"
- Musical notes: "do", "re", "mi", "fa", "sol", "la", "si" (PC speaker beeps)
- Custom: "custom"
- custom_file (string, optional) — custom WAV file path (when sound_type is "custom")
- filepath (string) — music file path (supports MP3, WAV, etc.)
Example:
play_warning("ding") -- play ding sound
play_warning("custom", "C:\\alert.wav") -- play custom WAV
play_music("C:\\bgm.mp3") -- play background music
if is_music_playing() then
log("Music is playing")
end
Logging
log(message) -> void
ocr_log(msg) -> void
print(...) -> void
Example:
log("Script started")
ocr_log("OCR result: " .. text)
print("Values:", x, y, z) -- output: Values: 100 200 300
Other
macro_call(macro_id) -> void
Notes:
- macro_id (string) — recorded macro ID to replay
- Replays all recorded events (mouse clicks, key presses, waits, etc.)
- Coordinates are automatically scaled to fit the current run area
Example:
macro_call("macro_12345678") -- replay a recorded macro
Check Stop
check_stop() -> void
Call during long loops or long-running operations to make the script responsive to pause and stop signals. If the user clicks pause or stop during execution, check_stop() will immediately interrupt the current operation.
The engine automatically injects this call in some long-running operations, but it's recommended to call it explicitly in custom loops.
Example:
for i = 1, 100 do
check_stop() -- allow the user to abort at any time
-- perform operations...
wait(500)
end
Common Conventions
Coordinate System
- All coordinates are in pixels
- Region format:
{left, top, width, height} - Coordinates are automatically scaled between design area and run area (multi-resolution)
Return Value Convention
- Success returns a valid value, failure returns
nil - For
ImageMatchResult, checkif r and r.successto determine match status