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.

One sentence in, a game design out
Here is what "make it a mystery interview" expanded into, none of it requested explicitly:
| The human said | The 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:

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.

Five capabilities, one pipeline
Each Floniks capability lands on an engine contract that was already waiting for it:
| Capability | Floniks side (tools over MCP) | Engine side (data as contract) |
|---|---|---|
| Portraits | Text-to-image base + image-to-image expressions | Textures load by filename; one API call switches expression |
| Cutouts | Background removal | Transparent PNGs composite with no engine change |
| Voices | TTS with a pinned voice per character | A dedicated voice channel: new line stops the old, no overlap |
| Ambience | Text-to-music | A 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.

