Skip to content

Structure and branching

Branching in Patter comes from a handful of building blocks, and Patterpad shapes them without ever asking you to wire up a flow chart. You change the structure through the action menu; the details on each piece live in the inspector.

Every snippet and group has a quiet ⋯ button at its top-right, and right-clicking anywhere on it opens the same menu. It holds the structural moves:

  • Use Follow with ▸ to add something after this piece, a Snippet, a Branch, a Choice, or a Sequence in one of its ready-made shapes (Once each, Cycle, Shuffle, or Best match).
  • Use Wrap in ▸ to wrap this piece (or several you’ve selected) in a Branch, a Choice, or a Sequence (Once each, Cycle, Shuffle, or Best match).
  • On a choice, Add option does the same job as the inline “+ option” control.
  • Choose Ungroup to undo a group, so its contents move up a level.
  • For snippets, Split here, Join with previous, and Join with next appear only when they make sense.
  • Reach for Duplicate to copy this piece and everything inside it in just after itself, as described below.
  • Finish with Delete, which removes the piece (with a quick confirm unless it’s already empty).

All of it is undoable.

Duplicate copies a whole snippet, group, option, or block along with its contents, dropping the copy in right after the original. It is the quick way to make a variant. Build one option the way you want it, duplicate it, and reword the copy. It’s also on Edit ▸ Duplicate (⌘D), which copies whatever you have selected, or the piece the cursor is in.

The copy is a genuinely separate piece, never a shadow of the original.

Every line in it gets its own identity, so editing the copy never changes the original (identities are what the text, the recordings and the translations hang off). The text comes with it, so you start from what you had rather than a blank.

Writing status and any notes come across too, since the copy is at the same stage of drafting. Review comments don’t, because a comment is a conversation about the original line. Recording status doesn’t either, because the copy has no recording yet.

Duplicating a block also names the copy <name> copy (then copy 2, and so on) and lets it take a fresh address, since two blocks in a scene can’t share one.

A choice offers the player options. Each option holds a prompt, the line the player reads, handed to your game exactly as you wrote it. It can hold optional content, anything from a single line to a whole branch of its own, played when the option is taken. And it carries a few per-option flags (below).

Edit all of a choice’s options together in one inspector panel. Prompt, condition, and flags sit side by side, with reorder, delete, and add.

A choice branches into options, each with its own content, then rejoins at a gather and carries on. Separately: a jump leaves for another scene or block and does not return; a call runs a shared piece of story and then returns to where it left off. A choice branches, then rejoins Choice option A content option B content option C content Gather rejoin here carry on Two ways a snippet diverts ↪ jump leaves for another scene or block, and never comes back ⤳ call runs a shared piece of story, then returns to carry on here
Flag Meaning
Sticky Repeatable. Left off (the default), an option is once-only: once the player takes it, it’s gone from the choice.
Fallback Taken automatically the moment it’s the last option standing. One per choice at most, and its prompt is never shown.
Secret Completely hidden from your game while its condition is unmet, so it can’t leak through the choice or a saved game.

An option is available only when its condition is met. Options carry conditions just like snippets do (a required item, a story flag, a visit count), and that condition is what decides whether the player can take it. By default an option whose condition fails is still shown, not removed: your game receives it flagged as unavailable, along with the reason, and decides how to present it (dimmed, locked, struck through, or hidden, that part is up to your UI). It lets you show “the path you couldn’t take.” Reach for Secret only when an option must stay invisible until it’s unlocked.

Any group has a selector (set in the inspector) that decides which of the things inside it play.

Run is the default, and plays everything eligible, in order. Branch plays only the first eligible item, which is your if / else-if / else, just conditions on an ordered list. Choice offers everything inside as options and waits for the player.

Sequence is a picker with a memory and two dials. Its Order is In order or Shuffle, and shuffle never repeats a line right after itself, and works through them all before reshuffling. Its Exhaust is Play once, Repeat, or Stick on last.

Those two Sequence dials cover the everyday patterns: “say each line once”, “cycle forever”, “random with no instant repeat”, “stop on the last line”. You can also share a Sequence’s memory (an inspector toggle) so two characters never draw the same shuffled line.

The action menu’s Once each, Cycle, and Shuffle aren’t separate things. They’re all the same Sequence, pre-set for the three most common setups:

Preset Order Exhaust
Once each In order Play once
Cycle In order Repeat
Shuffle Shuffle Repeat

Drop one in, then nudge the Order and Exhaust dials in the inspector to reach any combination you like. The preset is just a starting point.

A snippet can end with a jump to a scene, a block, or END. Open the jump row in the inspector and type to find any scene or block in the project (plus END). Once it’s set, a small jump / call toggle sits beside it, so you choose how it behaves.

A ↪ jump heads there and doesn’t come back, and that’s the default. A ⤳ call heads there, and when it finishes, comes back and carries on where you left off. That’s handy for a bit of story you want to reuse from several places (a shared aside, a recurring bit of business), without copying it.

The chip on the page shows the mode too, so you can tell a one-way ↪ from a returning ⤳ as you read. Renaming a scene or block never breaks a jump that points at it. A snippet that’s just a jump, with no lines of its own, is a neat way to route the story around. (⌘/Ctrl-click a jump chip to follow it to its target.)

Wherever a snippet or group has a condition, the script shows it as a quiet if … tag, and you edit it visually in the inspector. See Conditions, effects & data.

Some conditions are dead on the page, and you can see it without playing. If a snippet asks for @connected && !@seen, and the only thing that ever sets @connected is itself behind @seen, then @connected can only be true after @seen is, and nothing ever sets @seen back. The snippet can never run.

Patterpad checks for this as you type and says so in the Problems panel, naming the chain: “@connected can only become true after @seen, which nothing sets back.” It works on a single flag of a flags property too.

It is a warning, never an error, and it never fails a build or patter validate: writing the bit that sets a value later in the week is completely normal.

The check is deliberately narrow, because a wrong “this can never happen” on something that plays fine is worse than saying nothing. It reasons only about one-way switches: a boolean only ever set true, and a flag only ever +set. The moment a value is written any other way (set back to false, cleared, assigned something computed, driven by your game through @world, reseeded by temporary, or already true by default) it drops out of the check entirely rather than being guessed at. Counters, text, and qualities are never analysed at all.

The right pane (⌘2) stacks up everything around your cursor, innermost first: the line, text, or game event, its snippet, any groups around it, and the block and scene. Click a level’s header to jump to it. The title bar shows the <scene>.<block> address (click to copy), and a line shows its #id (also copyable, so you can hand it to a developer for translation or audio). The full tour of the inspector’s editors is on the next page.

Open source under the MIT licence, made by .