Case study · Todd Blocksom · 2026
HIDE/SEEK
A location-based multiplayer game that turns any neighborhood into a game board, for two to eight people, on foot, in an afternoon.
Built solo in seven weeks from first commit to TestFlight beta: product, design, iOS, backend, web, and release engineering. Now in public TestFlight beta.
Status · App Store submission in review
- Role
- Sole product, design, and engineering lead
- Timeline
- Seven weeks, first commit to TestFlight beta
- Stage
- Public TestFlight beta, App Store submission in review
- Scope
- iOS client, Postgres and PostGIS backend, spectator web app, operations tooling
- Outcome
- Shipped to beta with a privacy and retention architecture built for production
Why it exists
The origin is one sentence from the product spec, and it never changed: I wanted to play this with my kids, in whatever neighborhood we happened to be in, in a session short enough to fit a weekend afternoon.
The original spark came from Jet Lag: The Game, which proved that hide and seek turns deeply strategic once you add an information economy. Its ruleset assumes a country, public transit, and a full day, so almost nothing survived contact with a different audience, geography, and session length. Radii went from miles to hundreds of feet, hiding windows from hours to minutes, landmarks from train stations to mailboxes. The question economy had to be repriced around clues a child can act on while walking, and the round had to resolve inside an afternoon rather than a weekend.
Before there was an app, there was a summer of playing it by hand. We drew play areas on maps, dealt question cards on paper, tracked coins in a notebook, and texted photos back and forth. Each time we played, the zone got bigger and the round got more ambitious. That was the signal I trusted, and it is the reason the project was worth starting: the risky question, whether a neighborhood-scale version of this is actually fun, had been answered by people playing it before I wrote a line of code.
What was left was a tooling problem, and tooling problems are the safe kind to build. The app took over the map, the economy, the question deck, the timing, and the location updates, so that none of it had to be the point. It exists to clear away the administration and leave more room for the suspense.
-
Seekers spend coins to buy a clue. The Hider is paid the same number of coins for answering it. -
The Hider spends those same coins on traps and power moves. Every clue the Seekers buy gives the Hider another move. -
Calm at rest, loud at the moment it matters.
What shipped
A SwiftUI client, a server-authoritative Postgres and PostGIS backend with 37 row-level-secured tables and 158 database functions, a web spectator view, a marketing site, load-testing tooling, and the release pipeline.
Counts verified against the repo, 21 July 2026.
-
7Weeks to TestFlight beta
-
40%Less websocket traffic
-
750Automated checks, Swift and database
-
24hDefault retention for player and session data
-
Setup is a join code and a circle on a map. No signup, no email, no printed materials. -
The Hider's own view. The Seekers' map is the same board with that pin removed at the database, not at the client. -
The tag only fires when two players are truly face to face. Making that reliable became one of the hardest technical problems in the product.
Product judgment
-
Five specced screens and a database table, deleted in one review.
Hider invites, buddy multi-select, and buddy invite modals all collapsed into a single self-serve toggle, on the grounds that the tap itself is the consent. The invite functions and the table went with them. I would rather delete a table than ship a confirmation dialog nobody needed.
-
No anti-cheat, on purpose.
No photo freshness checks, no GPS spoof detection, no referee flow. This is a game played in person among people who know each other, and trust lets you cut entire branches of UI and server validation. Disputes resolve the way they always have: let's just replay that round.
-
Declining end-to-end encryption, with an argument.
It would have been the impressive-sounding choice, but the server has to read coordinates to run the game at all, so encryption would have meant either breaking the product or building a facade. The real threat model for a family app with no signup is over-retention, not a hostile server operator. So I hardened retention instead: gameplay data purges within 24 hours of a session ending, and there is no cross-session identity to accumulate. The one exception is an opt-in playtest recording, off by default and deleted after seven days.
What changed when people played
The target users were in the room from the start. My sons helped invent the game, and their friends widened the loop once it reached TestFlight.
The Scanner started as my youngest son’s request: a tool that points you toward the Hider. The request was right and the literal solution was wrong. Uncertainty is the core mechanic, and an accurate bearing would have collapsed the game he was trying to improve.
So it shipped as a Seeker tool costing 30 coins, returning one deliberately fuzzed bearing per five-second scan on a two-minute cooldown, computed server-side so the exact hiding spot never leaves the server. The feedback is haptic rather than numeric: the pulses tighten as you point closer, so you sweep the phone across the horizon and feel for it instead of reading a number off a screen. He got the feature he asked for. The game kept the uncertainty it needed. Users report the problem accurately and the solution approximately, and telling those apart is the job.
My other son proposed the Jammer: a way for the Hider to block questions and push the Seekers off the trail. It shipped as a placed zone that blacks out the map and locks the question menu, with a nested disable ring the Seekers have to physically walk to and then clear with a minigame. A feature request became a different kind of play, one that pulls people off the obvious path and back into the neighborhood.
Then the loop got wider than I planned. My kids sent the TestFlight link to their friends without being asked, and I started hearing about a new hide and seek app from other parents I had never told about it. That is not launch-scale growth and I would not dress it up as any. It is unprompted spread inside the intended audience, which for a pre-launch product is the strongest signal available.
Giving feedback is deliberately cheap. A tester can screenshot from anywhere in the app and file it, and the build notes ask for a third category alongside broken and confusing: or just not fun. That third bucket is the one worth having. Broken produces a fix. Not fun changes the roadmap.
Three hard problems
-
The Hider’s location had to be unknowable to Seekers. That is a database property.
Seekers never receive the Hider’s coordinates, not live, delayed, or approximated. Game state is server-authoritative, and Hider pings are withheld at the database layer. The one directional hint in the game, the Scanner, is computed on the server and returns a bearing. The position it was derived from never leaves the server.
During beta hardening I tested the live access model from a Seeker’s role, and found the locked hiding coordinate readable through three independent paths: a direct query against the round row, the realtime publication fan-out, and an ungated function. I closed all three.
The lesson is where they were. Row-level security governed which rows a player could read, and said nothing about which columns rode the realtime publication or who could execute a function. Postgres grants EXECUTE to PUBLIC on every new function, and a changed signature creates a new function rather than replacing the old one, so a lock-down does not carry forward on its own. Each path needed its own control, and revoking default function access became a standing convention.
The party screen at watch.myneighborhoodgames.com. It polls, and it shows the board from the Seekers’ perspective. The Hider is not on it unless the Hider or their buddy shares a separate reveal link. -
GPS cannot tell you that two people are standing next to each other.
The tag is the emotional peak of every round, and GPS accuracy under trees and between buildings is tens of meters. So the catch mechanic does not use GPS. It uses ultra-wideband peer ranging through Apple's NearbyInteraction framework, the same technology behind AirTag Precision Finding, which gets sub-meter accuracy under two meters. Devices without the hardware fall back to Bluetooth signal strength with a wider radius.
Then the product decision that cuts against the technology: the app deliberately does not help you find anyone. The takeover only fires under a meter and a half, by which point the two players are already looking at each other, so it works as a celebration rather than a guidance tool. Finding is the player's job. The app's job is the moment.
-
Cost was not the first scaling constraint.
I built an instrumented match simulator that reproduces the real client’s network behaviour, so scale was measured rather than estimated from a spreadsheet: actual HTTP calls, realtime messages, database writes, and concurrency. The useful finding was that the infrastructure bill is not what breaks first. The realtime message rate is.
Peer positions had been riding change events on the highest-volume table in the system, which produced oversized write-ahead-log frames and a pipeline that fell over at a realistic player count. I took that table out of the Postgres publication and replaced it with a throttled broadcast, asymmetric by design: Seeker ticks carry a position and apply on receipt, while Hider-side ticks are empty pokes that trigger a policy-filtered refetch. The Hider’s coordinates never ride the broadcast wire at all. Websocket traffic fell 40%. Privacy and performance wanted the same architecture, which does not happen often enough to pass up.
An AI-native product operating model
The output came from a practice, not ad-hoc prompting: specs and implementation plans committed to the repo as first-class documents, written behavioral guidelines for AI contributors, a separate git worktree per feature, and pure logic factored out of stateful classes so it could be tested without the hardware.
What stayed human was the part that decides: scope, architecture, which tradeoffs were acceptable, and whether the result was good enough to ship. AI shortened the distance between deciding something and having it. It did not do the deciding.
The honest framing: the AI did not build this. The judgment calls were the actual work.
What I am measuring next
The beta has produced a strong qualitative signal and not launch-scale product metrics. The spec sets targets: session completion, a median hide of fifteen to thirty-five minutes, whether the economy gets used rather than ignored, and families starting a second session within the month. Those are targets, not results. They have not been instrumented at scale, and the next phase is finding out whether the experience holds outside the community that invented it.
What is instrumented is pointed at decisions rather than at a dashboard. The shop logs one row per card appearance, including the cards players look at and decline, because the pass rate is what exposes a pricing or balance problem. An opt-in playtest mode can record a whole session for design review, off by default, behind a consent banner and a persistent recording indicator, and held for seven days rather than the ninety originally specced.
The work I want
HIDE/SEEK is in public TestFlight beta. The operating model behind it is the work I want to take forward.
I’m looking for a principal product leadership role where product strategy, technical architecture, privacy, and execution have to be held in the same frame.