cd /news/machine-learning/player-fingerprinting-in-starcraft-i… · home topics machine-learning article
[ARTICLE · art-136803] src=marianogappa.github.io ↗ pub= topic=machine-learning verified=true sentiment=· neutral

Player fingerprinting in StarCraft in the age of AI bots

A new tool called scfingerprint maps StarCraft: Brood War accounts to their human players by analyzing how they play, addressing a scene where progamers like Flash earned a $250,000 salary and over $700,000 in prize money across 113 tournaments. The project ships a built-in identity map, such as one showing progamer Queen (ZerO on Liquipedia) using eight toons across five regions, and arrives as some ladder games are now played by AI bots rather than humans. The work targets a namespace where players buy accounts and create unlimited toons across Korea, U.S. East, U.S. West, Europe and Asia, with community tracking handled manually via Liquipedia's alternate ID lists and the CWAL.gg Player Tracker browser extension.

read11 min views1 publishedSep 22, 2026

TL;DR #

Not all games are child’s play. Competitive e-sport athletes are full-time professionals, and the ones at the top earn around what corporate executives make.

When that much is on the line, working out who actually played a given game stops being a statistician’s obsession.

And as of this month, some of those games are not being played by a human at all .

Is it possible to fingerprint a human by the way they play?

This article covers the problem space, the science in brief, and the results.

Jaedong’s hands. This is not child’s play.

Introduction #

StarCraft: Brood War has been a career in Korea for twenty-five years. At the height of the corporate-team era, Flash was on a $250,000 salary while still in high school, and his prize money alone comes to over $700,000 across 113 tournaments.

The teams are gone, but the scene isn’t. Progamers now make their living two ways:

  • Livestreaming their games on SOOP , the KoreanTwitch (formerly AfreecaTV), where income comes mostly from viewer “star balloon” donations.
  • Placing well in tournaments.ASL is the big one: run by SOOP, offline, 28 players, a prize pool ofaround $58,000 a season.KCM Race Survival is the online circuit, on its 39th season atabout $8,800 each.Daily Proleague runs online showmatches all year.

The infrastructure is unusually simple.

  • One game client. Everybody plays the same one.
  • One server. Korean competitive play happens on Blizzard’s Battle.net.

The rules of the namespace #

  • You buy an account that lets you play on Battle.net.
  • You may create as many “toons” as you want on it. A toon is an in-game name, and it namespaces your results.
  • Toons are unique per region, not universally. Two different accounts can own the same toon on two different regions. The regions are Korea, U.S. East, U.S. West, Europe and Asia.
  • You may buy as many accounts as you like. In principle there’s no reason to. In practice, there is.

Here is what that looks like for one real progamer:

The account of the progamer Queen (ZerO on Liquipedia), from scfingerprint’s built-in identity map . Eight toons, five regions, one human.

💎 The trap is in the bottom right. The toon people know and track is on Korea. The account he’s actually playing sits on U.S. East, under a barcode nobody wrote down.

Everyone hides #

Every player creates aliases to keep some level of anonymity.

Progamers do it so opponents can’t scout their builds, and so viewers can’t follow them around while they practise. Everyone else has their own reasons.

And the cheapest anonymity in the game is a barcode:

How the community keeps track #

By watching. Someone tunes into a stream, the ladder screen is on camera, and they read the toon off the overlay and write it down. The result is a mapping from toon to identity, maintained by hand.

It has produced real infrastructure:

This mechanism is simple and it works in most cases. But it suffers from five problems:

  • It requires constant maintenance. The list is only as fresh as the last person who watched a stream.
  • It is possible to make mistakes. There’s no verification step and no confidence attached.
  • It does not survive the uniqueness rule. The same toon can be two different people on two different regions, and a flat string mapping cannot express that.
  • It rests on a single observation. It’s possible for people to play on each other’s accounts, and one sighting doesn’t establish who was at the keyboard for the next thousand games.
  • It does not scale past a hundred-odd people. Too much manual work. Liquipedia will track the ASL field. It will never track the four guys I play on Sundays.

When money is on the line, this is not good enough.

And this month the question got harder. A bot appeared on the ladder, good enough to beat progamers, and the community spent days trying to work out which accounts were it.

A ladder bot taking a game off a pro.

So the question is no longer only which human played a game. It is whether one did.

So: can you fingerprint a human from their replays? #

Brood War writes a replay after every game: a .rep file that records not what happened, but the stream of commands each player issued, each one timestamped. I’ve written about how maddening that is to get meaning out of , and built an interactive explainer of why.

Here it is exactly the right data. We don’t need to know what happened in the game, only how the keys were pressed. And nobody chooses their keypress habits: they are muscle memory ground in over years, closer to handwriting than to a password.

If that can be measured, every problem above goes away. But the fingerprint has to be:

  • Unique enough , so it doesn’t collide across the population of people playing.
  • Stable enough , so the same human always converges to the same fingerprint.

The next section is the high-level science. Skip to the results if you’d rather.

The science #

If the premise is right, this is a behavioural biometric , and specifically a close cousin of keystroke dynamics : the idea that how you type identifies you regardless of what you type. Most of what follows is the speaker-recognition pipeline with hands in place of a voice.

What gets measured

360 numbers per player per game. All of them describe how, never what: no map, no position, no build order, no strategy.

  • Hotkey habits. Which control groups they bind and select, the ratio of selects to assigns, double-tap rate, and which groups they bind in their first five assignments of a game.
  • Command loops. A 10x10 matrix of “which kind of command follows which”. Some players cycle select → hotkey → right-click tightly; others interleave production checks.
  • Rhythm. The distribution of gaps between consecutive commands: median, percentiles, the modal gap, how long their bursts run.
  • Micro-timings. How long after binding a hotkey they first use it. The gap inside a double-tap. How big their selections are.
  • Tempo. APM, effective APM, redundancy, and APM by phase of the game.

Two Zergs can open with the same build on the same map and be trivially separable here. One binds hatcheries on 4/5/6 and army on 1/2 with a 190ms double-tap. The other binds army on 1/2/3, checks production by clicking, and has a distinctive three-command burst. Nothing in their build orders tells them apart. Everything above does.

How two players get compared

  1. Standardise every feature against the training corpus, so that a millisecond and an APM count carry equal weight.
  2. Keep the 150 most discriminative features , ranked byF-ratio : between-player variance divided by within-player variance. Most of the 360 measurements distinguishgames ; only some distinguishpeople . That ratio is the same quantity at the heart oflinear discriminant analysis .
  3. Whiten using the within-player covariance,shrinkage-regularised because a 150x150 covariance estimated from limited games is otherwise unusable. Habits that move together stop being counted three times, and every remaining direction of variation carries equal information.
  4. Compare with cosine similarity . A player’s fingerprint is just the mean of their whitened per-game vectors, which is why it can be updated one game at a time and stored in a single database column.Here is Jaedong’s , if you want to see what one actually looks like.
  5. Grade that score against a crowd of strangers. A raw similarity of 0.8 means one thing for a player with common habits and something else entirely for a weirdo, so instead of using it directly we ask how far above a reference crowd it sits. That isz-norm and t-norm , lifted straight from speaker verification, and it is not optional garnish: raw cosine alone gives up roughly 40 points of true-positive rate at the strict threshold.
  6. Calibrate on how much evidence there is. An average over eight games wobbles less than a single game does, by roughly thesquare root of the count , so a score of 5 means different things at one game and at fifty. Each evidence bucket gets its own calibration. Without it, one large aggregate out-ranks everything for entirely the wrong reason. It did, once.

Is it unique enough?

Score two piles of replays against each other, on cases where the answer is already known.

Measured over the committed labelled corpus .

Stranger pairs land below 1.7. Same-person pairs land above 5.4. The 3.7 points in between stay empty.

💎 So: from a single game, one player is told apart from a stranger 99.8% of the time, and picked correctly out of 68 candidates 98.9% of the time. That is unique enough, and a case landing in the empty gap gets “I don’t know” instead of a guess.

Those percentages are the usual biometric measures, read off a detection error tradeoff curve.

Is it stable enough?

Split each player’s games in half by date, then score their earlier games against their own later ones.

Every point traces back to a replay in the committed labelled corpus .

Same measurement, used two ways:

  • Above the bar: this is one human, and their habits held.
  • Below it: the label is describing more than one person. That is how shared accounts and curation mistakes get caught before they poison anything.

Results #

I scored 474 ladder accounts against the catalogue, and checked every answer against the community list.

It reaches parity, and dodges all five problems by construction:

Problem with the manual list Why the fingerprint doesn’t have it
Needs constant maintenance Re-derives itself from replays
Can be wrong, silently Carries a calibrated confidence
Breaks on the per-region rule Never looks at a name at all
Rests on one sighting Measures whoever is at the keyboard
Caps out around 100 people Capped by replays, not by eyeballs

What fingerprinting found

✨ A progamer filed under another progamer’s name. The community list maps three accounts to Blade. One of them carries no toon, only the battle tag llllllllllll, and it plays like Paralyze : a different player, same race.

✨ Accounts nobody had connected to anyone. Five barcodes fingerprint as a catalogued pro, and the community list attaches no name to any of them:

  • wiwiwiww92Jaedong
  • IlllIIlIIlIllIISharp
  • lIIIlIlIIlIIIIlAmple
  • lllilliliiilillAlen
  • IIIlIlIIIIIIllTimeIsGold

Each matches its pro’s race and rating band, and has never played them on the ladder.

Limitations #

  • It cannot put a name on a face. It can tell you that an account filed under a pro isn’t that pro. It cannot tell you who the pro actually is, because the only thing that ever attaches a real name to a fingerprint is somebody watching a stream.
  • One game is a lead, not proof , and three or more is where it gets confident. Team games and custom maps are three to five times worse, because it was tuned on ladder 1v1.
  • The catalogue is the weakest link. Every wrong answer I’ve had came from a bad catalogue entry, not from the matcher: a player enrolled from contaminated games claims accounts that aren’t his.

💎 Which is why this is best viewed as a complement to the hand-maintained list, not a replacement for it, and not a better version of it.

Try it #

scfingerprint is a Go library and CLI, MIT licensed, with the labelled corpus committed so every number above traces back to replays.

scfingerprint match game.rep            # who is each player?
scfingerprint same --a dirA/ --b dirB/  # are these two the same human?
scfingerprint whois Queennnnnn          # who owns this toon, and what else do they own?

It’s wired into screpdb , my StarCraft reporting tool , so a barcode in your own replay folder resolves to the person behind it.

The identity map and the fingerprint agreeing on the same account, plus every other toon it plays under.

And the same across a whole replay folder.

screpdb compiles to WASM, so you can ▶️ try a preview in your browser without installing it.

── more in #machine-learning 4 stories · sorted by recency
── more on @starcraft: brood war 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/player-fingerprintin…] indexed:0 read:11min 2026-09-22 ·