daily language game
hear ten seconds of someone speaking, drop a pin where you think it is spoken.
python (stdlib only) · glottolog · glottography · natural earth · geojson · pillow
data pipeline built and tested, no clips yet, not playable.
Five clips a day, the same five for everyone. Each round plays ten seconds of one person speaking and you drop a single pin on a world map. The round scores by how far off you were, weighted by where the speakers actually are, so pinning Mexico City for Spanish beats pinning rural Patagonia. Then the real footprint appears as a heatmap and you find out what you were listening to.
The answer is never a language name. It is a place. That one choice is the whole design, and I will come back to it.
why i built it
I grew up with Khmer, which almost nobody can name on hearing it, and I got curious about how much geography is actually carried in the sound of a language. You can usually tell West African from East Asian from Nordic without knowing a single word. That intuition is real, it is widely shared, and nothing I could find lets you use it.
The games that exist ask you to name the language. That turns a listening skill into a vocabulary test. Kabyle is a good example. Several million people speak it, and almost no one outside North Africa has heard the word, so naming it is impossible for nearly every player. But hearing that it is North African and putting a pin near Algeria is something a lot of people can do on instinct.
Moving the answer onto a map made the game accessible to people who know no linguistics, and it also dissolved three problems the naming version needed special rules for. Hindi and Urdu stop being an argument about equivalence and become overlapping regions. Mandarin and Cantonese stop being a granularity rule and become two different places. Cover terms like "Arabic" stop needing an exception and become a footprint.
the thinking
Three decisions carry the design, and each one came out of trying to break the game.
One pin per round, never iterative narrowing. The obvious version lets you guess several times and tells you how far off you are each time. That version is solvable by trilateration in three guesses, so a player who cannot tell Khmer from Korean wins every day with arithmetic and no ears. One pin kills the exploit, which is also what makes plain distance scoring safe to show.
Density weighting instead of asking whether the pin is inside the polygon. Binary inside-or-outside makes Spanish free, because its footprint covers most of two continents, while Kabyle demands precision. Polygon size becomes the difficulty, and polygon size has nothing to do with how placeable a sound is. So every entry carries a speaker-density grid, and a pin scores against people rather than against area.


Those two images are the same three languages before and after the weighting, and the Khmer panel is the one that convinced me it was worth building. Population alone shades the Mekong Delta in Vietnam darker than rural Cambodia, which is true of people and false of Khmer speakers, so the grid also carries a hand-authored share of speakers per country for the entries where it matters. Khmer now reads 90 percent Cambodia, 6 percent Thailand, 4 percent Vietnam, which is roughly right.
The heatmap is a reveal, never a hint. Showing where a language is spoken is showing the answer. That is also why I dropped the hint ladder entirely. Under a map, any hint useful enough to help you place a pin is geographic, and therefore a spoiler, and any hint that is not geographic is trivia.
how it works
Phase one is a five-stage data pipeline, standard library Python only with no dependencies at all, where each stage gates the next and four of the five exit non-zero when something needs a human to look at it.
It starts from a hand-written pool of entries, resolves each one to a Glottocode against the Glottolog catalogue, pulls a language area for it from Glottography, falls back to administrative boundaries where no atlas covers it, rasterises a speaker-density grid inside each footprint, and reports which entries overlap too much to appear in the same session.
The rule the whole pipeline is built on is that it never guesses on my behalf. The resolver earned that rule on its first real run by offering Greek for Creek and Sakha for Yaaku, two wrong languages on two wrong continents. An upstream re-code in Glottolog holds the build shut rather than silently repointing the join key. Anything ambiguous exits non-zero with a reason and waits for me.
Verifying by eye is what caught the bugs that bounding-box checks could not. A reconstruction atlas was quietly winning eleven entries just by sorting first alphabetically, which drew Yiddish as a blob in pre-war eastern Poland. Fixing that meant recording what kind of thing each dataset actually draws, so a reconstructed range can never outrank a contemporary one again.
where it is now
The pipeline is real and the game is not. I would rather say that plainly than imply otherwise.
Built and counted as of November 2026. A pool of 136 entries, 119 languages plus 17 English accents, every one resolved to a locked Glottocode. Footprints for all 136, 117 straight from Glottography and 19 cut from administrative boundaries by hand. A density grid of 881,054 cells across the pool. 110 entry pairs flagged as sharing too much ground to sit in one session. 104 passing tests over about 2,400 lines of Python.
Not built. The clips. That is the long pole and it is roughly twenty hours of listening, because five rounds a day burns a library five times faster than a one-clip daily, and 450 clips is the target. No game loop, no front end, no approval gate, no deployment. The name is still undecided, which is less trivial than it sounds, since every obvious construction is already taken by something live.
The honest risk is differentiation. A polished competitor exists with more languages, leagues and multiplayer, and it owns the search terms. What I have that it does not is density-weighted scoring, the heatmap reveal, and a game you can win without knowing what any of the languages are called. I decided that trade deliberately, for accessibility, and I would rather build the accessible version well than the crowded version first.
what i learned
Almost all of the work is in the data, and none of it is in the game. The scoring and the map are a few hundred lines. The week and a half went into deciding what a language's footprint even means, which turns out to be a question atlases answer differently and none of them answer the way a game needs.
The other thing I learned is to check my own test data. I had labelled a city as the density bullseye for Kabyle from general knowledge, and when the smoothing landed a different city overtook it. My first instinct was that the weights were broken. The weights were fine. The label was wrong, and the only reason I found out is that the output was a picture I could look at rather than a number I had to trust.

