Ink Shape Catalog
Ink Shape Catalog
Narrative Building Blocks for Interactive Fiction
These are the building blocks of interactive fiction. Each shape is a composable unit — you can nest diamonds inside hub spokes, chain gauntlets into a branch-and-bottleneck spine, or use QBN to select which shape fires next. Think of them like functions: pick a shape, fill in your content, connect it to the next shape.
Class pacing: In-class, explore 3–4 shapes that match your story idea + paste one into Inky. The full catalog is a reference to revisit. The Reflection Journal is best as take-home pre/post work.
Diamond
Open, differ, converge. Single chokepoint fans out then reconverges.
When you want a meaningful choice that flavors later text without multiplying your workload. The reader picks a path, something changes, and the story comes back together.
VAR approach = ""
The cave mouth yawns before you. How do you enter?
* [Torch raised high]
Light floods the walls, revealing ancient paintings.
~ approach = "bold"
* [Creeping in the shadows]
You slip inside silently. Something skitters away.
~ approach = "stealthy"
* [Calling out a greeting]
Your voice echoes back threefold. Then silence.
~ approach = "friendly"
- -> cave_interior
=== cave_interior ===
The cave opens into a vast chamber.
{approach == "bold": The paintings continue deeper, guiding your way.}
{approach == "stealthy": Your eyes have adjusted. You see everything.}
{approach == "friendly": A faint voice answers from the dark.}
Something glints on the far wall.
-> END
"Write an Ink diamond: the player makes one choice from three options, each sets a variable, then all paths converge into a single scene that references which choice was made. Theme: [your theme]. Keep it under 25 lines."
Weave
Sticky hub, visit branches, return. Hub knot loops, tracks what you've visited.
When you want the player to explore a space at their own pace, examining things in any order. Each option disappears after being used, and the story moves on when everything has been seen.
VAR saw_fish = false
VAR saw_herbs = false
VAR saw_fortune = false
-> market_square
=== market_square ===
The market bustles around you.
+ {not saw_fish} [Visit the fish stall]
The fishmonger waves a gleaming trout.
"Fresh today! Caught it meself!"
~ saw_fish = true
-> market_square
+ {not saw_herbs} [Browse the herb cart]
Lavender and rosemary scent hits you.
The herbalist nods knowingly.
~ saw_herbs = true
-> market_square
+ {not saw_fortune} [See the fortune teller]
She turns a card. The Tower.
"Change is coming," she whispers.
~ saw_fortune = true
-> market_square
+ {saw_fish and saw_herbs and saw_fortune} [Leave the market]
You've seen it all. Time to move on.
-> END
+ [Leave the market early]
You slip away through the crowd.
-> END
"Write an Ink weave pattern: a hub knot with 3 sticky options that each disappear after being visited (use stitch visit counts to gate choices). When all three are visited, a final exit option appears. The hub loops back to itself each time. Theme: [your theme]."
Gauntlet
Gated stations, fail forward. Linear sequence where you can pass clean or messy.
When you want a sequence of challenges that the player always gets through, but their performance accumulates. Great for tension-building where the final outcome depends on how many gates you passed cleanly.
VAR wounds = 0
VAR has_rope = true
-> gate_one
=== gate_one ===
A chasm blocks the path. Far side, ten feet away.
* {has_rope} [Throw the rope across]
The rope catches! You cross safely.
* [Jump for it]
You leap — and barely catch the edge.
~ wounds = wounds + 1
Your hands are bleeding. But you made it.
- -> gate_two
=== gate_two ===
A locked door. The lock is rusted.
* {wounds == 0} [Pick the lock with steady hands]
Click. It opens smoothly.
* [Force it open]
You slam your shoulder into it. It gives.
~ wounds = wounds + 1
Something in your shoulder pops.
- -> ending
=== ending ===
You stumble into daylight.
{wounds == 0: Not a scratch on you. Perfect run.}
{wounds == 1: Battered, but alive. Could be worse.}
{wounds >= 2: You collapse. Barely made it.}
-> END
"Write an Ink gauntlet: 2-3 sequential challenge knots. Each has a 'clean pass' choice gated by a condition and a 'fail forward' choice always available that increments a penalty variable. The ending reads differently based on total penalties. Theme: [your theme]."
QBN (Quality-Based Narrative)
State determines which content appears. Different text and choices surface based on accumulated qualities.
When you want the story to feel responsive to the player's accumulated identity or stats. Instead of explicit branching, content appears or hides based on who the player has become. This is how Fallen London works.
LIST Traits = brave, clever, kind
VAR reputation = 0
-> tavern
=== tavern ===
The tavern is loud tonight.
{Traits ? brave: The scarred fighter nods at you from across the room.}
{Traits ? clever: You notice the barkeep's loaded dice.}
{Traits ? kind: A child tugs your sleeve, eyes wide.}
* {not (Traits ? brave)} [Stand up to the bully]
You shove him back. The room goes quiet.
~ Traits += brave
-> tavern
* {not (Traits ? clever)} [Challenge the barkeep's game]
"Those dice are weighted." He goes pale.
~ Traits += clever
-> tavern
* {not (Traits ? kind)} [Buy the child a meal]
The kid grins. Warmth blooms in your chest.
~ Traits += kind
-> tavern
* {LIST_COUNT(Traits) >= 2} [You've made your mark. Leave.]
~ reputation = LIST_COUNT(Traits)
The door swings shut behind you.
Reputation earned: {reputation}.
-> END
"Write an Ink QBN pattern: use a LIST of qualities. A hub knot shows different descriptive text based on which qualities the player has (using LIST ? checks), and offers choices gated by qualities they don't yet have. Each choice adds a quality. An exit unlocks when enough qualities are collected. Theme: [your theme]."
Hub-and-Spoke
Central hub with gated spokes. Return to hub after each spoke, new options unlock.
When you want the player to explore a location or conversation where completing one area unlocks another. Classic RPG town or detective investigation structure. Each spoke is a self-contained scene.
VAR talked_to_guard = false
VAR searched_alley = false
-> town_square
=== town_square ===
The town square. People bustle past.
+ {not talked_to_guard} [Talk to the guard]
-> guard
+ {not searched_alley} [Search the alley]
-> alley
+ {talked_to_guard and searched_alley} [Enter the locked tower]
The clues align. You know the password.
-> tower
+ [Leave town]
You walk away, mystery unsolved.
-> END
=== guard ===
"Saw someone in the alley last night," the guard mutters.
~ talked_to_guard = true
-> town_square
=== alley ===
Behind the crates: a torn note. "The password is MOONRISE."
~ searched_alley = true
-> town_square
=== tower ===
"MOONRISE," you whisper. The door swings open.
Inside, the truth awaits.
-> END
"Write an Ink hub-and-spoke: a central hub knot with 3-4 sticky choices gated by boolean flags. Each choice diverts to a spoke knot that sets a flag and returns to the hub. A final option unlocks only when specific flags are true. Theme: [your theme]."
Time Cave
Pure exponential branching. No convergence. Every choice leads to unique content.
When you want maximum divergence and every playthrough to feel completely different. Best for short stories because content grows exponentially. Classic "Choose Your Own Adventure" shape.
The letter says: "Come to the docks at midnight."
* [Go to the docks]
A figure waits in the fog.
** [Approach them]
"You came." They hand you a key.
*** [Take the key]
The key opens a warehouse. Inside: gold.
-> END
*** [Refuse the key]
"Your loss." They vanish into the fog.
-> END
** [Hide and watch]
They wait. Then leave a package on the ground.
*** [Take the package]
Inside: a map to somewhere far away.
-> END
*** [Leave it]
You walk home. Some mysteries stay unsolved.
-> END
* [Burn the letter]
The paper curls and blackens.
** [Go to bed]
You sleep soundly. Life goes on.
-> END
** [Regret it immediately]
You fish the scraps from the fire.
"...docks...mid..." Useless.
-> END
"Write an Ink time cave: start with one situation, branch into 2 choices, each of those branches into 2 more, and each of those ends uniquely. No paths should converge. Every ending is different. Total: 6+ unique endings. Theme: [your theme]."
Branch-and-Bottleneck
Repeated diamonds chained. The most common game structure (Telltale, Life is Strange, etc).
When you want an episodic structure with meaningful choices that don't spiral out of control. Each "chapter" fans out and reconverges, so you only need to write the next chapter from one starting point. This is the workhorse of commercial narrative games.
VAR ch1_choice = ""
VAR ch2_choice = ""
-> chapter_one
=== chapter_one ===
The king demands your counsel.
* [Advise war]
"Strike first," you say. The king smiles.
~ ch1_choice = "war"
* [Advise diplomacy]
"Send an envoy." The king frowns but nods.
~ ch1_choice = "peace"
- -> chapter_two
=== chapter_two ===
{ch1_choice == "war": Troops gather at the border.}
{ch1_choice == "peace": An envoy rides out at dawn.}
A spy brings disturbing news.
* [Interrogate the spy]
Under pressure, they reveal a traitor.
~ ch2_choice = "traitor"
* [Follow the spy secretly]
They lead you to a hidden camp.
~ ch2_choice = "camp"
- -> chapter_three
=== chapter_three ===
{ch2_choice == "traitor": You confront the traitor at court.}
{ch2_choice == "camp": You raid the camp at dawn.}
The kingdom's fate is sealed.
{ch1_choice == "war" and ch2_choice == "traitor": A bloody but decisive victory.}
{ch1_choice == "peace" and ch2_choice == "camp": A quiet triumph. No one even knows.}
-> END
"Write an Ink branch-and-bottleneck with 3 chapters. Each chapter offers 2 choices that set a variable, then all paths converge into the next chapter. The final chapter reads differently based on previous choices. Like a Telltale game. Theme: [your theme]."
Foldback
Branches that always rejoin the spine, but the story remembers which path you took.
When you want the illusion of major divergence while keeping a manageable story spine. The player takes different scenic routes but always arrives at the same checkpoints, and the prose acknowledges their specific journey.
// Foldback: paths FEEL different but arrive at the same outcome. // Compare with Branch-and-Bottleneck where endings genuinely diverge. -> prison === prison === The cell door is rusted. You need to get out. * [Pick the lock] Click. Click. The door swings open. You slip into the corridor, heart pounding. -> courtyard * [Smash the wall] Brick dust everywhere. A hole, barely big enough. You squeeze through, scraping skin on stone. -> courtyard === courtyard === // Same destination regardless of path above. The courtyard stretches before you. The gate is ahead. * [Climb the wall] Your fingers find holds in the old mortar. Over the top. You drop to the other side. -> road * [Bluff the gatekeeper] "Shift change." He squints, shrugs, waves you through. -> road === road === // The ending is IDENTICAL. That's the point of Foldback: // the player felt agency, but the story spine never moved. Miles later, you stop to breathe. You're free. The road stretches ahead. Whatever happened back there — it's done now. -> END
"Write an Ink foldback: 3 spine nodes (knots) connected in sequence. At each spine node the player picks from 2 paths, but both paths rejoin at the next spine node. A variable tracks which path was taken, and the converged text references it. Theme: [your theme]."
Parallel Paths
Two sustained storylines with occasional bridge points where you can cross over.
When you want two fundamentally different experiences that occasionally intersect. Good for dual-protagonist stories or "upstairs/downstairs" structures where the player commits to a perspective but can switch at key moments.
VAR current_path = "none"
Two letters arrive. One sealed in red, one in blue.
* [Open the red letter]
~ current_path = "red"
-> red_1
* [Open the blue letter]
~ current_path = "blue"
-> blue_1
=== red_1 ===
The Red Court summons you. Intrigue and poison.
* [Continue on the red path]
-> red_2
* [Defect to the blue side]
~ current_path = "blue"
-> blue_2
=== blue_1 ===
The Blue Fleet needs a navigator. Salt and stars.
* [Continue on the blue path]
-> blue_2
* [Defect to the red side]
~ current_path = "red"
-> red_2
=== red_2 ===
The courtiers whisper your name.
{current_path == "red": You've been here all along. They trust you.}
{current_path == "blue": A defector. They watch you carefully.}
-> finale
=== blue_2 ===
The horizon stretches forever.
{current_path == "blue": The crew knows you. You belong.}
{current_path == "red": A landlubber on deck. You have much to prove.}
-> finale
=== finale ===
War comes regardless. But where you stand determines everything.
-> END
"Write an Ink parallel paths structure: two storylines (A and B) that run in parallel, each with 2-3 beats. At one or two bridge points, offer the player a choice to switch tracks. The finale acknowledges which path they're on. Theme: [your theme]."
Loop-and-Grow
Same scene revisited with accumulated state changing what's available.
When you want to model progression through repetition, like a Groundhog Day loop, a growing relationship, or a place that changes over time. Each visit feels different because state has evolved.
LIST Knowledge = seeds, water, sunlight
-> garden
=== garden ===
{LIST_COUNT(Knowledge) == 0: The garden is dead earth. Nothing grows.}
{Knowledge ? seeds: Small green shoots push through the soil.}
{Knowledge ? water: The earth is dark and damp.}
{Knowledge ? sunlight: Golden light pools between the leaves.}
+ {not (Knowledge ? seeds)} [Plant the seeds you found]
You press seeds into the earth, one by one.
~ Knowledge += seeds
-> garden
+ {not (Knowledge ? water)} [Dig a channel to the stream]
Water trickles in, soaking the ground.
~ Knowledge += water
-> garden
+ {not (Knowledge ? sunlight)} [Cut back the dead branches overhead]
Light floods in. The soil warms.
~ Knowledge += sunlight
-> garden
+ {Knowledge ? (seeds, water, sunlight)} [Sit in your garden]
It took time. But look at it now.
-> END
"Write an Ink loop-and-grow: a single knot that loops back to itself. Use a LIST to track accumulated state. The descriptive text at the top changes based on which list values are set. Sticky choices are gated by what you haven't done yet. An exit appears when the list is full. Theme: [your theme]."
Pause & Reflect
Which shape felt like “yours”? As you scrolled through these 10 shapes, one probably grabbed you more than the others. That instinct isn’t random — it reflects how you see the world. The person drawn to diamonds believes choices converge. The person drawn to time caves believes choices are permanent. What does your favorite shape say about you?
What’s missing from this catalog? These are common shapes, but they’re not the only ones. Think about a story you love — a game, a book, a show. Does its structure fit neatly into one of these 10? Or does it do something none of them capture? If you could name a new shape, what would you call it and what would it look like?
If your life were an interactive fiction, which shape would it be? Not which shape you want — which shape it actually is right now. A loop-and-grow? A gauntlet? A hub-and-spoke where you keep returning to the same central place? And here’s the follow-up: if you could restructure it, which shape would you choose?