THE BUILD · A DEV LOG

A 45-beat story,
at 62% fewer tokens.

How Qento keeps a protagonist whose psychology shifts with every reader choice faithful across a full story — and why a compact notation beats a verbose one.

A dev log from Karyll Catubig · solo iOS · shipped April 12, 2026 · updated August 2026

THE PROBLEM

Forty-five beats. One context window.

A single Qento volume is forty-five beats long. One beat is one paragraph the model generates, triggered by one reader choice. Every beat has to carry evolving character trust, unresolved emotional debts, open narrative threads, a genre-specific physics, the protagonist’s psychology (wound, armor integrity, drive), and the reader’s latest nudge.

Feed all of that to the model as prose instructions and you spend around three thousand tokens per beat. The bill climbs. The latency climbs. And the output drifts anyway. Three thousand tokens of prose still under-specifies a live state system.

FIRST ATTEMPT

Prose instructions. Felt humane. Wasn’t.

When you pack live state into prose, the model reads it like narrative. It picks up on the voice of the instructions and mimics that, instead of tracking the constraints the instructions describe. Output leans toward whatever tone the prompt itself was written in. Characters drift. Grudges evaporate. The wound stops mattering.

THE INSIGHT
The model doesn’t read sentences. It reads signal density.

A compact notation has higher constraint-to-noise ratio than prose. The same state, expressed as equations, becomes a set of constraints the model can actually follow, not a wash of language it has to interpret first.

THE LANGUAGE BENEATH

The notation. The language Qento speaks to itself.

The notation is the layer between the reader and the generator. I named it Kwento — the Tagalog word for story. It never shows up on screen. It only shapes what does. One master equation, two dialects.

THE NARRATION DIALECT

Named from Filipino epic verse. Writes beats, chapter openers, finales: the prose the reader sees.

THE INTERIOR DIALECT

Named from the Tagalog word for consciousness. Writes the thoughts the protagonist carries but doesn’t speak.

THE SHARED SPINE

One equation. Two dialects.

The two dialects aren’t separate systems. They parameterize the same master equation: nine terms, three time indices, typed coefficients. The dialects differ only in which blocks they select and which coefficients apply.

The coefficients aren’t numbers. They’re typed values that direct how the model composes each block. Below: the schema, then a seven-line excerpt of the scene state the equation operates on for a single beat.

P(t, k, n) = ⊕_i  c_i ⊙ B_i(t, k, n)

|B| = 9   (typed blocks)
c   ∈ {readOnly, initialize,
       subset(sel), conditional(pred), ...}
⊕   block sum    ⊙   coefficient composition
t   beat    k   chapter    n   volume
T = 0.82 ^ +0.15 | unsettled
W = stirring("she doesn't deserve to stay")
α = 0.42  →  armor cracking
τ = 0.31  →  trust slipping
ε = 0.58  →  she can feel it now
S = 3/4  →  everything unsaid
R = 2/4  →  sentences cut lean

About 350 tokens for the state layer per beat — ~88% compression from the prose version. Net ~62% fewer input tokens across the full per-beat payload, at measurably better craft adherence.

THE LOOP

How the beat refolds.

1. NUDGE

Reader chooses what happens next. The choice writes deltas into the scene state.

2. STATE

The equation’s terms update. Tension shifts. Armor cracks. Trust drifts. Genre physics scale which terms move and by how much.

3. NARRATION

The narration dialect reads the new state and writes the next beat. One paragraph, faithful to the updated scene.

4. INTERIOR

If a private moment opens, the protagonist speaks their mind. The exchange feeds back into the state as the next beat’s starting condition.

SINCE THE FIRST PRINTING

The notation grew doors.

When this log first shipped, the state lived entirely beneath the prose. Since then, the app was rebuilt around it — and pieces of the equation became things a reader can touch.

THE ASIDE

The interior dialect got a door. Tap the protagonist’s name and speak — they answer in their own voice. Nothing said there changes the story.

THE ENDING

A story closes like a book now. The state distills into what remains: a memorial, the credits, one line written for you alone.

THE QUICK START

Type one line on the shelf and a story begins — genre, protagonist, and world seeded straight from your sentence.

THE GLANCE

A home-screen widget holds tonight’s last line and the question it ends on. Tap it and arrive mid-answer.

THE NUMBERS

What it cost. What it saved.

62%
fewer input tokens, full per-beat payload
88%
compression on the state layer vs prose
45
beats per volume
1
person built it
LESSONS

Three things I’d do differently.

I started with prose because prose felt humane. It isn’t. The model is a pattern-reader; it rewards structure. Every hour I spent softening the instructions was an hour making the output worse.

I underweighted the integration cost. The master equation is maybe five percent of the work. You could reproduce the notation in a weekend. The real craft is the parameterization: how a nudge writes deltas into the state, how genre physics scale the terms, how the narration stays faithful across the drift, how a last interior thought becomes the next beat’s starting condition. The notation is the architecture that makes all of that click. That took the year.

I should have benchmarked earlier. The 62% and 88% numbers didn’t exist until I built a proper eval harness. Until then I was optimizing in the dark, tightening prompts that weren’t actually bottlenecked, leaving the real bottlenecks alone.

The story itself
is on the homepage.

Download for iOS Back to the story →

iOS 18.6 and up · iPhone · no account required to start.

LETTERS FROM QENTO
Notes from inside the build.

The making of Qento, written like prose. One letter when something is worth sending. No launches. No asks.