Christopher Vistal, home
GitHub LinkedIn
โ† Back to blog
Blog  ยท  side project

How I Built a Multiplayer Phone Game for My Daughter with Claude

My 4-year-old daughter wanted to play with us on our phones, like a multiplayer game. One prompt to Claude gave us the first version. Every feature after that came from the people playing it: my daughter, my wife, and now my workmates.

Role
Idea, play-testing and every feature request; code written with Claude
Stack
HTML, CSS, JavaScript, Netlify Functions, Netlify Blobs, Web Speech API
Status
Played by my family and my workmates

Published

Illustration of a phone showing a grid of picture tiles, surrounded by a star, a check mark, a small flag, a second phone and three game pieces on a stone base.
Illustration of the game: a grid of pictures to find, a countdown on a second phone, and three players.

When my wife and I are on our phones, my daughter wants in. Not to watch a video, but to play with us, the way a multiplayer game works: everyone on their own screen, all in the same game. She is four, so it had to work without reading, with big buttons, and it had to be something she could actually win.

So I built one with Claude. This post is the story of how it started, how the people playing it shaped every feature, and a short look at how it works under the hood.

It started with one prompt

This was the whole first prompt:

let's create a fun applications multiplayer that we can play with my kid 4 years old and wife what do you suggest?

Claude came back with a few ideas that fit a four-year-old: a shared drawing board, a bubble-popping game, an animal sounds game, and a treasure hunt. I picked the treasure hunt. The phone shows a color or a shape, says it out loud, everyone runs around the house to find one, and taps Found it! Every find fills a shared star meter, and confetti plays when the family reaches the goal.

That first version was playable the same night. It was not the game we play now. Everything after that came from watching people play.

Then the players started asking for things

My job became simple: play, watch, and write down what people asked for. Then I described each change to Claude in a sentence or two. These are the requests, roughly in the order they came:

  1. Taps did not show on the other phone. A tap on one phone did not show up on the others. I moved the game to Netlify: one page plus a small Netlify Function that keeps the shared game in Netlify Blobs. Every phone checks for changes about every second and a half.
  2. Taps felt dead on mobile. A tap gave no visible feedback. Buttons now press down, and tapping a picture stamps a big green check on it.
  3. Make it a real game. A small color swatch instead of a giant one, six pictures per stage with wrong answers mixed in, a host who controls the game, a Next button that appears only when everyone is done, 10 to 30 stages, and a ranking from first to last at the end.
  4. Everyone starts at the same time. Each stage now opens with the voice saying what to find, then a 3-2-1-GO countdown that lines up on every phone. The pictures stay face-down until GO.
  5. Only pictures nobody can argue about. We removed every picture that could be argued: a crab that looks orange, a spider that looks grey. A square is never a wrong answer in a rectangle round.
  6. More than colors and shapes. A game picker on the start screen, plus Animals (sea, birds, farm, safari, bugs) and Flags. Flags is a matching game: the flag shows during the countdown, and you find the same one, so a four-year-old can play it too.
  7. No guessing. Two wrong taps in a row and you are out for that stage, no stars. A right tap in between resets the count.
  8. No peeking. The countdown cover was slightly see-through. Now it is solid.
  9. Less waiting. The host can skip ahead 10 seconds after GO, and can remove a player who left.

Not every idea stayed. We tried a second game, Color Spy, where you find a real object in the room and the host approves it. We removed it. Taking things out is part of the process too.

Lesson The first prompt gets you something playable. The game got good because the people playing kept telling me what was wrong, and each fix was one short request.

How it works

The whole game is one HTML page and one serverless function. There is no build step and no database server.

Design decisions

The rules were shaped by who was playing: a four-year-old and a group of competitive adults, in the same game.

Practical examples

Simplified example. The snippets below show the two techniques that keep every phone in the same game. They are not the full production code.

1. Build the same stage on every phone from a seed

// Small seeded random number generator (mulberry32)
function rng(seed) {
  let a = seed >>> 0;
  return () => {
    a = (a + 0x6d2b79f5) >>> 0;
    let t = a;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

function shuffle(items, random) {
  const a = items.slice();
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

// Every phone gets the same seed from the server, so every phone gets the same order.
shuffle(["๐ŸŽ", "๐ŸŒ", "๐Ÿธ", "๐Ÿณ", "๐Ÿ‡", "๐Ÿท"], rng(seed + stage));

2. Count down to the same moment on every phone

let offset = 0, best = Infinity;

async function syncClock() {
  const sent = Date.now();
  const { now } = await (await fetch("/api/game")).json(); // server time in ms
  const received = Date.now();
  const roundTrip = received - sent;
  if (roundTrip < best) {             // the fastest round trip is the most accurate
    best = roundTrip;
    offset = now - (sent + received) / 2;
  }
}

const serverNow = () => Date.now() + offset;
const msUntilGo = (goAt) => goAt - serverNow(); // 3000..0 is "3, 2, 1", then GO

Conclusion

What started as my daughter wanting to play with us turned into a game my workmates play too. I did not plan most of its features. The players did, one small request at a time, and Claude turned each one into working code.

The takeaway: start with something playable, put it in front of the people who will use it, and let them tell you what to build next.

What I would do next

References and further reading

Have an idea you want playable this week? I build web apps end to end, from the first prototype to the version people use every day.
Start a conversation