Someone on V2EX shipped a browser aim trainer called aimrange and posted it for feedback. The pitch was simple: they got hooked on FPS games, wanted to warm up for a few minutes before playing, and didn't want to install a client just for that. So they built a web version you open in a browser, no download, no registration. Six scenarios (Gridshot, Sixshot, Microshot, Spidershot, Motionshot, Strafetrack), sensitivity defaulting to Valorant's algorithm, cross-game conversion between titles, crosshair-code paste import, a weekly and all-time leaderboard with no accounts (type a name and you're on it), plus a reaction-time test bolted on.
What caught my attention wasn't the aiming. The pointer-lock gameplay canvas is the flashy bit, and honestly it's also the most replaceable bit. Browsers already ship a dozen aim trainers, pointer-lock behaves differently across devices, and the "feel" is the part people argue about and abandon. The piece that actually keeps someone coming back is boring by comparison: the sensitivity converter and the crosshair-code parser. Those are deterministic. You put in your Valorant number, you get your CS2 number, and it's correct every time or it's a bug. That's the part worth building to last.
Why the converter outlives the canvas
Think about where the churn is. A new aim trainer ships every month, so the gameplay layer competes on polish and novelty, and most of it gets forgotten. But a player who's mapped their sensitivity across three games once will keep that mapping forever, and they'll come back to whatever tool got the math right. The crosshair-code import is the same shape of value: nobody wants to re-enter settings line by line, so a parser that eats a pasted code and reconstructs the crosshair saves real friction. These are the sticky features, and they're sticky precisely because they're deterministic utilities, not entertainment.
The original author even flagged the failure mode themselves, inviting comments about bugs, bad feel, or conversions that don't line up. That last one is the tell. "Feel" is subjective and unfixable; a conversion that doesn't line up is a concrete, correctable defect. If you treat the converter as the product and the canvas as a demo, you're building the half that can actually be right or wrong.
Separate the math from the game
Here's the rebuild I'd do. Keep the front end thin and treat the per-game conversion rules as data, not code. The mistake I'd avoid is hard-coding each game's formula inside the UI, because then every new title or balance tweak means a redeploy and a chance to break the math.
On VicroCode the split falls out naturally. You can run HTML online for the front end: the scenario selector, the input fields, the leaderboard view, and the crosshair preview. That page doesn't need to know any game's conversion constants. It just collects a source game, a target game, and a sensitivity value, then calls a backend.
The conversion itself belongs in a small service. You can run Python online to host the endpoint that takes `{source_game, target_game, sens, dpi}` and returns the converted value, plus a separate route that parses a pasted crosshair code into structured fields. Keeping this in Python means the math is testable in isolation, away from any pointer-lock quirks. Write a table of known conversions, assert the function reproduces them, and you've turned "conversions don't line up" from a vague complaint into a failing test you can fix.
Formulas as an editable table
The part that makes this durable is where the per-game constants live. Put them in a database, not in the Python. Each game gets a row: an identifier, its reference unit, the coefficient that maps it to your canonical scale, and whatever offset it needs. The endpoint reads from that table, so conversion is "look up both games, convert source to canonical, convert canonical to target." Adding a game is inserting a row. Correcting a wrong coefficient is editing a cell.
That's exactly what a SQLite editor is for. When a user comments that the Valorant-to-CS2 number is off, you don't open an IDE and redeploy, you open the table, adjust the coefficient, and the live endpoint picks it up. The same database holds the login-free leaderboard: a scores table keyed by display name and scenario, with no account system behind it. The author's "type a name and you're on the board" choice maps cleanly onto a couple of SQLite tables, and it sidesteps the whole auth, password-reset, and privacy burden that a login flow would drag in.
A caveat worth stating plainly: name-only leaderboards are trivially spoofable. Anyone can type any name and submit any score. For a warm-up tool that's fine, and it's arguably the right call since it removes signup friction. But don't pretend the numbers are competitively trustworthy, and don't bolt real stakes onto them without rethinking identity. If you later want verified scores, that's a different project with real auth, not a patch on this one.
What this gets you, and what it doesn't
The payoff of the split: the throwaway layer stays throwaway. You can rip out the gameplay canvas, swap it for a new one, or run it alongside the reaction-time tool, and none of that touches the converter or the leaderboard. The math service, the formula table, and the scores all survive independent of whatever's happening on the aiming screen. You've isolated the durable 10% from the disposable 90%.
Against what the evidence actually supports, I'd keep the claims modest. The source post is one developer sharing a project and asking for feedback; there's no data on retention, accuracy, or how many players the conversions served, so any statement about this architecture driving engagement or being more accurate is unverified. What I can say is structural: deterministic utilities are testable and correctable in a way that gameplay feel is not, and separating data from code lets you fix a wrong coefficient without a deploy.
A few boundaries, since it's easy to over-promise here. The crosshair-code parser is only as good as the format you reverse-engineer, and if a game changes its code format you're back to reading it by hand. The conversion table is a maintenance commitment, not a one-time build, because games retune their sensitivity scales. And pointer-lock behavior across browsers and devices is genuinely inconsistent, which is one more reason not to anchor your product on the aiming canvas. VicroCode covers the HTML front end, the Python endpoint, and the SQLite store cleanly, but it won't help you with native-client capture or desktop-level input, and that's fine because none of the valuable part needs them.
If you're a solo builder weighing this, the lesson generalizes past aim trainers. When a tool bundles a flashy interactive surface with a quiet deterministic utility, the utility is usually the asset. Build it as a tested service over editable data, keep the surface swappable, and you've got something that outlives the trend that inspired it.