Emberline
A cross-platform interactive story platform I built for stories that change course with the reader's decisions.
Targeting Android/iOS · Preparing for release
- Role
- Independent developer
- Status
- In development and preparing for release
- Platform
- Android · iOS (Flutter)
- Focus
- Story engine and reading experience


( Idea )
Emberline isn't just a reading app that shows text: it's a story engine built on story nodes, state variables and conditional transitions.
I separated the story (data) from the reading experience (engine). Stories are structured as JSON and packaged independently of the app, so the same engine can play stories of very different genres.
( What I built )
Core systemsStory engine
- JSON-based story structure and nodes
- State variables driven by choices
- Conditional transitions, branching narrative
- Chapter and story endings, multiple endings
- Timed choices
Reader
- Reading interface
- Character and background display
- Dialogue and choice presentation
- Progress and save management
Library · Discover
- Story library and discover screen
- Detail pages, chapter lists, covers
- Download and access flows
Accounts and saves
- Google and email sign-in (Firebase Auth)
- Guest mode
- Local progress, Firestore sync
- Bookmarks and favourites
Production pipeline
- Markdown to JSON conversion
- Character sprites and backgrounds
- Story bundles, Firebase Storage
- Validation scripts that check branches and conditions
Design
- A custom design approach called "Space UI"
- Deep colour palette, custom navigation
- Atmospheric, genre-appropriate visuals
- Responsive Flutter interfaces
( Technical depth )
Problem and approachManaging branching stories without hard-coding them
In a choice-based story every decision opens a new path. If those paths live in code, every new story becomes a new development task.
ApproachA reusable, JSON-based story engine: nodes, choice-driven state variables, conditional transitions and multiple endings.
Shipping stories without broken branches
In a story with many chapters and conditions, a branch that can't be reached or leads to a dead end ruins the experience.
ApproachA Python production pipeline: converting text from Markdown to JSON, bundling, and validation scripts that check branches and conditions.
Never losing a reader's progress
Readers can start as guests and create an account later; their progress has to survive either way.
ApproachLocal progress saves, Firebase Authentication account flows and syncing the relevant data with Firestore.
( Tech stack )
App
Firebase
Tooling
( What I went deep on )
Mobile app architecture, data-driven content management, building my own software engine, user experience, and AI-assisted visual content production.
( Gallery )
Story visuals





