In April 2025, Josh threw together a daily film-link puzzle so we could play it on a road trip. People kept playing — small but real traction. In May 2026, we picked it back up with two new partners: Hyperagent as the design and strategy room, and Replit as the build environment. One week of work shipped sixteen things — including a complete gameplay logic reboot, a Movie Identity Card system, a watchlist feature born inside a badge concept, daily auto-posting infrastructure, a full GA4 + GTM analytics layer, a press page, and this case study.
The Movie Game started in the front seat of a car. Emily had carried the mechanic in her head for years — every movie has actors, every actor has been in many movies, so any two movies can be connected by a third. Six Degrees of Kevin Bacon, daily. Ahead of a long drive in April 2025, Josh used Replit to throw together a working prototype we could play on the road. It was a weekend build — deployed to a domain, shared with a small group of friends, functional enough to actually play.
And then we kept playing it. Friends kept playing it. A small, organic following formed around it. The prototype worked — it had real, if quiet, traction. We always meant to come back. Life got in the way for about ten months.
In May 2026 we picked it back up — this time with a clearer division of labor. Hyperagent re-imagined what Replit had built: the GTM thinking, the redesigns, the identity system we'd never gotten around to. Replit then built everything — the new logic, every redesigned surface, the integrations, the deploy. The prototype gave us the mechanic; the sprint gave us the product.
We brought the gut-feel direction. We knew how the game should be played. We said yes or no to feature ideas. We asked for changes based on the feel of the game and how — and when — to scratch a movie itch. Hyperagent turned those instincts into strategy docs, mockups, copy, and specs. Replit took the resulting plans and built them — including a complete reboot of the link/clue selection logic that we worked out together inside the Replit environment. Most days we ran ideas through Hyperagent in the morning and watched Replit ship them by afternoon.
One week. Sixteen things shipped or specced. That's the headline. The rest of this doc is what we made, why, and which AI did which part.
The starting product was simple and worked: a daily film puzzle where you guess the movie that shares a cast member with two clue films. Four rounds, three hint reveals across them, a share string at the end. After solving, you saw a stripped-down post-game screen with the answer and a link to the movie's full page (which itself was a quiet rabbit hole of Wikipedia-grounded trivia, soundtrack, cast, awards, where-to-watch — all already shipped). Tap "Play Again" and you dropped into Practice mode with the full puzzle archive — no 24-hour cooldown.
What was missing was everything around it. No identity system. No badges, no streak visualization beyond a number. No watchlist. The Statistics modal was a basic Wordle-clone screen. The post-game share moment wasn't optimized for virality. The "How to Play" was a wall of text. There was no analytics — we couldn't actually tell what players were doing. And there was no GTM plan beyond "tell some friends." We had a mostly great mechanic and a working game; we did not have a product designed to grow.
The original game pulled the connecting actor from anywhere in the link movie's full cast list — no weighting, no filtering. That sounds reasonable until you see it in practice: the algorithm might land on the eighth-billed actor in a mid-sized ensemble, someone who also happened to appear in a clue film with a small cast and a limited release. The connection was real. It was just one that almost nobody would recognize, on either side. Players couldn't get the "I knew that one" moment because the actor wasn't famous enough to recall, and couldn't get the "now I know" moment either, because the movies themselves weren't memorable enough to care about. The puzzle was technically solvable but emotionally unsatisfying — and that's the one thing a daily puzzle can't afford to be.
A clean division of labor emerged on day one and held all week: Hyperagent generated ideas, designs, and functional specs; Replit handled building, fine-tuning, testing, and deployment; we steered with gut-feel direction. Most surfaces below were drafted in Hyperagent in the morning and shipped through Replit by the same evening. A few of them — most notably the link/clue logic reboot — were Replit-led from the start, with Hyperagent feeding diagnostic ideas rather than designs.
Each card below names the work, the shipping status, and which AI did which half.
The first deliverable was a complete free go-to-market plan, written before any redesign work. The playbook ranked surfaces by ROI, established a four-week sequencing model, and called out the strategic positioning — most daily games punish enthusiasm with a 24-hour timeout; The Movie Game rewards it with unlimited Practice mode after the daily, plus a rich movie-page rabbit hole instead of a results screen. That single observation reframed every later pitch in the document.
It also established the anti-strategy: what we deliberately weren't doing. No founder TikTok. No public X-as-yourself. No paid social. No app store. No leaderboards. Saying no turned out to be half the value of the document — every later piece of work landed inside those constraints without re-litigating them.
Maybe the most significant under-the-hood change of the week. The original puzzle generator picked the link movie's actors at random from the full credited cast. The result: clue movies that were technically connected but often felt like a stretch — a 1996 single-scene appearance linking a 2024 lead role, or two unrelated supporting parts. Players solved it eventually but the "ahhh" of recognition was muted.
We rebuilt the actor-selection logic inside Replit to optimize for billing position, filmography depth, and cross-movie recurrence — picking the actors from the link movie whose presence in the clue movies is most likely to feel obvious in hindsight. The result: puzzles where the link, once you see it, is almost embarrassingly clear. Average solve rate climbed; hint rate dropped; the share-string distribution shifted toward earlier-round wins.
The play screen was rebuilt around a clearer game model. Three fixed hint slots — Hint N reveals automatically at the end of round N, no exceptions. The corner badge on each filled slot tells the story of that round: 💡 if the player took the hint, 🎞️ gold if they guessed wrong. Wrong guesses get their own row below the indicators, struck through, only appearing when made.
The hint counter button now uses ❓ instead of 💡 — keeping 💡 reserved for the corner-badge meaning ("I took the hint this round"). The whole surface becomes self-narrating: one glance tells you what round you're in, what you know, what you've tried, and how many reveals are still coming.
❓ vs 💡 separation that finally made the surface unambiguous.
hint_reveal, guess_attempt, and game_completion events via the GA4 layer with attempt-number + correct-boolean per submission.
The post-game moment is where players decide whether to share, whether to come back, and whether to tell anyone. The original was functional but under-loved. We rebuilt it as the central social surface of the entire game — share string anchored at the top, brand-blue accent, prominent share affordances by platform, streak ribbon, and a clear path into the rabbit-hole movie page.
Five executions of the concept were generated side-by-side so we could decide by comparison rather than abstraction. The chosen execution made the share-string the hero, with secondary surfaces (badges earned, watchlist quick-add, replay CTA) tucked below the fold.
post_game_modal_open, share with platform parameter) so every iteration is measurable.
Maybe the single highest-leverage design decision of the week. The share string had to look unmistakable in a feed, encode a complete game state in a glance, and trigger the same I-have-to-try-this reflex Wordle's green-yellow grid does. Five rounds of iteration to land on the right emoji vocabulary: ✨ for solving it, 💡 for a hint taken, 🎞️ for a wrong guess, 🎭 for a bust.
Hyperagent first proposed 💨 for the bust (smoke, fire-going-out streak metaphor). Josh wasn't sold, so Hyperagent floated a few alternatives — and 🎭 landed instantly: theater masks, cinematic specificity. It became both the bust signal and the framing for a card design ("the drama got you").
The clue titles are the hook. A non-player sees "Top Gun ↔ Mean Girls" in their feed and thinks how are those connected? That's the game explained in one line.
The emoji row is the story. Wrong guess, took the hint, solved in round 3. Anyone can read it.
The theater masks finish the row. Cinematic, thematically right, narratively kind. "The drama got you" reads better than "you lost."
The streak break is symbol + number. No English, copy-pastes clean across every platform.
The shipped Statistics screen — a single full-page surface stitching together every signal the player generates. Current streak crowned at the top, the canonical three-tile ledger below it (Played · Win Rate · Avg Rounds), the result distribution showing where wins land round-by-round, the live solver style with its contextual one-liner, the badge tray with the running unlock count, and a primary CTA to share the Movie Identity Card.
Everything on this surface derives from the player's own play history — no leaderboards, no comparisons, no social pressure. A simple toggle pairs the richer surface with a canonical numbers-only view, so the screen meets the player where they are.
localStorage — every streak count, every win-by-round bucket, every badge predicate, and every solver-style cascade is computed in the browser from the player's own device. No server round-trip, no account required, no analytics aggregate masquerading as personal stats. The screen renders synchronously from local state, which is why the streak crown lands the moment the modal opens.
Twenty badges across six groups and an eight-style solver classifier — a full identity layer threaded through the Statistics screen (§06) and anchoring the Movie Identity Card system (§08). Badges reward streaks, solving prowess, volume, content mastery, discovery, and watchlist behavior. Solver styles read the player's running play pattern and assign a single label that updates as the pattern evolves.
Every badge predicate and every style cascade is computed in the browser from the same Zustand store the game uses, so the player's identity surfaces the moment they earn it — no server round-trip, no waiting.
client/src/lib/badges.tsclient/src/lib/badges.ts. Predicates fire client-side from the persisted Zustand store the game already uses, so unlocks land instantly without a server round-trip.
Five identity-card concepts were generated side-by-side: The Plaque, The Folio, The Cover, The Poster, The Plate. Each carried a different metaphor for who the player is as a film-watcher. After comparison, The Plaque won — inset corner brackets, logo in a framed block, polished-metal gradient — partly because it felt earned (the plaque metaphor) rather than self-selected (the cover metaphor).
The card surfaces solver style, badge seals earned, streak signature, total puzzles, and a personal title. It's designed to be screenshotted and shared — a posting artifact, not just a profile.
This one wasn't on the original list. While working through the Identity system, we noticed that the "Watchlist Builder" badge implied a watchlist feature that didn't actually exist yet. The badge needed somewhere for the user to build. So we designed and shipped the Watchlist as its own surface — a video-rental-wall of posters the player has marked from past puzzles, opening into the rabbit-hole movie pages already shipped.
The Watchlist Builder badge progress strip lives just above the wall (Scout earned at 5 films · Watchlist Builder unlocks at 25), tying the page back to the identity system. Tapping any poster also surfaces a small new section on the detail page: "Why this is on your watchlist — Connected Whiplash and Mean Girls via Greta Lee in Puzzle #287 · added two days ago." The watchlist becomes a memory of the player's journey, not just an inventory.








/watchlist and /watchlist/:id), the Zustand slice for watchlist state, and the GA4 events (watchlist_add, watchlist_remove, watchlist_view, watchlist_detail_view) with source attribution so we can see which surfaces drive adds.
Tap to expand
The old How to Play was a wall of text. The new one is a three-panel walkthrough: what you're solving (the cast-link mechanic with a worked example), how the rounds work (auto-revealing hints, the corner badge vocabulary, wrong-guess rows), and what happens when you finish (rabbit-hole movie page, Practice mode, sharing). Skip-ahead from the first panel for returning players.
Critically, the share-string legend (🎞️ · 💡 · ✨ · 🎭) lives inside the modal as a small inline section — players who encounter a share string in the wild can decode it without needing to play first.
Tap to expand
Settings used to be a single Reset Progress button buried in a modal. Rebuilt as a dedicated screen organized into five sections: Gameplay (Hard Mode, Spoiler-Safe Share), Sharing (Default share target — Ask / X / Bluesky / Letterboxd / Reddit / Copy), Accessibility (Reduce Motion, High-Contrast Palette), Data (Export and Import progress as a JSON file, Install The Movie Game, Daily Reminder with a time picker, Auto-snooze when today's puzzle is already played, and the Reset Progress button), and About (tagline, dedication, Send Feedback link). Each setting carries a one-line description; defaults are sensible; the screen respects the player who just wants to play and the player who wants to tune.
The push-notification reminder system was wired up alongside Settings — a daily nudge at the player's chosen local time, fully opt-in, no email collection, runs on web-push with VAPID keys. Export/Import gives players insurance against device wipes without any account requirement.
setting_changed) so we can see which knobs players actually touch.
Every past puzzle now has its own discoverable URL with proper JSON-LD VideoGame + Movie structured data. Clue movies and link movies are marked up; cast members are linked; release years and titles are crawlable. Search engines can index the entire puzzle history, and individual puzzle URLs are shareable as deep links.
Also added an archive index page (/archive) with a list view and a calendar view. Past puzzles are playable via Practice mode directly from the archive — no 24-hour wait, just tap and play.
/puzzle/[number] and /archive), the metadata strategy (per-puzzle OG image generated via Satori with the answer hidden), and the calendar view layout. Wrote the index-page copy.
archive_open and replay_open via GA4.
A dedicated press page at /press — origin story, pre-approved quotes, brand assets (logos in 80/160/240px, screenshot library, OG images), the strategic positioning (the rabbit-hole win, Practice mode, schema-safe migration), and a contact email. Built so a journalist can fact-check, quote, and run a story without needing to email first.
Includes a checklist for ourselves of what an inbound journalist might ask, with pre-written answers. The page itself is now the asset linked from every cold pitch in the outreach playbook.
Press kit · themoviega.me/press Visit the hosted press pagethemoviega.me/press. Wired the brand-asset downloads. Routes added without disturbing the puzzle archive or the watchlist routes. Image optimization pipeline applied to every press-page asset.
We went from no instrumentation to a full nine-category GA4 layer in one sprint. Container GTM-WZRC3KHR, property G-V7HQGBVLMV. Categories: Lifecycle & navigation · Game lifecycle · Post-game surfaces · Sharing · Watchlist · Settings & data · Reminders · Install / PWA · Badges. All snake_case, no PII (guess strings never sent, no emails, no tokens). All pushed to window.dataLayer from client/src/lib/analytics.ts.
Every event is documented with when-it-fires, params, and gotchas — including dedupe rules, cardinality warnings, and the difference between our custom page_view (carries surface) and GA4's auto page_view. Looker Studio dashboard plan included: engagement overview, game funnel, difficulty insights, watchlist behavior, sharing, install/PWA funnel, reminders, settings, retention.
GTM-WZRC3KHR · Property G-V7HQGBVLMV · no PII · all snake_caseclient/src/lib/analytics.ts and connected to the dataLayer. Configured the GTM container, registered the custom dimensions in GA4 Admin, verified events in DebugView. Built the Looker Studio data source connection. Module-scoped guards in place for app_open and rabbit_hole_open to prevent React StrictMode double-fires.
The site now auto-posts a daily message to Bluesky and Tumblr at 8:00 AM ET — different content variant per day-of-week (clue-forward Mon/Thu, challenge framing Tue/Fri, yesterday's chain Wed, solver stats Sat, trivia teaser Sun) so the feed reads human, not bot. The Wed-reveal variant is the only one that ever spoils — all others stay spoiler-safe so the post itself is a hook.
X is queued but skipped for now. X's new pay-per-action API pricing makes write actions expensive at our scale, and the manual copy-paste-via-Josh's-phone approach is fine for now. We'll revisit once volume justifies the cost.
puzzle.number, puzzle.clue_a, puzzle.clue_b, yesterday's solver aggregates). Specified the spoiler-safety rules (only Wed reveals). Drafted the Tumblr tag set for algorithm pickup.
@atproto/api for Bluesky and tumblr.js for Tumblr NPF. Scheduled via node-cron with timezone-aware 7 AM ET trigger (8 AM ET adjustable). Failover logic in place: if either platform 4xx's, the other still posts. Logs every send to a daily audit table. X integration is built but feature-flagged off.
After the original GTM playbook landed, we needed it operationalized. v2 of the outreach playbook is a sequence of copy-paste-ready drafts: specific Reddit posts per subreddit (tier-1 permissive, tier-2 organic-only, tier-3 topical hooks); personalized journalist emails for ten priority contacts (Bergeson, Edwards, Webster, Kottke, Cheng, Broderick, Hickey, Polygon Discoveries, Letterboxd editorial, Griffin Newman); ten newsletters; eight podcasts; five founder cross-promo emails; an eight-item aggregator submission checklist.
Plus the updated Letterboxd playbook for 2026 — reflecting that the Letterboxd API is no longer granting write access for our category of project, so the strategy is manual brand-account + lists + the Journal editorial pitch + critic DMs. Three moves, all founder-driven.
For anyone evaluating Hyperagent + Replit as a build partnership for their own product: this is what's actually running in production at themoviega.me. The whole stack is JavaScript, hosted end-to-end on Replit, deployed via Replit autoscale.
Vite 5@hookform/resolvers@fontsource)tsx in dev / esbuild-bundled in proddrizzle-zod against PostgreSQL 16 (Neon serverless driver)express-sessionmemorystore for session backing@resvg/resvg-wasm for generating share imagestailwindcss-animate, @tailwindcss/typographynodejs-20, python-3.11, postgresql-16)cartographer, runtime-error-modal, shadcn-theme-jsonshared/schema.ts — single source of truth for DB tables, Zod insert schemas, and TS types consumed by both server and clientEvery choice in the table above prioritizes one of three things: (1) fast iteration with AI assistance — TypeScript-everywhere means Hyperagent's specs and Replit's generated code stay typed-consistent end-to-end; (2) low-ops production — Replit autoscale + Neon serverless mean no infra babysitting; (3) the v1 → v2 storage shift — Drizzle + the shared schema.ts file replaced v1's cached-only client storage as the structural backbone that enabled the SEO archive, analytics, watchlist persistence, and the auto-posting cron.
Asked at the start of the week, "what's the most important thing we'll ship?" — we'd have answered wrong. The work didn't unfold by priority; it unfolded by conversation. Each piece suggested the next. Here's the sequence of lightning strikes, in order.
We almost started with design. We're glad we didn't. Writing the free GTM playbook first forced us to articulate who we are before redesigning a single screen. The rabbit-hole win and Practice mode emerged as the strategic moat — and once those were named, every later design decision had something to optimize toward.
Most of the sprint ran Hyperagent-first, Replit-second. This was the inversion. The diagnostic — "the connections feel like a stretch" — went straight into the Replit conversation, and Replit drove eight rounds of heuristic tuning. The result: puzzles where the link, once you see it, is almost embarrassingly clear. Hardest work to evaluate in a screenshot. You feel it when you play.
Hyperagent proposed the emoji vocabulary — ✨ solved, 💡 hint, 🎞️ wrong guess — and first floated 💨 for the bust state. Josh wasn't sold, so Hyperagent floated alternatives. 🎭 landed instantly: theater masks, cinematic specificity, and a card framing too ("the drama got you"). A perfect example of the partnership: AI generates the systematic options, the human picks the right metaphor.
Once the share-string was right, the post-game screen had to be rebuilt around it. Five comparative concepts; the chosen one made the share-string the hero. Secondary surfaces (badges earned, watchlist quick-add) followed naturally. The post-game's structure then suggested the Stats screen should mirror it — same hierarchy, different content.
The Stats redesign needed more than tiles. Hyperagent proposed badges; the badges suggested solver styles; both needed somewhere to live. That place became The Plaque — chosen from five card concepts because the "earned, not self-selected" metaphor felt right. We didn't set out to build an identity system. We set out to fix a Stats modal. The identity system fell out of the work.
The one we love telling. Hyperagent generated a Watchlist Builder badge in the identity spec. We looked at it and went, "wait — there's no watchlist yet." The badge implied a feature that didn't exist. So we built it. The Watchlist page is now one of the most-loved surfaces — a video-rental wall of films marked from past puzzles, opening into the rabbit-hole movie pages we already had. The badge designed the feature.
By mid-week we had a redesigned game, an identity system, and a watchlist — but the surfaces around them felt loose. How to Play was a wall of text; Settings was a single Reset button buried in a modal. Cleaning both up in parallel was the moment the work stopped being a collection of pieces and started feeling like a coherent product. Putting the share-string legend inside How to Play was the small detail with outsized effect.
The single hardest piece of design to land. The auto-reveal hint model — Hint N reveals after round N, badges show what the player did that round — sounds simple. Four iterations and seven corrections later, the breakthrough was the corner-badge separation: 💡 means "I took the hint this round," so the hint counter button couldn't share the symbol — it became ❓. Suddenly the surface stopped fighting itself.
By Friday we had a beautiful product with no way for anyone to find it. The outreach playbook v2 and the daily auto-posting infrastructure shipped together. Hyperagent wrote thirty-plus draft emails and the five auto-post variants; Replit wired Bluesky and Tumblr APIs to a cron. The product can now market itself daily, without us, while we focus on the next phase.
The discipline of refusing to build certain things mattered as much as the design of what got built. Every "not now" is a Phase 2 unlock — the system grows by addition, not re-architecture.
Saying no is half the strategy. — The anti-strategy section of the GTM playbook
One week of two humans and two AIs shipped what would have taken a product team a full quarter or more. Idea → concept → production is faster and more accessible than ever — to anyone with the imagination and the token budget to run it.