Type How to Make a Text Based Game (Choice Loop 2026)

By Arron R.13 min read
How to make a text based game in 2026: a scene graph of rooms and choices, a tiny parser or choice UI, an inventory record, and an AI audio pack for narration,

Colossal Cave Adventure shipped in 1976 (verified against en.wikipedia.org/wiki/Interactive_fiction on 2026-08-16) and every question of the form “how to make a text based game” still reduces to the same skeleton fifty years later: a graph of scenes, a small record of who the player is and what they carry, a render loop that prints the current scene and reads the next choice, and a save routine that pickles the whole state to disk. The 2026 stack has not changed those primitives, but everything above them — the narrator voice, the tension-bed music, the chime and thud SFX, and even the branching logic itself — is now a one-prompt problem instead of a one-month problem. That means WizardGenie to scaffold the scene graph, the choice UI, and the JSON save-load pair, Sorceress Speech Gen for the narrator voice, Music Gen for the loopable tension track, and SFX Gen for the handful of stingers that separate a plain page of prose from a game. This guide is the honest end-to-end for how to make a text based game that ships in a browser tab in a weekend in 2026, under two dollars in Sorceress credits.

How to make a text based game browser pipeline: scene graph, choice UI, state and save, and audio pack with WizardGenie and Sorceress tools
The 2026 how to make a text based game recipe: a scene graph of rooms and choices, a choice UI that reads prose and appends buttons, a state record persisted to localStorage on every click, and an audio pack of narration, music, and SFX pumped in from Sorceress.

What “how to make a text based game” actually means in 2026

The query “how to make a text based game” hides three related but different styles. Some searchers want a parser-driven interactive fiction game — the player types verb-noun commands (GO NORTH, TAKE LANTERN, EXAMINE DESK) and the game parses those into scene mutations. That was the shape of Zork in 1980 and it is still the shape of most modern IFComp entries. Some searchers want a choice-based text game — the player reads a passage of prose and taps one of two to five choice buttons; each choice advances to a new passage. That is the shape most modern web text games take because it maps cleanly onto touchscreens. And some searchers want a hybrid text RPG — short prose scenes plus combat, inventory, stats, and a save file. This guide targets the shared 2026 core of all three because the mental model is identical: JavaScript reads the player's next choice, runs a resolve function on world state, and re-renders the current scene as prose plus buttons.

Four things make a text based game still one of the highest-quality-per-hour builds in 2026. First, the audience is huge and underserved: interactive fiction has an active competition circuit (IFComp, Spring Thing) and a permanent archive at the Interactive Fiction Community Forum, per en.wikipedia.org/wiki/Interactive_fiction verified 2026-08-16. Second, the tooling is trivial — a scene graph is a plain JavaScript object, a choice is a button, a save file is a JSON string. Third, the writing carries the game, which means an author with strong prose ships a great text based game before a shader nerd finishes a single lighting pass. Fourth, voice, music, and SFX are now generative, so a lone writer can also ship a full audiobook-quality narrator track without hiring a voice actor. The genre has never been in better shape for a hobby build.

The text based game loop in one minute

Every text based game is the same three-line skeleton. Print the current scene — write its prose into a reading pane and append one button per available choice. Read the input — wait for a click on a choice button (or, in a parser game, wait for the player to hit Enter in a command line). Resolve and advance — run any state mutation the choice specifies (add an item to the inventory, set a story flag, deduct HP), swap the current scene ID to the choice's target, save the state, and re-render. That is the whole loop, and in modern JavaScript it fits in about thirty lines with zero dependencies.

The critical discipline is the same one that keeps a canvas game honest: the render function never mutates state and the resolve function never writes DOM. Concretely: keep a state record as a plain JS object (current scene ID, inventory array, flags object, stats object), a scenes object keyed by scene ID (each value has a prose string and a choices array), and a small ui record with references to the two DOM nodes (a <div id="prose"> and a <div id="choices">). The render function reads state.scene, looks up scenes[state.scene], writes its prose to the prose div, and appends one button per available choice. The click handler mutates state, then calls render. Everything else — the save-load pair via the browser's localStorage API verified 2026-08-16, the audio playback, the death and ending screens — is layered on top of these three pieces.

Text based game render loop: print scene, read input, resolve and advance with a choice UI and save routine
The three-step text based game loop that survives any browser tab. Print the scene by writing prose and appending buttons, read the input on a button click, then resolve the choice, mutate state, save, and re-render.

Pick your engine for how to make a text based game: vanilla JS, Twine, or WizardGenie

Three good targets in 2026, each with a very different trade-off. Vanilla HTML plus a single JavaScript module is the right pick when you want total control over the presentation, the save format, and the audio pipeline — and when the game is under a couple hundred scenes. A working vanilla JS text-based game is roughly 200 lines of JavaScript: a scenes object, a state record, a render function, a click handler, and a localStorage save-load pair. You get pixel-level control of the reading pane, a save file you own, and a total bundle size under 20 KB before audio. This is the honest default when you already want the audio pipeline that Sorceress ships.

Twine 2.12.0 (released 10 April 2026, verified against twinery.org on 2026-08-16) is the honest default when the story is huge (hundreds of scenes), the mechanics are simple (mostly branching prose), and you want a visual passage editor that draws the story graph for you. Twine is free, open source, and exports to a single self-contained HTML file that runs anywhere. Its built-in story formats (Harlowe, Chapbook, SugarCube, Snowman) cover everything from beginner-friendly hyperlink fiction to SugarCube's full JavaScript API for stat systems and inventories. The trade-off: adding custom audio, custom UI, or a hybrid text-RPG feel means fighting the story format's assumptions. When the mechanical ambition is beyond “click a link to advance,” a vanilla JavaScript build is usually less friction than a heavily customized Twine build.

WizardGenie is not a separate engine — it scaffolds whichever of the two above you pick from a single natural-language prompt. WizardGenie is the Sorceress game-native coding agent, and it ships as both a Windows desktop app (installer with auto-update, available to Early Access supporters and above) and a no-install web build at the same URL. Its coding-model lineup (verified 2026-08-16 in src/app/_home-v2/_data/tools.ts lines 766 through 775) covers Claude Opus 4.7, Claude Sonnet 4.6, GPT-5.5, Gemini 3.1 Pro, DeepSeek V4 Pro, Kimi K2.5, Grok 4.2, and MiniMax M2.7. For a first vanilla-JS text based game, any model in the lineup writes the whole skeleton in under two minutes. If you want to run cheap on a long story session, pair a frontier planner (Claude Opus 4.7 or GPT-5.5) with a budget executor (DeepSeek V4 Pro or Kimi K2.5) — the planner designs the scene graph and the resolve rules, the executor types the code and populates the scenes. That pairing runs at roughly one-fifth the cost of a single-frontier session.

Step 1 — design the scene graph and choice branching

Before you write a single line of code, sketch the scene graph on paper. A scene is any moment where the story pauses and offers the player a choice, which usually means: a room, a decision point, a mini-scene of dialogue, a combat resolution, or an ending. A short jam-scale text based game has 20 to 50 scenes, three or four endings, and a couple of items that gate branches. Draw it as a directed graph — nodes are scene IDs, arrows are choices, and note any require predicate (a choice that only appears if the player has an item or has met a flag) on the arrow itself. Fifteen minutes of sketching prevents six hours of dead-end debugging later.

Now translate the graph into JavaScript. Open a fresh directory, create three files (index.html, game.css, game.js), and paste the scene graph in as a single object literal. Every scene value has two required fields (a prose string and a choices array) and two optional ones (an onEnter function that runs when the scene loads, useful for damage from a trap or a flag flip; and an ending boolean that suppresses the choices array and shows an end-of-game screen instead). Every choice object has a label (the button text), a next (the ID of the scene it advances to), an optional mutate function that receives state and mutates it, and an optional require predicate that receives state and returns a boolean. That is your entire data model.

Two authoring habits that pay off enormously: keep the prose short (under 400 characters per scene — players tap through longer scenes without reading), and give each ending a distinct feel (a solemn tragic ending, a comic bad ending, a triumphant good ending). The scene graph is the game — the code that renders it is trivial and you will spend 90% of your build time writing prose, not writing JavaScript.

Text based game data structures: scene graph, state record, and choice object with require and mutate functions
The three JavaScript data structures every text based game needs. A scene graph keyed by scene ID, a state record with inventory and flags and stats, and choice objects with optional require predicates and mutate functions.

Step 2 — wire the parser or choice UI and inventory system in WizardGenie

Open WizardGenie and paste your scene graph and state record in as the seed. Give the agent one paragraph: “Wire the browser text based game for this scene graph. Build it as one ES module: (1) a boot function that reads the current save from localStorage if one exists, otherwise initializes state to { scene: 'start', inventory: [], flags: {}, stats: {hp: 10} }, then renders the current scene; (2) a render function that looks up scenes[state.scene], writes the prose to a #prose div, clears the #choices div, iterates the choices array, filters out any choice whose require predicate returns false, and appends one button per remaining choice; (3) a click handler that runs the choice's mutate function on state if present, sets state.scene to the choice's next, saves state to localStorage as a JSON string, and calls render; (4) an ending screen that shows when scenes[state.scene].ending is true and offers a Play Again button that clears the save and reloads.” Any coding model in the lineup produces the module in under three minutes.

The click handler is where the game lives, and its five lines do almost all of the work: if (choice.mutate) choice.mutate(state); state.scene = choice.next; save(); const s = scenes[state.scene]; if (s.onEnter) s.onEnter(state); render();. Everything else on top of that skeleton — the inventory sidebar that lists state.inventory, the stats bar that reads state.stats.hp, the flag-based prose variants that use template literals inside the prose string, the timed choices that fire after N seconds via MDN's querySelector reference verified 2026-08-16 — is optional decoration. Ship the skeleton first, then layer in the sidebar and the flags after the core loop feels right.

If you want a parser-driven variant instead of the choice UI, swap the choices array for a parse(input, state) function per scene that reads the player's typed command, matches it against a short verb-noun table (TAKE, DROP, EXAMINE, USE, GO), and either advances the scene or writes an error line back to the prose div. The parser is more work to write and much more work to test, so most modern text based games choose the tap-friendly button UI even for reading-heavy fiction — the parser is a stylistic choice, not a functional one.

Step 3 — Speech Gen narration, Music Gen tension bed, SFX Gen chime stingers

Silent text on a screen works, but a text based game with a narrator voice, a tension-bed music loop, and a handful of chime stingers on key moments feels like an entirely different medium. Sorceress covers all three in under an hour of hands-on time.

Narration first. Open Speech Gen and paste the prose for each scene as its own generation. Speech Gen bills 0.5 credits per 1000 characters on the HD tier and 0.3 credits per 1000 characters on the Turbo tier (verified 2026-08-16 in src/app/speech-gen/page.tsx line 28 as CREDITS_PER_1K_HD = 0.5 and line 29 as CREDITS_PER_1K_TURBO = 0.3), with a minimum charge of 1 credit per generation (MIN_TTS_CREDITS = 1, line 30). A 30-scene game with 400 characters of prose per scene is 12,000 characters, which is 6 credits on HD or 3.6 credits on Turbo — call it $0.06. Optional: clone your own voice or an author-appropriate reference for 400 credits one-time (VOICE_CLONE_CREDITS = 400, line 31) — that clone then narrates every scene for the flat per-1K rate. Play each narration file from JavaScript with a fresh Audio object per the MDN HTMLAudioElement reference verified 2026-08-16, and start it on the first user click so browser autoplay policy stays happy.

Music second. A text based game rewards two music tracks: a calm exploration bed and a tension bed for combat or high-stakes scenes. Open Music Gen. Music Gen bills 10 credits per generation (verified 2026-08-16 in src/app/music-gen/page.tsx line 28 as MUSIC_CREDIT_COST = 10). Two tracks with two tries each is 40 credits (about $0.40). Add 2 credits per WAV export (WAV_CREDIT_COST = 2, same file line 31) if you want lossless. Play each track with a single Audio object, set loop = true, and swap tracks on scenes that flip a state.flags.tension boolean.

SFX third. A text based game feels alive when small stingers punctuate every meaningful choice: a soft chime on inventory pickup, a heavier thud on damage or death, a bright arpeggio on discovering a new area, a muted click on the choice-button hover. Open SFX Gen. SFX Gen bills 1 credit per second on the seed-audio tier (verified 2026-08-16 in src/app/sfx-gen/page.tsx line 23 as SEED_AUDIO_CREDITS_PER_SECOND = 1). A full text-game SFX kit is roughly 6 short stingers times 2 seconds each, so 12 credits (about $0.12). Trigger each stinger from the mutate function on the choice that owns it, or from a scene's onEnter hook.

What a how to make a text based game project costs on Sorceress in 2026

Concrete asset and generation budget for a browser text based game with a 30-scene story, HD narration, two music tracks, and a full SFX kit, from empty repo to zip-and-share playable, all numbers verified 2026-08-16 against local Sorceress source:

  • Narration (Speech Gen, HD tier): 0.5 credits per 1000 characters, 30 scenes at 400 characters each = 12,000 characters, so 6 credits ($0.06 USD). Turbo tier is even cheaper at 3.6 credits.
  • Optional voice clone (Speech Gen): 400 credits one-time for a custom author-voiced narrator ($4.00 USD). Skip on a first build; add later if the game is a series.
  • Music (Music Gen): 10 credits per generation, 2 tracks (exploration + tension) with 2 tries each = 40 credits ($0.40 USD). Add 2 credits per WAV export.
  • SFX (SFX Gen, seed-audio tier): 1 credit per second, 6 stingers at 2 seconds each = 12 credits ($0.12 USD).
  • WizardGenie coding time: effectively free on the Sorceress side (bring your own model API key, or use one of the built-in trial-key options for the smaller models). Model-side API cost for a 1-to-2-hour prompt session on a cheap Executor like DeepSeek V4 Pro is typically under $0.40.
  • Total for one complete browser text based game build (30 scenes, HD narration, 2 music tracks, 6 SFX stingers, working choice engine, save-load pair): 58 credits, or roughly $0.58 USD in Sorceress credits, plus under $0.40 in model API time. Under $1 end-to-end for a first playable text based game — under $5 if you add the optional custom-voice clone.

Sorceress bills 100 credits per dollar at the standard rate (CREDITS_PER_DOLLAR = 100 in src/lib/models.ts line 69). New accounts start with 100 free credits (SIGNUP_GRANT = 100 in src/app/api/admin/credits/route.ts line 12), which is enough for the narration, both music tracks, the SFX kit, and 30 credits of headroom. The Sorceress Lifetime tier at $49 one-time (LIFETIME_PRICE = 49 in src/app/plans/page.tsx line 51) covers unlimited Speech Gen, Music Gen, and SFX Gen use, which matters if the text based game is the first entry in a series or an IFComp pipeline that ships a new branching entry every month.

For related browser-first pipelines that share the choice-and-state spine, the closest reads are Branch an AI Text Adventure (Browser Quest Loop 2026) for the AI-driven-narrator sibling, Pen How to Make a Visual Novel (Browser Scene Loop 2026) for the illustrated cousin, and Code How to Make a Game in JavaScript (Browser Loop 2026) for the canvas-and-loop counterpart. The Sorceress Tools Guide is the master index for every tool the guide referenced. Under one dollar in credits, one weekend of writing, and how to make a text based game is a done deal on Sorceress in 2026.

Frequently Asked Questions

What is a text based game, and how is it different from interactive fiction?

A text based game is any game whose primary output is text on a screen and whose primary input is either typed commands or on-screen choices. Interactive fiction (IF) is the historical umbrella term for the genre, dating to Colossal Cave Adventure in 1976 and Infocom's Zork in 1980 per en.wikipedia.org/wiki/Interactive_fiction verified 2026-08-16. In 2026 practice, three overlapping styles all count as text based games. Parser-driven IF asks the player to type verb-noun commands (GO NORTH, TAKE LANTERN, EXAMINE DESK) and the game parses those into scene mutations. Choice-based IF (also called choose-your-own-adventure or hyperlink fiction) shows the player a passage of prose plus 2 to 5 tappable choices; each choice advances to a new passage. Hybrid text RPGs mix short prose scenes with combat, inventory, and stats. All three share the same core skeleton: a graph of scenes, a state record for the player, and a render loop that prints the current scene then reads the next choice. This guide covers all three because the mental model is identical.

Do I need a special tool like Twine or Inform to make a text based game?

No. Twine 2.12.0 (released 10 April 2026, verified against twinery.org on 2026-08-16) is a great authoring tool for choice-based IF because its visual passage editor and hyperlink macro language remove almost all boilerplate. Inform is a great pick for parser IF because its natural-language rule engine handles the world model for you. But you can also write a text based game in about 200 lines of vanilla JavaScript with zero build step: a scene graph as a plain JS object, a state record for inventory and flags, a render function that writes prose to a div and appends buttons for each choice, and a click handler that resolves the choice, mutates state, and re-renders. That single-file approach ships in any browser tab and gives you total control over the presentation, the save format, and the audio pipeline. Choose Twine when the story is huge and the mechanics are simple. Choose vanilla JavaScript (via WizardGenie) when you want game-native audio, custom UI, or a hybrid text-RPG feel that Twine story formats do not cover well.

How do I structure the scene graph for a text based game?

A plain JavaScript object keyed by scene ID, where each scene value has a prose string and an array of choice objects. Concretely: const scenes = { start: { prose: 'You wake in a dim cabin. A lantern sits on the desk.', choices: [ { label: 'Take the lantern', next: 'lantern_taken', mutate: s => s.inventory.push('lantern') }, { label: 'Open the door', next: 'porch', require: s => s.inventory.includes('lantern') } ] }, ... }. The scene ID is the only piece of story-position state you save. Each choice object has a label (what the button says), a next (the ID of the scene it advances to), an optional mutate function (a state mutator that pushes to the inventory, sets a flag, or increments a stat), and an optional require predicate (a boolean check on state that hides the choice unless satisfied). This shape scales from a five-scene game jam entry to a two-hundred-scene text RPG without changing the rendering code. The render function reads scenes[current], writes the prose, and iterates the choices array to append one button per available choice.

How do I save and restore a text based game session?

localStorage plus JSON.stringify, no framework required. Serialize the state record (current scene ID, inventory array, flags object, stats object) with JSON.stringify on every choice resolution and read it back with JSON.parse on page load. localStorage per developer.mozilla.org/en-US/docs/Web/API/Window/localStorage verified 2026-08-16 gives every origin roughly 5 to 10 MB of synchronous string storage, which is more than enough for a text based game that never exceeds a few kilobytes of state. Two nice-to-haves worth building in on day one: an export button that downloads the current state as a JSON file via a data URL (so a player can share their run or resume on another device), and an import handler that reads a JSON file and replaces state. Neither is more than ten lines of code. The synchronous localStorage model matches how the render loop already thinks: click choice, mutate state, save state, re-render.

How much does it cost to make a text based game with Sorceress?

Under $2 in Sorceress credits for a first playable browser text based game with narration, music, and SFX. Concrete breakdown at 2026-08-16 credit rates all verified in local source. Speech Gen at 0.5 credits per 1000 characters on the HD tier (src/app/speech-gen/page.tsx line 28 as CREDITS_PER_1K_HD = 0.5) for 30 narrated scenes at 400 characters each = 12,000 characters, so 6 credits or $0.06. Voice cloning at 400 credits (src/app/speech-gen/page.tsx line 31 as VOICE_CLONE_CREDITS = 400) is optional if you want a custom narrator voice. Music Gen at 10 credits per generation (src/app/music-gen/page.tsx line 28 as MUSIC_CREDIT_COST = 10) for 2 tracks (calm exploration + tension) with 2 tries each = 40 credits or $0.40. SFX Gen at 1 credit per second on the seed-audio tier (src/app/sfx-gen/page.tsx line 23) for 6 chime stingers at 2 seconds each = 12 credits or $0.12. Total: 58 credits or roughly $0.58 in Sorceress credits, plus under $0.40 for a coding-agent session on a cheap Executor like DeepSeek V4 Pro. New Sorceress accounts get 100 free credits (src/app/api/admin/credits/route.ts line 12 as SIGNUP_GRANT = 100), which fully covers the narration, both music tracks, and the SFX pack with room for iteration.

Sources

  1. Interactive fiction - Wikipedia
  2. Text-based game - Wikipedia
  3. Twine - open-source interactive fiction tool
  4. MDN - localStorage
  5. MDN - HTMLAudioElement
  6. MDN - Document.querySelector
Written by Arron R.·2,946 words·13 min read

Related posts