Role
every hat
- Product
- Interaction
- Visual
- Code
Design case study · Everywhen
A place-based learning app nobody needed to open twice, and how it became a daily where-and-when game people return to, down to the physics of a single sheet.



Everything that ever happened, happened somewhere.
The hard part wasn’t the places. It was giving anyone a reason to come back tomorrow.
Role
Timeline
14 iOS versions in four months, live the whole time
Platforms
Scale
930places in eight realms, in English and 中文
A learning app gives you no reason to open it tomorrow.
A daily round of four real places: guess where, guess when, then read what happened there.
Input that makes precision possible, scoring that rewards being close, a voice that takes your side, and one sheet that moves the way your hand expects.
The app collects no analytics, so this is design reasoning and my own daily play, not a retention chart.
The problem
The first Everywhen, shipped in mid-July, was a place-anchored learning app. You opened it, a place lit up on the map, and you got a two-minute story about it, ideally listened to on a walk. One place, one takeaway, one question. The premise still drives everything: memory is exceptionally good at hanging facts on locations (the method of loci), so every fact in Everywhen is pinned to the spot where it happened.
The loop was tidy and the content was good. What it lacked was pull. Explore was built on “pull, don’t push”: nothing appeared unless you asked. A daily notification named a random place. Tomorrow looked exactly like today, so there was no particular reason to come back to it, and in my own use I mostly didn’t.

Explore, the original front door. It is still in the app, but it is no longer the reason to open it.
The bet
The day after 1.0 shipped, I wrote a new first line for the spec: “The retention engine: one shared daily round of four place-guessing puzzles that ends in learning.” It was built and merged that same day, and Today became the first tab.
A new round each day is a reason to come back that needs no explaining. A streak turns that into a small promise to yourself.
Everyone gets the same four places on a date, so scores are comparable and a share is an invitation, not a brag.
Four a day keeps learning spaced, which is how it sticks. Bingeing a catalog is cramming, so the scarcity is the feature, not a limit.
Guessing before reading also does real work. The guess is a retrieval attempt, a moment of “I think I know this”, and the story then lands on a question you already care about. The game feeds the Passport, the atlas of every place you have collected. It is not a parallel universe.
The shape of a day
A day runs easy to hard, and each place is worth more than the last: 100, 200, 300 and 400 points. Knowing the obscure place pays the most, which is the right incentive for a learning game, and the maximum comes out a clean 1,000. A fifth bonus place is optional and never counts toward the streak or the shared score, so the core day stays comparable for everyone.


I chose never over “once a year”. At five a day that is roughly 150 new places a month, forever, so content became a permanent rate to hold rather than a backlog to clear. An unscheduled place is invisible in the app, so the schedule is the product.
Playing in October, I noticed I mostly didn’t recognise round two at all. Places had drifted to being rated more famous than they are. The fix wasn’t harder content but a nudge: a region chip and an era chip on the first rounds, always on, at no cost.
Asking “when”
The first when-input was one slider from 4.5 billion years ago to today, log-scaled so the sixties and the age of the dinosaurs felt equally reachable. It looked elegant and was physically impossible to use: the full-points window was about half a pixel of track at every era. It became two steps, a range and then a year inside it, shipped the same day the daily did. Try both.

When was Pompeii buried?
Pompeii, Italy · full points within ±97 years · try both inputs
First design · one slider
Off by 65,135 years.
1.4 px wide: the whole full-points window on this track.
Shipped · range, then year
Six ranges, oldest first. The slider wakes up in the one you pick.
Same answer, same tolerance, same rules as the app. Only the input changed.
The first ranges followed textbook eras, and Modern alone held 47% of the places while Prehistory held 4%. Merging the two oldest into “Before history” and splitting Modern at 1900 brought the fullest range down to about 30%, so every choice is a real choice.
Tolerance is 5% of an answer’s age, which is fair for antiquity and brutal near the present: ±3 years on a 1962 temple that looks medieval. Within forty years of a modern date now scores in full, because the present is exactly where a photograph lies to you.
Making it fair
The original where-score had, in my own note, “a cheap top and a cruel middle”. Anything within about 64 km showed a perfect score, while a guess 2,000 km along the Amazon earned a quarter and 5,000 km earned almost nothing. In late October I reshaped the curve so it falls fast near the answer, keeping a top score meaningful, and flattens across the middle, so the right continent keeps real credit.
Hover the chart to compare.
| km off | 100 | 300 | 1,000 | 2,000 | 3,000 | 5,000 |
|---|---|---|---|---|---|---|
| Before | 96% | 83% | 50% | 24% | 12% | 3% |
| After | 92% | 81% | 60% | 44% | 33% | 21% |
An audit found 44% of the hints leaked: a century, an era label, a word from the place’s own name. With a forgiving when-score, one leaked century was worth full marks. All of them were rewritten, and a test now fails the build if a hint names its place or runs past 140 characters.
A date has to match the event the story itself tells, backed by a quote from the story. Otherwise a player who read carefully would be marked wrong, which is the one thing a learning game can’t do.
On the player’s side
The reveal says one line, right away, in the voice of a delighted friend across the table. It is never scoreboard-speak. When you nail it, it says so. When you don’t, the puzzle takes the blame: the place was hiding, and being wrong is how these stick. The hardest place of the day stays forgiving-funny, because nobody is meant to get that one cold.


“You felt the era. The map played tricks.”
Every reveal ends in a real place and what happened there.

Petra100 BC

Mount Fuji750

Uluru550 million years ago

Great Wall1570

Terracotta Army210 BC

Hagia Sophia532

Stonehenge3000 BC

Gombe1960

Potala Palace1682

Salem1692

Alcatraz1934

Sistine Chapel1508

Machu Picchu1450

Galápagos1835

Borobudur800

Abu Simbel1264 BC

Pompeii79

Rapa Nui1000
A face for every place
A list of 930 places is a lot of names to tell apart. In late October every place got its own small line drawing: a bridge, a crater, a stepwell, a chimp. They sit beside each place in the Library and its collections, drawn in the colour of the place’s realm, so a shelf of places has a shape before you read a word. Find one, or filter by realm.
The content build refuses two places with the same drawing, and refuses a catalog where any place is missing one. Distinct isn’t a hope I check by eye; it’s a test.
Each icon is a few path strings on a 24-point grid with round caps and no fill, drawn natively by SwiftUI, Compose and the browser. iPhone reads paths most strictly, so every one is checked the way iOS will read it before it ships.
Reasons to come back
A restored phone once read “0-day streak” over two hundred played days. Every screen now counts it one way, pinned by a test.
It points at the game, not an answer. Android asks permission only after your first round.
Past dailies stay playable, and finishing one heals the streak. A streak that can only break teaches you to stop caring.
Everyone plays the same four, so a friend can take you on today. The cards →
Cards that leave the app
A share is the one part of Everywhen that leaves the app and lands in someone else’s messages. So each card is designed for whoever receives it, which means two people at once: a friend who plays, and a stranger who doesn’t. Every card is the same 4:5 object on iPhone, Android and the web. Tap through them, then flip the thread to dark.
1080 × 1350, the shape Messages and Instagram treat best
A pin would hand the answer to a friend who hasn’t played yet.
Each filled to its round’s score: the same numbers as the text share.
Everywhen.cc #122 · November 8
46😬 54😬 47😬 80🌟
Final score: 616 / 1,000 · 🔥 40
616Georgia
616Charter
Motion: one sheet
“See your guesses” lets you step back through the day’s four places: your pin and the answer on the map, your scores, then the place’s story. The whole design is one sheet over a map, and almost all of its quality is in how it moves. Every rule below is in the shipped app, with the same constants on iOS, Android and the web.
Try it
Drag it, flick it, push it past the top.
Every release is projected to where it would coast to a stop, then settles on the nearest of three stops: Open, Half and Peek.
“See your guesses” arrives: a way back into the day’s four places from the scorecard.
First design: pull the panel up and the story rises over it as a separate page. It read as a second page stacked on the first, and I reverted it 26 minutes later.
A half sheet over the map instead. Push it up and the photo and story are right there below the scores.
The motion rules arrive: project the flick, settle on a critically damped spring, bend past the ends instead of hitting a wall.
A third, lower stop, so the map can have nearly the whole screen when you want to look at it.
The map stops moving when the sheet does. Every camera fix re-centred it a beat later, so the review map became a native map view with its margins split from its camera.
The rule I’d written down (“stop at the top, pause, then scroll”) was wrong in the hand. Reversed: the sheet and its story are one surface.
Driving it by touch in the simulator found it didn’t move at all on the newest iOS, and that Read story was a dead tap. Both fixed before 1.9.2.
One game, three clients
Everywhen is three separate clients: SwiftUI on iPhone and iPad, Kotlin and Compose on Android, and React on the web at everywhen.cc. The game rules are shared, not the interface: scoring and streak fixtures are generated from the Swift code and checked by the Android and web tests, so a day scores identically everywhere.
The first Android daily passed every test and was one step from release when I played it on my phone and found five ways it didn’t feel like the iOS game: the story in the wrong place, no map on the reveal, ranges that scrolled, and more. A port has to reproduce the flow, not just the features. Now I play every port end to end before it ships.
All 930 places, every clue and every story, read in Traditional and Simplified Chinese. The Simplified text is converted from the Traditional, with hand-made exceptions where the converter picks the wrong word.


What I’d measure next
Everywhen has no analytics SDK, by choice, so I can’t show you a retention curve. What I can show is the reasoning, the craft, and a habit of playing my own game every day and fixing what it teaches me. If I added consented measurement, these are the questions I’d want answered first:
Everywhen
Four new places are waiting today. Guess where, guess when, and see how close you get.