Skip to content
Bircan Görür
Open to internships — Spring 2027
← All work

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
Emberline reader screen: two characters in a train carriage and a dialogue bubble
Reader
Emberline profile screen: reading text size, typeface, letter-by-letter display and music settings
Reading settings
Illustration · choices, conditions and endings

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 systems

Story 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 approach

Managing 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

FlutterDartFreezedSharedPreferences

Firebase

AuthenticationFirestoreStorageAnalyticsCrashlytics

Tooling

Python scriptsFlutter testGit · GitHub

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
These are story visuals made with Emberline's AI-assisted visual production pipeline, not app screenshots.
Story cover: an old steam train, smoke rising, on cracked desert ground
Cover
Rusty passenger carriages crossing a cracked desert plain
Background · desert
A wooden platform beside a water tower in the desert, with passengers waiting for the train
Background · platform
The train's lounge car: worn armchairs, a stove and round wooden doors
Background · lounge car
The engineering car: gauges, pipes, a safe and a large power unit
Background · engineering car
A detective character in a long trench coat and fedora
Character · detective
Celeste, a character in a green period dress and shawl
Character · Celeste