Adaptive Scaling
How the matcher handles elements that change size at runtime
Template matching normally looks for your saved image at roughly the same size it was captured. Adaptive scaling lifts that restriction — the matcher tries your template across a wide range of sizes so it can find elements that appear larger or smaller than when you recorded them.
What TapForge already handles automatically
When you run a macro on a different device than it was recorded on, the template search range widens automatically — if TapForge detects that the current device's screen dimensions differ by more than 20% from the recording device, it extends the matching range to 0.50×–2.00× of the original template size without any extra setting. This covers the typical size difference between different phone models or between a phone and a tablet.
Note: this automatic widening applies to template matching only. Raw coordinates in scripts — tapAt(x, y), swipe(), longPress(x, y) — are not scaled and will land at the same pixel position regardless of device. If you need cross-device coordinate portability in a script, compute positions from getPosition() matches rather than hardcoding numbers.
When do you actually need adaptive scaling?
Enable it when the element genuinely changes size at runtime — not just because you're running on a different device:
- The game has a zoomable map or camera — icons on the map (villages, bases, resource nodes) appear at different sizes depending on zoom level. Without adaptive scaling, a template captured at one zoom will be missed at any other.
- In-game UI that scales dynamically — some games scale parts of their interface based on in-game settings (minimap zoom, HUD scale slider). If the element you're matching can be resized by the user or by game events, adaptive scaling lets the matcher find it across that range.
- Extreme device size differences — the automatic widening covers up to 2× difference. If you're running a macro recorded on a small phone on a very large tablet where the game renders elements more than twice as large, enable adaptive scaling to extend the range to 3×.
How does it work?
The matcher runs your template through a search across multiple scale levels, ranging from 0.30× (the element is much smaller than captured) up to 3.00× (much larger). The best-scoring location across all scales wins. Without adaptive scaling, the search only covers a narrow ±25% range around the original size, which handles minor rendering drift but not genuine size changes.
Performance and scale caching
Searching many scales takes more time than a single-scale pass. To reduce that cost, TapForge caches the winning scale from each match. On the next execution of the same step, it tries that scale first. If it produces a confident hit, the full multi-scale search is skipped entirely. For an element that stays at a consistent zoom level between runs — which is common — this means you pay the full search cost once, and subsequent matches are nearly as fast as with adaptive scaling off.
If the element moves to a different zoom level, the cached scale will miss, and the full search runs again to find the new scale, which is then cached for the next run.
Per-object and scene-level settings
Adaptive scaling can be toggled per object in the scene editor, or overridden at the scene level:
- Per object (default) — each object uses its own setting. Turn it on only for objects that genuinely need it, leaving the rest at the fast narrow search.
- Force on (scene level) — all objects in the scene use adaptive scaling regardless of their individual setting. Useful when you're porting a macro to a different device and want everything to adapt without editing each object.
- Force off (scene level) — all objects skip adaptive scaling. Useful for performance-sensitive macros on a single known device.
Example: zoomable strategy map
Imagine a strategy game where you scroll a world map and the icons for your own villages appear at different sizes depending on how far you've zoomed in. You capture a template of your village icon at medium zoom. Without adaptive scaling, your script only finds it reliably at that exact zoom level. With adaptive scaling on, the matcher finds the icon whether you're zoomed in to 2× the capture size or zoomed out to 0.5×.
// Script that works regardless of current map zoom
var pos = getPosition("my_village");
if (pos) {
pos.tap();
} else {
// Not visible at current zoom — adjust zoom, then retry
swipe(540, 960, 540, 600, 300);
wait(500);
var pos2 = getPosition("my_village");
if (pos2) pos2.tap();
}
Tips
- Enable adaptive scaling only on objects that actually change size. Applying it everywhere increases matching time per step.
- If matching is slow on a step that uses adaptive scaling, check whether the element actually varies in size. If it doesn't, turning it off restores single-scale speed immediately.
- Very small templates (under ~28 px at the captured size) are unreliable at extreme scales. Capture the template at a zoom level that gives the element a comfortable size on screen.
- If you're seeing false positives — matches at the wrong location — the template may contain too much background. Use segmentation to isolate the element first, then enable adaptive scaling.