Inspiration
Most kids’ TV time is passive, so we wanted to make it more interactive by creating a buddy that responds to children. It can dance when asked, speed up when they say “faster,” and respond gently when they feel sad by slowing down and guiding them through a simple breathing exercise. Safety was our top priority, so the app works completely offline and speaks only pre-approved lines reviewed by adults. The only optional online feature is a fresh joke, which goes through two safety checks before being shown. Parents can also turn this feature off whenever they want.
What it does
Four buddies (Zora the baby dragon, Mimi the kitten, Bruno the pup, Teddy the bear), each with its own look and voice. Dance Studio and Dance Maker, a Rhyme Room with five sung songs and karaoke highlighting, three games (Shape Match, Zora Says, Animal Sounds with 11 real recordings), Alphabets (26 letters), a Band with 10 instruments, a Talk section with conversation starters and 16 phrase buttons, Calm breaths, shiny-scale rewards, and a grown-ups Settings area with a wind-down timer. Everything is driven by the Fire TV remote. When the TV is online, Tell me a joke can also fetch a brand-new, safety-checked, voiced joke; with no connection it tells a stored one. It runs on a Fire TV Stick (Fire OS) and on the Vega Virtual Device.
How we built it
A platform-agnostic TypeScript core (intent parser, allowlist registry, session brain, character state machine, pure game engines, band sequencer) with 167 unit tests, and a React TV UI with our own D-pad focus navigation. The buddies are original flat SVG drawings that one pose engine animates, so they look the same on every TV. Speech is recorded voice clips (263 lines for each of four buddies, generated offline with Piper); a small sequencing library keeps speech, songs and animal sounds from ever overlapping. The app is one self-contained web page that runs inside an Android WebView on Fire OS (firetv/, package com.zoraplay.tv). The same web build also runs inside the Vega app (vega-app/) on the Vega Virtual Device. A small open-source library we wrote, TV Audio Flow, is the sequencing layer (see the Open Source challenge below).
How we used AWS
The app on the TV has no AWS SDK and no keys. At build time we use Amazon Bedrock (Converse API, Amazon Nova Lite and Nova Pro) to write new jokes, riddles, animal facts, chat replies and bedtime lines as strict JSON. A Bedrock Guardrail checks the model's output and then every line again with ApplyGuardrail; our own local rules check length and words; a person approves or rejects each line. Of 226 generated lines (206 jokes plus 20 others), a human approved 148 and rejected 17, 61 jokes are still waiting for review, and only the approved lines are in the app, voiced for all four buddies. One optional button also uses AWS at run time: when the TV is online, Tell me a joke calls API Gateway and a Lambda that asks Bedrock for one joke (Guardrail on the output, our own rules on top), speaks it with Amazon Polly in the buddy's voice, and falls back to a stored joke if anything fails or the TV is offline. Bedrock model invocation logging writes every call to CloudWatch Logs. Details and evidence: docs/aws-bedrock.md. (Run-time: one optional button also uses API Gateway, Lambda, Bedrock and Polly; see the repository's infra/joke-service.)
Challenges we ran into
Honest voice: a Fire TV app cannot reliably receive microphone audio, so we built a clean VoiceInputService seam and shipped the Talk buttons instead of faking it. Making sound clear: one sound at a time, with music and effects ducked under speech. A weak-TV start-up: the opening scene uses the same light SVG buddies as the app, so it appears at once. The guardrail's prompt-attack filter blocked our own generation prompts until we used guardContent (found through the invocation log).
Accomplishments that we're proud of
Every line the buddy says is voiced and reviewed. Works offline with no data stored. Contextual follow-ups ("faster", "again", "stop") feel natural. A real child-safety pipeline with a documented guardrail, a human gate and logs. The Open Source library keeps one sound session at a time: switching from the Rhyme Room to the dance music never overlaps.
What we learned
Measure, do not guess: the guardrail blocking our own prompts only became clear from the invocation log, and the silent jokes only became clear when we counted which lines had no voice clip. Keep one thing playing at a time: a tiny sequencing library fixed overlapping speech, songs and sounds for good. Flat SVG buddies beat 3D on a TV: WebGL is not the same on every device. And a safe-by-design children's app needs a human gate: the model writes, the guardrail and our rules check, a person approves, and the app falls back to stored lines when anything fails.
What's next for Zora Play
Real voice input once a supported API exists; more songs and buddies; on-device saving of scales with parental consent; more buddy voices through Amazon Polly (it already speaks the live joke).
Built With
- amazon-api-gateway
- amazon-bedrock-(nova-lite
- amazon-cloudwatch-logs
- amazon-polly
- android-webview-(fire-os)
- aws-lambda
- claude-code
- esbuild
- ffmpeg
- gradle
- guardrails)
- kiro
- node-test-runner
- nova-pro
- piper-tts
- playwright
- react
- svg
- typescript
- vega-sdk-(vega-virtual-device)
- web-audio
Log in or sign up for Devpost to join the conversation.