The problem
In ARAM Mayhem, League of Legends offers you three augments several times a game, and picking well depends on your champion. Riot does not publish which augments are on offer, so no tool could react to them in game. Players alt-tabbed to a stats site, mid-fight, against a timer.
What I built
A Tauri 2 app with a Rust backend and React windows. It talks to the League client's local API for champ select, ready checks and item sets, and to the game's Live Client Data API for your champion and the teams. During an offer it takes small captures of the card area, reads the titles with a bundled OCR model and overlays each card's tier, win-rate difference and rank for your champion. In champ select it rates picks and bench swaps, and on lock-in it writes item sets into the client. A small TypeScript service on Fastify and SQLite caches the community statistics per patch and serves them in the shape the app needs.
Technical challenges
- Any screen, no calibration. Card positions are predicted from the window size alone, fitted on real screenshots at nine resolutions and four aspect ratios, with every card edge within 1% of the window height.
- Cheapest question first. Each tick checks a short strip for the reroll buttons before touching the card area, so outside an offer the app barely works at all.
- OCR without installs. The PaddleOCR model runs through
tract, a pure-Rust ONNX runtime, one card per thread. It is tested end to end on real screenshots, including titles that wrap onto two lines. - Safe by design. No memory reading, no injection, no Riot web API: only local APIs and the screen.
Outcome
Version 1.3.2 is released on GitHub with signed auto-updates, an installer and a portable build. A measured match shows about a tenth of one core between offers and peaks only for the seconds when titles are being read.