Inspiration
We wanted to solve a problem every parent faces: finding stories that truly resonate with their unique child. Generic characters in books don't reflect the diversity of real kids—their appearances, dreams, and personalities. We imagined a world where every child could see themselves as the hero, with stories that adapt to their interests and grow with them.
What We Learned
Building Funova taught us the power of Gemini's multimodal capabilities:
- Character consistency is hard—we solved it by generating a "Cast Visual Guide" that Gemini references across all panel images
- Rate limiting strategy with exponential backoff (max 3 retries) keeps the experience smooth during high API usage
- Prompt engineering is an art—enforcing "bold black ink outlines, vibrant flat colors, no text in images" ensures a consistent comic book aesthetic
- Local-first architecture with SQLite + filesystem storage makes the app fast and private without requiring cloud infrastructure
How We Built It
- Onboarding wizard (
KidWizard.tsx) — Multi-step form collects child's name, appearance (with optional photo upload), personality archetype, dream, art style, and story length - Single API generation — One call to
POST /api/stories/generatetriggers Gemini to write the script (gemini-3-flash-preview) and generate 10-18 panel images (gemini-2.5-flash-preview-image-generation) - Skeuomorphic reader — Book-style viewer with page spreads mimics the tactile experience of reading a physical comic
- Magic Revision — Natural language editing ("add a dragon!") regenerates individual panels without losing story context
- Persistent gallery — All stories save to SQLite with images stored locally in
backend/images/
Challenges We Faced
- Character consistency: Early versions had characters changing appearance between panels. We fixed this by having Gemini generate a detailed "Cast Visual Guide" upfront that's injected into every image prompt.
- API rate limits: Generating 10-18 images in rapid succession hit 429 errors. We implemented exponential backoff with jitter.
- Image storage: Initially tried base64 encoding, but switched to local filesystem + FastAPI
StaticFilesfor better performance. - Test mode configuration: To avoid burning API tokens during development, we added
testConfig.tswith aTEST_MODEflag that limits panel generation.
Built With
- aiosqlite
- fastapi
- gemini
- postgresql
- python
- react
- sqlite
- supabase
- typescript
- uv
- vite
Log in or sign up for Devpost to join the conversation.