I play Counter-Strike, and like everyone who plays Counter-Strike, I wanted to get better at it without the part where you mindlessly grind deathmatch for two hours and call it practice. So I built the thing properly: a personal training platform that measures real gameplay mechanics server-side, grounds its drills in motor-learning research instead of vibes, and builds timed sessions around whatever the data says I'm worst at. The whole thing is orchestrated by the same Raspberry Pi that runs the rest of my setup, and the actual game server spins up on a rented GPU only when it's needed — €0.22 an hour, and nothing runs when nobody's training.
What it actually does
- Real measurement, not a stopwatch. A custom CounterStrikeSharp plugin hooks the game's own events and reads server state directly: crosshair offset at the moment of firing, counter-strafe stop quality (your velocity at the fire tick), burst discipline via the recoil index, hit placement, time-to-kill per bot. Workshop aim maps show you a HUD number and keep it; this writes every attempt to a database.
- 495 scenarios across the entire Active Duty pool. Nine maps, three disciplines (prefire, aim, recoil), three difficulty tiers — 6,315 bot placements, converted from an MIT-licensed open route dataset with an original converter. Every common position has a prefire angle; every drill has a stated training purpose.
- Sessions built around measured weakness. The plan engine reads your per-skill ratings (recency-weighted, ELO-style) and generates a structured block — warmup, mechanical work on the focus skill, targeted weakness reps, a game-like transfer block, and a fixed benchmark that never changes so progress is comparable week to week. Ask for 30 minutes, you get a 30-minute session with a reason behind every block.
- Scoring that can't be gamed. Speed and accuracy are coupled multiplicatively — a fast-but-sloppy run mathematically cannot outscore a slower accurate one. There's a regression test that proves it. Consistency (coefficient of variation) and headshot ratio are scored as their own dimensions, and a data-quality gate flags impossible records at the ingest boundary instead of quietly keeping them.
- It knows when to stop. Fatigue detection watches accuracy trend and variance across a session and will tell you to take the break — because grinding reps while tilted isn't training, it's just noise.
How it's built
Three layers. On the game server: the plugin, written in C#, plus Metamod and the CounterStrikeSharp runtime, deployed as one self-contained bundle the server container pulls at boot. On the Pi: a FastAPI control plane — session management, analytics endpoints, the plan and progression engines, a dashboard — backed by SQLite, with 65 tests keeping it honest. Between them: a spend-tracked RunPod integration that deploys the cheapest available GPU under a hard cost ceiling, streams the game logs, and drives the server over RCON.
The research layer is the part I'm most pleased with. Before writing a single scoring formula I had the training methodology researched and written up — deliberate practice, skill isolation vs transfer, spacing, adaptive difficulty — with every design rule tagged by evidence tier (peer-reviewed, coaching consensus, or engineering assumption) and traced to the code that implements it. When the plan engine picks "weakness block" over "more reps", there's a citation behind that decision.
Honest status
What's proven: the full engine (65/65 tests), the control plane and API running live, the cloud lifecycle — deploy, log-watch, RCON control, teardown — exercised end to end across four live server deployments, and the API ingest chain verified with real sessions landing in the database. What isn't: the final plugin-load on a fresh server install was still being validated when I called time on the budget, so the last link — plugin load on boot, then a real player killing real bots — is built and staged but not yet demonstrated live. It's the next thing on the list, and when it lands, the whole chain from "start me a session" to "here's what you improved at" runs unattended.
The stack, briefly
- C# / CounterStrikeSharp plugin, Metamod:Source, .NET 10
- Python: FastAPI, SQLite, 65-test suite, CI
- RunPod GPU cloud (on-demand, spend-capped), RCON, Tailscale
- Raspberry Pi 5 control plane + dashboard
- ~75KB of research docs grounding every training decision