Learning games I built for my 3-year-old. Letters and numbers, taught through the NFL, because that's what he was actually excited about.
Hero shot: iPad running the Eli's Games home screen with game cards, or a grid of in-game screens across letter-match, number-match, NFL team match, NFL letter logos, farm animals, and colors
Eli was starting to recognize letters and count at school, but some letters and most double-digit numbers kept tripping him up. He'd get frustrated and check out. I was homeschooled my whole life, so finding sideways paths into learning feels natural to me.
Whatever I built, the voice had to feel like a real person talking to a kid. Flat TTS kills engagement instantly. So the voice system became the core of the whole thing.
He was already obsessed with team logos and uniforms from watching games with me. So I wrapped the practice inside the obsession. Number match tuned for the 20s and 30s because that's what jerseys showed on TV. Letter sounds practiced through the first letter of team names. He didn't know he was practicing.
Letters, numbers, NFL teams, NFL letter logos, farm animals, and colors. All built on the same audio, UI, and generation system. A drawing game is in progress.
Eli was a little over three. He was starting to recognize letters and count at school, but some letters and most double-digit numbers kept tripping him up. He'd get frustrated and quit. The kid stuff in the App Store was either covered in ads or made for kids who already read. I was homeschooled my whole life, so trying a sideways angle into learning felt natural. I was already building everything else with Claude Code, so I figured I'd try building him his own game.
It was football season. Eli was watching games with me and getting obsessed with which logos went to which teams, the uniforms, the names. So I stopped trying to convince him to practice letters and numbers, and started wrapping the practice inside the thing he was already paying attention to. Number match topped out at 29 because that covered the jersey numbers he'd see on TV, especially the 20s and 30s he was struggling with. Letter sounds got their first real practice through the first letters of team names, the Cardinals and the Chiefs and the Steelers. And the team-logo match game was pure memorization, which he already loved doing. He didn't know he was practicing. He just wanted to play.
Split screenshot of NFL team match and number match gameplay, ideally showing a jersey-number question in the 20s or 30s, plus a team logo with its name below
A 3-year-old tunes out flat TTS in about four seconds. The first version used the browser Speech Synthesis API and it was fine for me, awful for him. I switched to pre-recorded ElevenLabs clips with a consistent voice across every game. One voice, one personality, one thing Eli recognizes the second a game starts. 126 clips now, covering every letter, every number, every NFL team, plus success and encouragement phrases that rotate so nothing gets stale. The game waits for audio to finish before advancing, so the praise lands cleanly instead of talking over itself.
Audio folder listing or waveform visualization showing the success/encouragement clip rotation (e.g. f-success-1.mp3 through f-success-7.mp3)
Around game three I noticed I was copy-pasting the same scaffolding over and over. Audio hooks, toast notifications, settings menu, shuffle-bag randomness so the same question doesn't repeat. I knew I was going to keep making more of these, so I turned it into a pipeline. I describe a new game concept, Claude drafts the component off the existing pattern, generates the list of voice prompts into a declarative JSON, and a Python script runs everything through the ElevenLabs API. For imagery, it kicks out an image list I feed into Nano Banana Pro. What used to take a weekend now takes an afternoon, and the voice stays identical across every new game Eli gets.
The prompts config is the single source of truth. Every prompt, every filename, every game, all in one JSON. That means I can regenerate the entire voice library if I ever switch voices, add a male variant, or tweak a phrase. It's the kind of thing that doesn't matter until it matters, and then it matters a lot.
Snippet of prompts.json showing a game section with prompts array, or a terminal screenshot of the generate_prompts.py script running with its tqdm progress bar
Letter match (upper and lower), number match (1 through 29), NFL team match (all 32 teams), NFL letter logos, farm animal match, and color match. Each one reuses the same audio hook, the same settings menu, the same favorites system, the same shuffle-bag algorithm so Eli doesn't see the same question twice in a row. Anything game-specific stays in the game component. Everything else is shared.
3x2 grid or scrolling strip of screenshots showing each of the 6 shipped games: letter-match, number-match, nfl-team-match, nfl-letter-logo, farm-animal-match, color-match
It runs as a PWA on an old iPad we keep around for him. The iOS safe area was tinting green every time he got an answer right, because Safari was reading the success toast color and repainting the status bar. That kind of detail only shows up when a kid uses your thing every day.
Photo of Eli playing on the iPad, or a screenshot of the PWA installed on the home screen with the Eli's Games icon
OptionalThe drawing game is the one I'm still wrestling with. The idea is tracing letters on the iPad so Eli can practice writing them the way he practices reading them. It works, sort of, but inside a PWA the latency and gesture handling never feel right. That's the thing pushing me toward porting the whole suite to Expo and React Native. Same pipeline, same voice library, same games, but with native touch handling and a real app icon on his home screen. That's the next version.
This one counts twice for me. It's software as a gift, built for the person I care about most, and it's a system I use every time I want to make him another one. The games are the output. The pipeline is the thing that keeps making more of them. Eli doesn't know any of that. He just asks if he can play Daddy's games.