Regions & Advanced Matching
Create search regions, chain matches, and extract specific screen areas.
The Region API allows you to explicitly define and manipulate areas of the screen. Instead of performing global searches, you can limit template matching and OCR operations to strict boundaries, significantly improving performance and reliability. Regions can also be chained together!
new Region(x, y, w, h)
Creates a new rectangular Region with precise coordinates in current device pixels.
// Create a region in the top left corner, 200px wide and 100px high
var r = new Region(0, 0, 200, 100);
Region.fromScene(sceneName)
Creates a region based on a bounding box drawn and saved in the visual editor, looked up by scene name or ID. This is automatically scaled to the current device's screen size. Only scenes resolve here — object names do not. Returns null when no scene matches, so check the result before using it.
// Get the bounds of the minimap as defined in the editor
var minimap = Region.fromScene("minimap_area");
Region.fullscreen()
Returns a Region that encompasses the entire device screen.
region.expand(pixels) / region.inset(pixels)
Returns a new Region expanded or shrunk by the given number of pixels in all directions. Useful for giving a search some "breathing room". Every modifier on this page returns a new Region — the one you called it on is left unchanged.
var r = Region.fromScene("health_bar").expand(20);
Don't inset past half.inset(n)wherenis at or beyond half the region's width or height produces a zero- or negative-size region, and the two consumers disagree about what to do with one: template, text and colour searches silently fall back to the full screen — the opposite of the narrowing you asked for — whileocr()returns"". Neither reports an error, so check the resultingw/hif the inset amount is computed rather than literal.
region.offset(dx, dy)
Returns a new Region shifted by the given x and y offsets. Useful for finding an element relative to a known landmark.
var titleMatch = Region.fullscreen().findText("Score:");
if (titleMatch) {
// Read the score directly to the right of the title text
var scoreText = titleMatch.offset(100, 0).ocr();
}
region.topHalf() / region.bottomHalf() / etc.
Quick geometry helpers that slice the current region in half. Includes topHalf(), bottomHalf(), leftHalf(), and rightHalf().
// Optimizes performance by only searching the bottom half of the screen
var btn = Region.fullscreen().bottomHalf().findObject("next_button");
All searches performed on a Region instance are strictly limited to its boundaries. These methods return a Match object or null.
region.findObject(objectName, options?)
Finds an image template within this region.
region.findAllObjects(objectName, options?)
Finds all instances of an image template within this region, returning an Array of Match objects.
region.ocr(options?)
Extracts all text directly inside this region's boundaries. Pass { numeric: true } to read it as a number (digit-confusion correction) or { binarize: true } to force thresholding — same options as the global ocr().
Returns string | null — recognized text, "" if empty, or null on failure. See ocr() for the distinction.
region.findText(query, options?)
Finds specific text within this region.
region.findColor(colorHex, options?)
Finds the first pixel matching the given color within this region.
region.findAllColors(colorHex, options?)
Finds all pixels matching the given color within this region, returning an array of Match objects. Accepts the same tolerance and maxResults options as the global findAllColors().
region.findColorRegions(colorHex, options?)
Groups adjacent matching pixels within this region into connected blobs, returning one Match per blob (bounding box + centroid). Accepts the same tolerance, minSize and maxResults options as the global findColorRegions().
region.findAllText(query, options?)
Finds all occurrences of the given text within this region via OCR, returning an array of Match objects. Accepts the same wholeWord and maxResults options as the global findAllText().
Every region-scoped method takes the same options as its global twin, as an options object — a bare value throws aTypeError. That includesregion.ocr()andregion.highlight(), which is where the region-scoped forms are stricter than the global ones:ocr("name", true)quietly reads with default settings, whileregion.ocr(true)throws. Your object is never modified: the region is added to a copy, so the same options object can be reused for an unscoped search afterwards.
region.waitForObject(objectName, options?)
Waits until an image template appears within this region. Equivalent to the global waitForObject() with a pre-scoped region. Returns a Match on success, or null if the timeout is reached.
| Option | Type | Default | Description |
|---|---|---|---|
timeout | number | 5000 | Maximum wait time in ms. |
interval | number | 500 | Polling interval in ms. |
threshold | number | 0.70 | Minimum match confidence (0–1). Values below 0.10 are clamped up to 0.10. |
matchTimeout | number | 0 | Per-attempt matching budget in ms. 0 means the engine's own 10-second budget, not unlimited. |
var panel = Region.fromScene("inventory_panel");
var item = panel.waitForObject("rare_sword", { timeout: 10000 });
if (item) item.tap();
region.waitForText(query, options?)
Waits until the given text appears within this region via OCR. Returns a Match at the found text on success, or null on timeout. A returned Match is truthy, so if (region.waitForText(…)) checks keep working.
| Option | Type | Default | Description |
|---|---|---|---|
timeout | number | 5000 | Maximum wait time in ms. |
interval | number | 500 | Polling interval in ms. |
wholeWord | boolean | false | Match whole words only. Returns a word-level box when the query matches a single recognized word; a multi-word query falls back to a whole-line box. |
var dialog = Region.fromScene("dialog_box");
if (dialog.waitForText("Are you sure?", { timeout: 8000 })) {
tapAt("confirm_button");
}
region.waitUntilGone(objectName, options?)
Waits until an image template disappears from this region. Returns true once gone, or false on timeout. Accepts the same options as region.waitForObject().
var loadingRegion = Region.fromScene("loading_spinner");
loadingRegion.waitUntilGone("spinner", { timeout: 15000 });
region.waitUntilTextGone(query, options?)
Waits until the given text disappears from this region via OCR. Returns true once gone, or false on timeout.
| Option | Type | Default | Description |
|---|---|---|---|
timeout | number | 5000 | Maximum wait time in ms. |
interval | number | 500 | Polling interval in ms. |
wholeWord | boolean | false | Match whole words only, as on region.findAllText(). |
var statusBar = Region.fromScene("status_bar");
statusBar.waitUntilTextGone("Loading...", { timeout: 10000 });
region.waitForColor(colorHex, options?)
Waits until a pixel matching the given color appears within this region. Equivalent to the global waitForColor() with a pre-scoped region. Returns a Match (1×1, at the found pixel) on success, or null on timeout.
| Option | Type | Default | Description |
|---|---|---|---|
tolerance | number | 15 | Maximum per-channel deviation 0–255. 0 = exact match. |
timeout | number | 5000 | Maximum wait time in ms. |
interval | number | 500 | Polling interval in ms. |
var bar = Region.fromScene("health_bar");
var low = bar.waitForColor("#FF0000", { tolerance: 20, timeout: 10000 });
if (low) print("health dropped into the red");
region.waitUntilColorGone(colorHex, options?)
Waits until no pixel matching the given color remains within this region. Returns true once gone, or false on timeout. Accepts the same options as region.waitForColor().
var indicator = Region.fromScene("loading_dot");
indicator.waitUntilColorGone("#FF0000", { tolerance: 20, timeout: 15000 });
region.highlight(options?)
Draws a temporary visual overlay box around the region on your screen, then clears it again. Extremely helpful for debugging your scripts to ensure you are searching exactly where you think you are.
| Option | Type | Default | Description |
|---|---|---|---|
duration | number | 2000 | How long the outline stays on screen, in ms. |
color | string | "#FF0000" | Outline color as a hex string. |
strokeWidth | number | 4 | Outline thickness in pixels. |
Any other canvas paint option (fill, alpha) works here too — they are passed straight through to canvas.drawRect().
Region.fromScene("health_bar").highlight({ duration: 2000, color: "#FF0000" });
This takes an options object, not positional arguments.highlight(2000)throws aTypeErrorrather than silently ignoring what you passed.
A Match represents a successful search. It extends Region, meaning a Match has its own width and height, and you can perform searches inside a match!
Match Properties
cx, cy | number | The exact center coordinate of the match. |
x, y, w, h | number | The bounding box of the match (inherited from Region). |
score | number? | Match confidence between 0.0 and 1.0. Always present, but only a real confidence on a match from findObject or findAllObjects (and their region-scoped forms). Every other producer — waitForObject included, along with all text and colour searches and promptPosition — sets a constant 1.0 placeholder, so don't branch on the score of a match you got any other way. |
text | string | undefined | The extracted text. Present only on a match from a text search (findText, findAllText, waitForText); undefined on object and color matches. |
match.tap() / match.longPress(options?)
Directly taps or long presses the center coordinates (cx, cy) of the match. Each returns boolean — true if the gesture was dispatched successfully — so findObject("x")?.tap() doesn't silently discard the result.
var inventory = Region.fullscreen().findObject("inventory_panel");
if (inventory) {
// Search for the potion STRICTLY inside the inventory panel
var potion = inventory.findObject("health_potion");
if (potion) {
potion.tap(); // Taps the potion!
}
}