Inspiration

Finding someone who shares your interests is solved. Talking to them isn't. The chat goes "hey" → "hey" → silence. Apps like Bumble BFF and Series decide who you meet, and AI openers write the first message. Nothing helps with messages 2 through 50.

About 1 in 2 US adults report loneliness. Time spent in person with friends fell from about 60 minutes a day in 2003 to 20 in 2020, and for people aged 15–24 it fell almost 70% (U.S. Surgeon General, Our Epidemic of Loneliness and Isolation, 2023).

Riff's design comes from three findings:

  • Asking follow-up questions increases liking (Huang et al., 2017). Riff gives connection points for follow-ups and callbacks.
  • Closeness builds when questions escalate gradually (Aron et al., 1997). Nudges climb from light to opinions to deep, then drop back to light.
  • People expect deep talk with strangers to be more awkward than it is (Kardas, Kumar & Epley, 2022). Deep prompts are in the mix once both players have earned connection points.

What it does

Riff is a social app for meeting people through conversation, with profiles, people search, instant matching and friends. At its core is the chat: an AI host steps in when the conversation stalls, scores both players for being curious about each other, and coaches each of them afterwards.

  1. Onboard: one question per screen: name, age, hometown (checked to be a real place), a goal, a this-or-that, and your top 3 interests out of 419.
  2. Profile: a public profile with your hometown, interests, up to 3 prompts ("My hot take…", "Ask me about…") and up to 3 favorites (a game, a show, an artist…). Each is checked on save: real places, real favorites, no contact info. Your last name and age stay private.
  3. Find people:
    • Match me always pairs you. If another real person is on Match me, you're paired with them. Otherwise, after about 3 seconds, you're paired with an AI persona that shares at least one of your interests and brings one new one. Their interests fly into your orbit, shared ones merge and glow, then "It's a match".
    • Search by vibe: "elden ring" finds gamers. Tap someone to see their profile and invite them. Invites last 60 seconds.
    • Invite by link or code, or Test with AI to practice.
  4. Chat: it feels like iMessage: tailed bubbles, typing dots, instant send, and voice messages transcribed to text.
  5. Nudges: an intro nudge opens the chat. After that the AI stays quiet while the conversation flows and drops in a nudge when it stalls. A nudge is a text prompt, an AI-generated image with a question about it, or a mini game (Guess their pick, Two truths and a lie). Each one is written from what these two people have actually said, climbs in depth from light to opinions to deep, and has a countdown.
  6. Points: only answers to nudges score. Speed is computed in code; quality and connection are judged by the AI. Connection means engaging with your partner: follow-ups, callbacks, building on what they said. Points pop in when the timer ends.
  7. Bonus mode: when one player falls 25 points behind, the next 2–3 nudges move to their interests so they can catch up. Nobody is told.
  8. End: first to the target score wins, or either player taps End. The end screen shows Moment Spotlight cards: the best moments of the chat, quoted word for word.
  9. After: each player gets a private coaching report: what they were good at, where they fell flat, and what to improve, quoting their own messages. "Coach me" opens a 1:1 chat with an AI coach that teaches what they missed.
  10. Friends: add each other at the end of a chat. Invites reach you on any screen, and you can reopen previous chats.

About the people you meet: Search and Match me include 300 AI personas with generated names, bios and photos, played by the AI. They keep Match me from ever leaving you waiting while few real people are online, like at a hackathon. They aren't labeled in the app. Match me always pairs you with a real person first when one is waiting.

How I built it

  • Stack: Next.js 16 (App Router), TypeScript, Tailwind 4 and shadcn, hosted on Vercel. Supabase provides Postgres, Realtime, anonymous auth and Storage for voice messages.
  • No game server: while a chat is live, both clients call /api/tick every second. Each tick closes a nudge early once both players have answered, scores it when its timer runs out (compare-and-set, so concurrent ticks are no-ops), checks for the end, and decides whether the next nudge is due. A unique constraint on (chat, nudge number) prevents double pop-ups.
  • Writing a nudge: code rules out repeats (for example, at most one image in any 3 nudges). Jev picks the kind that fits the moment: a mini game when replies get short, an image for a change of scene. The writer drafts 3 candidates, each naming the specific thing from the chat it builds on, and Jev picks the one these two would most want to answer. Nudges are written ahead (images 2 ahead), so nobody waits on a model.
  • What stays in code: speed points, mini-game scoring, when Bonus mode switches on, pacing (when a nudge may pop), and the depth arc.
  • Tests: Vitest over the engine: pacing, scoring, Bonus mode, matching, mini games and coaching.

Models: which does what

Muse Spark (Meta Model API): the primary model. Any error retries on Grok automatically.

  • Writes every nudge ahead of time, with 3 drafts each: text prompts, image scenes and their questions, Guess-their-pick questions with 4 options, and Two truths themes.
  • Moment Spotlight: picks and quotes the best moments.
  • The end-of-chat summary.

Grok (xAI): first for anything time-boxed (~1 s against Muse Spark's 5–21 s). It falls back to Muse Spark.

  • Running notes on the live chat.
  • Deciding whether both players answered, so a nudge can close early.
  • Scoring: quality 0–10 and connection 0–5, with reasons.
  • Rewriting the next nudge once the last one is scored, using the new answers.
  • Playing the AI personas: chat replies, Guess-their-pick answers and Two truths statements. It also runs Test with AI and the coach chat.
  • The coaching report.
  • The hidden profile.
  • Picking the best-fit person when several real people are waiting on Match me.
  • Writing the 300 personas' prompts and favorites (one-off script).

Muse Image: image nudges (~12 s, so they're generated 2 nudges ahead) and the personas' profile photos. Grok Imagine is the fallback for both, then a pre-generated pool of tagged images.

Grok speech-to-text: voice messages.

Jev (TypeSafe's System One model): one-pass scoring, in about half a second.

  • Search: scores everyone (the live queue and 300 personas) for fit, or for the vibe you typed, in one call.
  • Match me: ranks personas by fit before the mix rules apply.
  • Choosing the kind of each nudge.
  • Picking the best of the 3 drafts.
  • Checking your hometown at onboarding.
  • Checking profiles on save.
  • Fallbacks: word overlap for search, a fixed rotation for the kind, and the first draft.

Context: how Riff gets to know you

What the AI knows

  • The live chat: the latest messages.
  • Running notes: as messages arrive, Grok updates notes on each player (facts, opinions, stories: "has a corgi named Mochi"), the current topic, unanswered questions and running jokes.
  • Nudge history: every earlier nudge and how well each player answered it.
  • Learned interests: the scorer picks up new interests from answers ("minecraft"), on top of the 3 you chose at signup.
  • Public profiles: hometown, interests, prompts and favorites. Both players can see them.
  • Chat summaries: at the end, each chat is summarized per player: what they shared, what clicked, what died, and references they missed.
  • Hidden profile: rolled up from your last 20 chat summaries: what you enjoy, what falls flat for you, and what you tend to miss. Never shown to anyone.
  • Kept out: last name and age never reach a model or another player. Contact details, addresses and handles are left out of notes and summaries. Every prompt treats profile and chat text as data, never as instructions.

How it's used

Better nudges

  • Each nudge builds on the notes: it digs into something one of you said, picks up an open question, or calls back to a running joke. Every draft has to name the thing it builds on.
  • Nudge history steers the topic. If you both answered weakly, the topic moves on. If one of you was strong and the other weak, it's that player's ground. If you were both strong, it goes deeper or comes back from another angle.
  • Public profiles are fair game: a nudge can play off a prompt answer or pit your favorites against each other.
  • Your hidden profile only chooses topics: more of what you enjoy, less of what fell flat or what you didn't get. A nudge never mentions or quotes it.
  • Deep questions come only once you've both earned connection points.
  • Jev picks the best of the 3 drafts using both players' interests (including the learned ones) and notes.

Bonus mode: when you fall behind, nudges are built around your interests, including ones learned during this chat, and things you've said.

Fairer scoring: the scorer reads the notes, so a callback to something said 20 minutes ago earns connection points, and repeating yourself doesn't earn quality.

Better search: Jev compares you (your interests, hometown, prompts, favorites, and what your hidden profile says you enjoy) with every person's public profile. Typed searches match by vibe, not keywords.

Better matches

  • Among real people waiting on Match me, the matchmaker weighs interests and each person's past chats, and avoids topics that fall flat for either person.
  • AI personas are ranked by fit, then by the mix: at least one shared interest and one new one. It skips anyone into a topic that fell flat for you, and anyone from your last 5 chats.
  • Personas chat in character, from their own interests, prompts and favorites.

Better endings: Moment Spotlight uses the running jokes to find the moments that mattered.

Better coaching

  • The coaching report reads the chat, the notes and how you answered each nudge. It quotes only your own messages, checked in code, and never quotes or judges your partner.
  • The coach's lesson comes from what fell flat in that chat.
  • Coach me without a report catches you up on the references you missed: your latest chat first, then the patterns in your hidden profile.

Better over time: each chat's summary feeds your hidden profile, so your next chat's nudges, matches, search results and coaching start from what worked before.

Challenges I ran into

  • Latency: Muse Spark took 5–21 s per call. Points that pop 20 seconds after the buzzer feel broken. Anything time-boxed now goes to Grok first, and Muse Spark only does work that writing ahead can hide.
  • Loose instruction-following: Grok would skip or reword required parts of a nudge. Now the model writes only the creative part, and code assembles the required pieces.
  • Realtime ordering: loading state and then subscribing dropped messages sent in between. State now loads only once the Realtime channel is ready.
  • No server clock on Vercel: the whole game loop runs on client ticks with compare-and-set writes, so two clients ticking at once never score twice.
  • An empty app at a hackathon: Match me falls back to an AI persona after about 3 seconds, ranked by fit, mixing shared and new interests, and skipping recent partners and topics that fell flat for you.

Accomplishments that I'm proud of

  • The AI's job is to get two humans talking: it writes prompts, judges answers and coaches, then gets out of the way.
  • Nudges are specific. Every draft has to name what it builds on from this chat.
  • The scorer can reward an answer like "Sharknado 3, unironically", which no rule-based system can.
  • Match me never leaves anyone waiting.
  • Built solo in one weekend.

What I learned

  • Latency shapes the design more than model quality does. Writing ahead and splitting fast from slow models mattered more than prompt tuning.
  • Anything that must be in the output belongs in code. The model should supply only the creative part.
  • Timing matters as much as content. A good nudge in the middle of a flowing chat kills it, so pacing waits for a real lull.

What's next for Riff

  • Recommendations: who to talk to next, based on who you connected with.
  • Per-pair learning: a bandit (Thompson sampling) over nudge kinds, rewarded by the messages after a nudge and by connection points.
  • Double-tap reactions and meme-audio nudges.
  • In-person mode: Riff hosts two people at a table, by voice.
  • Launching with Georgia Tech students.

Built With

  • grok
  • grok-imagine
  • jev
  • meta-model-api
  • muse-image
  • muse-spark
  • next.js
  • postgresql
  • shadcn-ui
  • supabase
  • supabase-realtime
  • tailwindcss
  • typescript
  • vercel
  • xai
Share this project:

Updates

Submission history