Inspiration
Every time you ask an AI image generator to create a character in a new scene, it "forgets" who they are — hair color shifts, scars vanish, ethnicities drift. We wanted to build a system where characters evolve but never drift, maintaining a locked identity across every scene. Chronicle was born from the idea that AI storytelling needs memory and rules, not just generation.
What it does
Chronicle is a character story engine that lets users:
- Lock a character canon — define immutable traits (appearance, personality, distinguishing features) that persist across all scenes
- Evolve scenes with natural language — type commands like "move to a rainy street" or "add dramatic lighting" and watch the scene transform while the character stays consistent
- Generate AI images for each scene, anchored to the character's canonical appearance
- Track emotional journeys — visualize how a character's emotional arc progresses across their timeline
- Reject invalid edits — the system blocks commands that would violate the character's locked traits
How We built it
Frontend: React.js deployed on Netlify. Features a timeline UI with scene cards, an emotional journey tracker, and a natural language command editor.
Backend: Python + FastAPI deployed on Render. Handles all AI orchestration using Google Gemini:
- Parses natural language edit commands and classifies them (emotion change, environment change, visual adjustment)
- Validates every edit against the character canon — rejects anything that violates immutable traits
- Generates evolved scenes with visual prompts that restate the character's physical description first, preventing trait drift
Image Generation: Pollinations.ai as primary service with Puter.js as automatic fallback — both free, no API keys required.
Persistence: localStorage on the frontend for session continuity, with backend state synced via REST API.
The consistency score is computed as:
$$ S = \max\left(85,\ \min\left(100,\ 100 - 0.5n + 5\frac{v}{e} + \begin{cases} 5 & \text{if } n \geq 4 \ 0 & \text{otherwise} \end{cases}\right)\right) $$
where \( n \) is the number of scenes, \( v \) is visual adjustments, and \( e \) is total edits.
Challenges we ran into
Character consistency across AI generations was the hardest problem. AI models naturally drift — generating a character in Scene 1 vs Scene 5 can produce completely different people. We solved this by embedding the full canonical appearance in every prompt and explicitly instructing the model to restate physical traits before describing scene changes.
Free-tier infrastructure reliability was a constant battle. Render's free tier spins down after inactivity and loses in-memory data. Pollinations.ai experienced full outages. We built resilient error handling: graceful resets when the backend loses state, automatic image service failover, and localStorage backup so users never lose progress.
Structured AI output — getting Gemini to return valid JSON while being creative required careful prompt engineering with explicit formatting constraints and rejection criteria.
Accomplishments that we're proud of
- Characters genuinely maintain identity across scenes — same skin tone, same scars, same features
- The edit validation system actually rejects canon-breaking changes instead of silently breaking consistency
- The app degrades gracefully when services go down — fallback image generation, resilient reset, local state preservation
What we learned
- AI consistency is a prompt engineering problem, not just a model problem — the same model produces wildly different results based on how much context you anchor it with
- The gap between "AI can do this" and "AI does this reliably every time" is where most of the real engineering lives
- Building on free-tier services demands defensive architecture — fallbacks, graceful degradation, and clear user feedback
What's next for Chronicle
- Reference image anchoring — use a generated canonical portrait as a visual reference for all future scene generations
- Multi-character scenes — track consistency for multiple characters interacting in the same scene
- Persistent database — migrate from in-memory storage to a real database so characters survive backend restarts
- Export to storyboard — generate a complete visual storyboard PDF from a character's scene timeline
Built With
- api
- css3
- fastapi
- gemini
- javascript
- localstorage
- netlify
- pollinations.ai
- puter.js
- python
- react.js
- render
- rest

Log in or sign up for Devpost to join the conversation.