i made an aim trainer · pramit.gg
toggle theme
back to the table<br>back to the table
i made an aim trainer
hello.
A lot has happened in my life recently, and as it happens I'm accepting a new position in the birthplace of fallen dreams (san francisco).
Exciting as this is, it means I will have to work again. I've been trying to take advantage of my freedom while I have it, so I have returned to my love/hate relationship with the video game Valorant. There is one issue with this: I'm bad at it.
When I look at a game, I tend to divide it into micro and macro (for a much better explanation of what that means, this video is helpful). Applied to Valorant, this means that I am paranoid about having good aim. Unfortunately, I am very naturally uninclined towards this end.
The normal tool for this is an aim trainer, or just getting good. I've used aim trainers for quite a while. My favorite routine right now is the Viscose benchmarks in KovaaK's, and I think they are honestly really good.
However, as a perception engineer with a Cognitive Science degree and some dabbling in brain-computer interfaces, I felt like I may be uniquely equipped to make this problem much more complicated than it needed to be.
background
Most aim training works like so: somebody makes a playlist of scenarios, each one targets a certain skill, and you replay them until the number goes up. The hope being that this number represents better mouse control, which hopefully represents better aim, which even more hopefully transfers to the game you're playing.
I had two hangups with this norm. First, the scenarios are usually fixed while the player is not. Anyone that's played an older Voltaic playlist knows this feeling, where the gap between the scenarios in the easiest playlist and the next one sometimes feels insurmountable. However, humans generally improve quickest at a slight challenge point, and this is very sensitive per player. This is one of the good parts of Viscose, difficulty jumps much less and keeps the player anchored on improvement. Second, scores give an overall read of the targets you clicked, but not how. If you clicked on a target late, or your wrist was shaky, or you just got tired, the end result is still just a single number that provides insight on only the peak of your performance on this one specific scenario.
So I made openaim, a (free!) aim trainer that records your raw mouse movements and tries to estimate your actual motor proficiency skills with the mouse, instead of a score on a scenario. Then, an algorithmically-motivated coach generates drills to make scenarios that are just hard enough to foster improvement, in all the specific skills you're the worst at.
I wanted this article to be interesting to anyone interested in FPS games and aim trainers, as well as giga nerds like myself. This lent itself to a difficult to balance and technically dense writeup, so buckle up.
OpenAim's menu
how it's going
Before the specifics, here is a player who does not exist.
This is a 24-second run from a synthetic generated player on 2-Tap Strafe
how did we get here
Let me back up. Before any of the interesting modeling, there was a pile of unglamorous groundwork.
First of all, I needed to make a basic aim training environment. I wanted to really make sure this was snappy, so it runs on WebGPU and can comfortably hit 2k+ fps on my 4080, this also allowed me more leeway to simulate it locally. Input fidelity is quite important, so I made sure that the browser takes inputs at as high of a fidelity as Chrome would allow me to. Latency is also measured and subtracted first class to get as accurate of a per-player fit as possible. In true CS2 fashion, the inputs are sub-tick as well!
Every kind of target the engine can spawn — a spread of sizes, spheroids, capsules, blinks, hit-flashes, beam-tracked locks, partial-HP rings — all at once while the camera sweeps across them. The FPS counter is real per-frame draw throughput, and this is captured software-rendered, so my 4080 does better.
It was pretty snappy, so I then moved to the crux of the problem: data.
It's incredibly useful to have a model and a dataset. With my industry being where it's at, it was very tempting to jump to a transformer, but it's good practice to first find the simplest model that can accurately represent your objective.
So the first natural question is, given a player's mouse inputs and an aim scenario, what can we estimate? The underlying system is a human using a chain of very complicated muscles along a feedback loop between your brain, arm, wrist, and fingertips. The output is literally just how much the mouse moves. So, given our run's raw mouse samples, camera angle, scenario targets, and sensitivity, we need to make a decent back estimation of what your actual hand is doing.
In order to do this, I tackled first the goliath Riot Games dared not to till recently: a replay system. This would allow me to make a dataset of myself, then...