How To Call It
VisualTarget is a global table: call its functions with a dot (VisualTarget.<method>(...)), not a colon.
Creates a profile table holding one or more views of a target (for example front and side) and its tracking settings.
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: 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") },
{ name = "side", template = Asset.image("enemy_side") },
}, { acquireThreshold = 0.85 })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") },
{ name = "side", template = Asset.image("enemy_side") },
}, { acquireThreshold = 0.85 })local stepOk = true
local profile = VisualTarget.profile("enemy", {
{ name = "front", template = Asset.image("enemy_front") },
{ name = "side", template = Asset.image("enemy_side") },
}, { acquireThreshold = 0.85 })
if stepOk then
wait(200)
endlocal ok, err = pcall(function()
local profile = VisualTarget.profile("enemy", {
{ name = "front", template = Asset.image("enemy_front") },
{ name = "side", template = Asset.image("enemy_side") },
}, { acquireThreshold = 0.85 })
end)
if not ok then
print("API step failed: VisualTarget.profile: " .. 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_profile_step()
local profile = VisualTarget.profile("enemy", {
{ name = "front", template = Asset.image("enemy_front") },
{ name = "side", template = Asset.image("enemy_side") },
}, { acquireThreshold = 0.85 })
end
local ok, err = pcall(run_profile_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