Floniks
Back to Blog
Showcase5 min read

Ship a Visual Novel From One Sentence: Five Generation Capabilities, One Pipeline

The entire brief was "make it a mystery interview." An agent shipped an interrogation visual novel with consistent portraits, one fixed voice per character, an ambient score, and branching dialogue — five Floniks capabilities in one pipeline, with the voice fix verified by instruments.

Author: Elena Park
Ship a Visual Novel From One Sentence: Five Generation Capabilities, One Pipeline

The entire project brief was one sentence: "make it a mystery interview." From that, an agent shipped a mild-horror interrogation visual novel — three witnesses with consistent faces across three expressions each, a distinct synthesized voice per character, an ambient soundtrack, branching dialogue, and a browser-playable build. Five Floniks capabilities — text-to-image, image-to-image, background removal, TTS, and text-to-music — ran in one pipeline, orchestrated end to end by the agent. The human wrote zero prompts.

This is part two of a two-part series. Part one, Build a Puzzle Game From One Screenshot, covers the method's foundations.

The witness select screen: three transparent portraits composited over the midnight gallery — a live screenshot of the WASM build
The witness select screen: three transparent portraits composited over the midnight gallery — a live screenshot of the WASM build

One sentence in, a game design out

Here is what "make it a mystery interview" expanded into, none of it requested explicitly:

The human saidThe agent decomposed it into
"Mystery interview"The premise: a famous painting, The Gazer, stolen from a gallery at midnight; interrogate three witnesses, read their expressions, accuse the thief
(nothing)Three characters with professions, personalities, and secrets: a tennis coach, an accountant, an art-history lecturer
(nothing)An asset spec: 3 characters × 3 expressions, two scene variants (clean and unsettling), 3 opening voice lines, 1 ambient loop
(nothing)A branching dialogue engine with typewriter subtitles and expression switching
(nothing)Dodged a Lua reserved-word landmine (goto as a branch field name) by renaming it

The portrait pipeline: one face, four stages

The hardest problem in a visual novel is character consistency — the same face must carry calm, tense, and frightened states, on a transparent background. The pipeline, entirely Floniks over MCP:

The portrait pipeline in four stages: text-to-image base with a baked background, background removal to a clean transparent sprite, then two image-to-image expression variants of the same face
The portrait pipeline in four stages: text-to-image base with a baked background, background removal to a clean transparent sprite, then two image-to-image expression variants of the same face

One text-to-image base portrait locks the face, outfit, and demeanor. Image-to-image derives the tense and frightened variants from that base — same face, only the expression moves. Background removal produces the final transparent sprites. The eerie scene works the same way: a clean gallery backdrop, image-to-image'd into a variant where one painting on the wall is looking at you.

Voices: one fixed timbre per character, verified by instruments

The human's requirement was one line: give each character a fixed, distinct voice matching their gender. The first "fix" sounded plausible — until a follow-up question triggered an acoustic analysis: the three voices measured 128, 122, and 131 Hz fundamental frequency. Effectively one voice. Not fixed at all.

The root cause was a wrongly-named parameter field; the platform expected voiceId in a different shape. After correcting it, the measurement read 291, 202, and 158 Hz — three genuinely distinct voices, one pinned per character in the game's data so every regeneration stays consistent.

The lesson generalizes to any AI workflow: "fixed" needs an instrument reading, not an impression.

One screenshot report, three root causes

After launch the human sent one screenshot: "the voices work, but nobody is cut out — all three still have backgrounds." The agent's chain: run all nine portraits through Floniks background removal; fix silent audio on the web build along the way (browsers suspend the AudioContext until first interaction); and when the fixed art still didn't show, identify browser caching as the third culprit and rename the textures to bust it.

One symptom sentence, one engine refactor

Late in development the human reported a symptom, not a solution: "audio track management is chaotic — tracks overlap and stack; solve it systematically." The agent rebuilt the engine's audio as three channels: sound effects may overlap but deduplicate within a frame; music never restarts when the same track is re-requested; and the voice channel stops the previous line before playing the next, so dialogue can never talk over itself. A patch fixes one bug; a model fixes the whole class. Every game in the collection inherited it.

Interrogating a witness: typewriter subtitles render as The Gazer watches from the wall behind her — a live screenshot of the WASM build
Interrogating a witness: typewriter subtitles render as The Gazer watches from the wall behind her — a live screenshot of the WASM build

Five capabilities, one pipeline

Each Floniks capability lands on an engine contract that was already waiting for it:

CapabilityFloniks side (tools over MCP)Engine side (data as contract)
PortraitsText-to-image base + image-to-image expressionsTextures load by filename; one API call switches expression
CutoutsBackground removalTransparent PNGs composite with no engine change
VoicesTTS with a pinned voice per characterA dedicated voice channel: new line stops the old, no overlap
AmbienceText-to-musicA music channel that never double-plays
Story— (the agent writes the branch tree; the LLM is the editor)Hot-reloaded Lua; branching data is plain text, diffable

Same conclusion as part one, sharper here: the agent isn't fast — the road has no toll gates. Script, portraits, cutouts, voices, score, tests, deploy: one session, zero manual file ferrying.

Fully cross-platform: the same script, native and browser

This is the most demanding game in the collection — portraits, voices, music, branching story — and all of it runs from one identical Lua script on native macOS, native iOS at 120Hz, and WebAssembly in the browser. Platform quirks like the browser's audio-unlock requirement are absorbed by the engine layer; the script never knows. Both screenshots in this article were captured live from the WASM build in a headless browser.

Questions and answers

How is character consistency achieved across expressions?

One text-to-image base portrait per character locks the identity; tense and frightened variants are derived from that base with image-to-image, so only the expression changes. Background removal then produces transparent sprites.

How do you guarantee each character keeps the same voice?

The voice ID is pinned in the character data, so every TTS generation reuses the same timbre — and the fix was verified by measuring fundamental frequencies (291 / 202 / 158 Hz), not by ear.

What did the human contribute after the first sentence?

Only one-line requirements and bug-report screenshots. Research, decomposition, generation, debugging, and the audio-engine refactor were the agent's work.

Does the browser version really run the same game?

Yes — the same Lua script, byte-for-byte, drives native and WASM builds; the engine swaps its Lua VM per platform behind an identical API.

Wire your own pipeline up with the Floniks MCP server — and if you missed how this method starts, read part one.

Tags

#showcase#visual-novel#character-consistency#image-to-image#tts#text-to-music#mcp#agentic-development

Related Articles

Ship a Visual Novel From One Sentence | Floniks