Inspiration

Most of us lose hours every day to short-form video, and screen-time limits only make us feel guilty. We flipped the question: what if your phone made you excited to put it down?

The Last Voyage is a co-op pirate adventure where your real friends are your crew and you all share one ship. The ship only sails when you go live your life.

What it does

Everything you do in real life becomes Moves, and you spend Moves exploring islands and fighting bosses with your crew.

  • Steps (Android Health Connect): 1 Move per 1,000 steps, up to 10 a day.
  • Quests: walks, workouts, reading, time with friends, hobbies and more. Up to 6 Moves a day, on the honor system with hard caps.
  • Free Moves: 2 every day, so nobody is ever locked out.
  • Calm Seas streak: stay under your short-form limit (60 swipes and 20 minutes by default) and your Moves multiplier grows. If you don't open TikTok, Instagram or YouTube at all, Shore Leave adds a bonus on top.

Today's Moves:

$$ M = \left\lfloor \big(2 + \min(10, \lfloor s / 1000 \rfloor) + a\big) \times \left(1 + 0.1 \cdot \min(c, 10) + 0.25 \cdot \ell\right) \right\rfloor $$

where \( s \) is your steps, \( a \le 6 \) is your quest Moves, \( c \) is your Calm Seas streak in days, and \( \ell \in {0, 1} \) is Shore Leave.

Example: 6,200 steps, a walk and a workout, on a 5-day streak gives \( \lfloor (2 + 6 + 3) \times 1.5 \rfloor = 16 \) Moves.

Breaking a streak never punishes you. It only resets the bonus. You never lose Moves, items or progress.

On the island

  • Each island is a seeded hex board of radius 5 (91 hexes) with fog of war, terrain costs, hazards and loot.
  • Tap a hex and the cheapest path is taken and paid in Moves.
  • At the center is a boss whose HP is shared and persists, so your crew chips away at it across days.

Your fighting stats come from your real-life skills:

$$ \text{HP} = 25 + \tfrac{\text{Grit}}{2}, \qquad \text{ATK} = 4 + \tfrac{\text{Grit} + \text{Craft}}{20}, \qquad P(\text{crit}) = \min!\left(0.5,\; 0.05 + \tfrac{\text{Charm}}{300}\right) $$

So reading, working out and seeing friends literally make your pirate stronger.

The crew's companions

  • The Tidekeeper: a voiced AI narrator. Hold to talk and ask "how many Moves do I have?" or shout "strike!". He can also summon real-world events onto the island, grounded in live web search with source links.
  • The Shipwright: shows the ship's speed for the day (= your Moves) and the next best real-life action to go faster. He never scolds.
  • A theme song for every player, composed by ElevenLabs Music from your top skill, your island and your streak.

How we built it

  • App: React Native + Expo SDK 58, Expo Router, strict TypeScript. One codebase builds the Android app and an installable web app for iPhone and desktop.
  • Scroll tracking: a Kotlin Expo module running an Android Accessibility Service plus Usage Access. It counts YouTube Shorts swipes and minutes on the device itself. It reads only screen-layout IDs, never text or content, and only daily totals leave the phone.
  • Game rules: a pure TypeScript package shared by the app and the server, covered by Vitest tests: Moves, streaks, island generation, combat and the Shipwright.
  • Server: Node + Hono + MongoDB Atlas, with JWT sessions and zod validation. Voice replies and theme songs are stored in Mongo with TTL expiry.
  • Auth: SSOJet (OIDC + PKCE).
  • AI and voice:
    • OpenAI gives the Tidekeeper a brain (structured JSON actions) and runs the Game Master events with web search.
    • ElevenLabs handles text-to-speech, speech-to-text and music generation.
  • Deploy: Vercel serves the static web build plus a serverless API function.

The Tidekeeper never decides outcomes. The model proposes an action as structured JSON, and the game code checks it and applies it:

// questions never spend Moves; only game code applies actions
if (intent.kind === 'question') action = 'none';

Challenges we ran into

  • Counting Shorts swipes. YouTube fires almost no usable scroll events. We detect a swipe when the settled video in the Shorts pager changes, checked every 400 ms, using layout IDs only.
  • Keeping the AI honest. Early versions spent Moves when you only asked a question. We moved every rule into code. The AI only narrates.
  • SSOJet callbacks. SSOJet accepts only http(s) callbacks, so we built a small server bridge page that hands the sign-in back to the Android app.
  • iPhone without a Mac or an Apple developer account. We shipped a web build of the same codebase that installs from Safari with Add to Home Screen.

Accomplishments that we're proud of

  • Real-life activity drives a full game loop: earn Moves → explore → loot → fight a shared boss → conquer.
  • Privacy-first tracking that never reads what's on your screen.
  • A fully voiced, context-aware narrator, and a unique theme song for every player.
  • "Never punish life": no lost progress, ever.

What we learned

  • Rewards beat guilt. A growing streak bonus feels far better than a screen-time warning.
  • Code decides, AI tells the story. Keeping game rules out of the model made the AI fun and trustworthy.
  • Android accessibility APIs are powerful but quirky. Every app version can change its screen layout.

What's next for The Last Voyage

  • Instagram Reels and TikTok tracking.
  • Life-event story cards, journal → personality traits, and ship rooms that upgrade your hull.
  • Crew heading votes, rival crews, and a voiced morning recap.
  • Monthly themed islands, plus the Lodestar: at year end, the top Legend pirate earns a crown, a legendary ship for their crew, and gets to name an island in next year's sea.

FIND THE WORLD'S PRIZE: LODESTAR! ⚓

Built With

  • anthropic
  • claude
  • elevenlabs
  • openai
Share this project:

Updates

Submission history