How To Call It
VisualTarget is a global table: call its functions with a dot (VisualTarget.<method>(...)), not a colon.
Rebuilds the profile with new name, views or options; the tracked state is kept when the stateKey is unchanged.
Documented for app version 1.0.51Updated:
VisualTarget is a global table: call its functions with a dot (VisualTarget.<method>(...)), not a colon.
In detection flow, refresh the screen with Snap.screenRefresh() first, then narrow the search area and confidence using Region and FindParam.
Required: previous, name, views. Optional: options (omit to pass nil and use the runtime default). Returns a Lua table.
profile(name, views, options): views holds 1-32 views; each view is { name, template } or { name, matcher = function } with an optional findParam. Options: engine (default "hybrid"), acquireThreshold (0-1, default 0.82), retainThreshold (at most acquireThreshold, default 0.72), maxDriftPx (default 160), lostFrameLimit (1-120, default 4), reacquire (default true), movementThresholdPx (default 4), stillFrameLimit (1-120, default 3), adaptiveScan (default true), maxCandidatesPerView (1-16, default 8), findParam and stateKey. step returns a copy of the state: found, status ("acquired", "tracking", "moving", "still", "reacquired", "searching", "lost" or "error"), x, y, w, h, centerX, centerY, score, viewIndex, viewName, velocityX, velocityY, moving and lostFrames.
It is typically combined with Snap, Region, Asset, and FindParam; you can feed the result into quickTap(), click(), or a follow-up OCR step.
The snippet below is a starter pattern that can be applied directly in runtime flow.
local profile = VisualTarget.profile("enemy", { { name = "front", template = Asset.image("enemy_front") } })
local result = VisualTarget.refresh(profile, "enemy", { { name = "front", template = Asset.image("enemy_front") } })From foundation to combined usage, each level is provided as a separate code block so you can copy the level you need and adapt it directly.
local profile = VisualTarget.profile("enemy", { { name = "front", template = Asset.image("enemy_front") } })
local result = VisualTarget.refresh(profile, "enemy", { { name = "front", template = Asset.image("enemy_front") } })local stepOk = true
local profile = VisualTarget.profile("enemy", { { name = "front", template = Asset.image("enemy_front") } })
local result = VisualTarget.refresh(profile, "enemy", { { name = "front", template = Asset.image("enemy_front") } })
if stepOk then
wait(200)
endlocal ok, err = pcall(function()
local profile = VisualTarget.profile("enemy", { { name = "front", template = Asset.image("enemy_front") } })
local result = VisualTarget.refresh(profile, "enemy", { { name = "front", template = Asset.image("enemy_front") } })
end)
if not ok then
print("API step failed: VisualTarget.refresh: " .. tostring(err))
requestStop()
end-- In detection flow, refresh the screen with Snap.screenRefresh() first, then narrow the search area and confidence using Region and FindParam.
local function run_refresh_step()
local profile = VisualTarget.profile("enemy", { { name = "front", template = Asset.image("enemy_front") } })
local result = VisualTarget.refresh(profile, "enemy", { { name = "front", template = Asset.image("enemy_front") } })
end
local ok, err = pcall(run_refresh_step)
if not ok then
toast("Step failed")
print(err)
end-- Follow a moving target and tap it while it is visible
local profile = VisualTarget.profile("enemy", {
{ name = "front", template = Asset.image("enemy_front") },
{ name = "side", template = Asset.image("enemy_side") },
}, { acquireThreshold = 0.85 })
local area = Region()
for frame = 1, 20 do
local state = VisualTarget.step(profile, area)
if state.found and state.status ~= "moving" then
VisualTarget.click(profile)
elseif state.status == "lost" then
break
end
wait(150)
end