BOOK A CALL

All projects

Case study

Whimsy

Free audio walking tours, written by a model, fact-checked against real sources, and narrated by a small open-weights voice running on a Mac in the house.

Platform
iOS · watchOS
Stack
SwiftUI · Python · MLX Kokoro · nginx
Status
TestFlight, build 2
Scale
2,300 lines Swift · 900 watch · 2,500 lines of tour script

The problem

Paid audio-tour apps are expensive per city, thin outside the famous places, and written as a list of facts rather than as a walk. A self-guided tour that actually works has to be paced for someone moving between points — it has to say “walk toward the facade and climb the stairs, about three minutes” and then stop talking.

The bet

Scripts written by a model, fact-checked by a second pass against real sources, narrated by a small open-weights TTS model on hardware already sitting in the house. That combination puts the marginal cost of a tour close to zero, which is what makes fifty places free and plausible.

The quality bar is a hand-written reference tour of St. Peter’s: ten stops, 1,650 words, about twelve minutes of narration, every stop ending with directions to the next.

Decisions

  1. Three depths from one script

    The same walk is offered as Highlights, Essentials and Full, compiled from a single Markdown file with +++ markers. A tourist with twenty minutes and one with a whole afternoon want the same route and different amounts of talking — and maintaining three scripts per place would have killed the catalog. Identical depths collapse, so a short tour never offers the same walk three times.

  2. Logistics are fact-checked as carefully as dates

    Entrances, one-way flows, timed-entry order, stairs, security lines. A wrong year is an embarrassment; a wrong turn strands someone in a foreign city.

  3. Units follow the place, not the reader

    A tour of Kyoto is in metres, because that is what the signs say.

  4. No GPS triggering in v1

    Indoor GPS fails in precisely the buildings the tours care about. The player pauses after directions and waits for “I’ve arrived” — or a headphone next-track press — with auto-continue available for people who prefer a short gap.

  5. Per-stop audio files

    Skip, scrub, “start at stop 7” and resumable downloads all become trivial, and re-synthesising one edited stop touches one file.

  6. Map snapshots as cover art

    No photo licensing problem, and every tour gets art the day it is written.

The look

The design system is the product’s personality, and it is deliberate rather than decorative. One file holds all of it: a yellow page, pink display type in Baloo 2, and saturated card tints cycled through a list so a catalog reads as a set of toys rather than a table of rows. Text colour is chosen per tint by a function, so the lime card gets ink and the rest get white — legibility is enforced by the type system rather than by remembering.

Nine mascot poses are wired to app states, so the character reacts to what you are doing rather than sitting in a corner. The watch keeps the same shapes at smaller numbers, from the same file, through one platform guard on the geometry constants. One design system, two platforms, no fork.

The engineering story

  1. The pipeline is the product

    Compile, synthesise, publish — with a per-chunk content-hash cache. Editing a sentence re-renders that sentence’s chunk and nothing else; changing the voice re-renders the catalog. That property is what makes iterating on fifty tours affordable.

  2. The catalog is the authority, not the app

    A tour is available only when its JSON and every audio file exist on disk. The app cannot advertise something it cannot play, because it is not the thing deciding.

  3. QA is automated because listening does not scale

    The pipeline transcribes the rendered audio and diffs it against the source script. It is how a swallowed paragraph gets caught without anyone sitting through twenty-five minutes of narration.

  4. Assets are code

    Every mascot pose and the app icon regenerate from source art by script. The matting flood-fills inward from the border rather than colour-keying, because a colour key ate the character’s teal body against a blue plate and its red headphones against a coral one.

Where it stands

Ten of the fifty tours are written, fact-checked and rendered: Indianapolis, Grand Central, Westminster, Notre-Dame and the Île de la Cité, the Roman Forum, St. Peter’s, the Acropolis, the Old City of Jerusalem, Fushimi Inari and Sensō-ji. Build 2 is on TestFlight with the watch app included. The remaining forty places are catalogued and marked coming soon, which the app renders honestly.

Screens

The yellow page, the pink Baloo 2 wordmark, and the character. Card tints cycle through blue, coral, lime, pink and teal so a list of tours reads as a set of toys.
The yellow page, the pink Baloo 2 wordmark, and the character. Card tints cycle through blue, coral, lime, pink and teal so a list of tours reads as a set of toys.
The decision that most needs a picture: one script, three walks. Highlights 15 minutes, Essentials 29, Full 56 — with stop count and distance recalculated for each.
The decision that most needs a picture: one script, three walks. Highlights 15 minutes, Essentials 29, Full 56 — with stop count and distance recalculated for each.
The player. Per-stop audio, 15-second skips, speed, and the Auto-continue toggle that decides whether the tour waits for you at the end of each stop.
The player. Per-stop audio, 15-second skips, speed, and the Auto-continue toggle that decides whether the tour waits for you at the end of each stop.
Words opens the narration the way a music app shows lyrics: one line lit at a time, sweeping word by word, and a tap on any line jumps the audio to it.
Words opens the narration the way a music app shows lyrics: one line lit at a time, sweeping word by word, and a tap on any line jumps the audio to it.
Practical notes and the route, each stop carrying its narration length and the walk to the next one.
Practical notes and the route, each stop carrying its narration length and the walk to the next one.
Top tours and the location prompt. The mascot’s pose changes with what the screen is for — pointing at the location card, waving at the headphones prompt.
Top tours and the location prompt. The mascot’s pose changes with what the screen is for — pointing at the location card, waving at the headphones prompt.