Thank you for this reply. It’s most interesting.
My flow system is called Strand, and it’s true that you will often need additional labels (i call terms) compared to Ink. This is because in Strand:
- You cannot have multiple sets of choices within the same term flow.
- You cannot nest choices, instead you flow to another term (and return).
However, i don’t think this is such a drawback as it first appears. I’ll explain why in a bit.
The flow system is definitely capable of anything in Ink.
But the main advantage with Strand flow is that flows return. Or, in general, that call/goto/return are the same. This also allow terms to be “dropped” inline into text that expand like macros (because they return). This avoids all the messy Ink-like “variable text” syntax.
The reason why you have nested choices in Ink is to fix the problem that you cannot have a choice return, so you have to nest it. What happens when two choices want to invoke the same subchoice? You cannot factor it as there is no automatic return. Instead you might have to test a conditional to know where to divert.
Let me write your example a bit different. You can avoid additional labels like this:
MISSING_REEL
* The stolen component...
The reel went missing from the Bombe this afternoon... SECOND_CHOICE
* Shrug
// The story returns to wherever it is called.
SECOND_CHOICE
* Panic
..
* Calculate
..
* Deny
...
I put the text inline with the choice and branch to SECOND_CHOICE
But really;
You would probably structure it more like your layout deliberately with extra labels. Why?
This is my explanation of why extra labels are useful;
Examples look great when the text is short. In a real game, the text is much longer and there is a lot more of it. When this happens your workspace is dominated by content and you cannot easily visually scan the flow logic anymore.
I am routinely taking out chunks of content and refactoring them into separate terms, so that i can more clearly see the flow.
Furthermore, as covered in the ink manual, you wind up labelling gathers and options anyhow with a (bracket)
syntax.
Here’s an example from the Ink manual:
=== meet_guard ===
The guard frowns at you.
* (greet) [Greet him]
'Greetings.'
* (get_out) 'Get out of my way[.'],' you tell the guard.
- 'Hmm,' replies the guard.
* {greet} 'Having a nice day?' // only if you greeted him
* 'Hmm?'[] you reply.
* {get_out} [Shove him aside] // only if you threatened him
You shove him sharply. He stares in reply, and draws his sword!
-> fight_guard // this route diverts out of the weave
- 'Mff,' the guard replies, and then offers you a paper bag. 'Toffee?'
And here’s how it would look in Strand flow;
MEET_GUARD
The guard frowns at you. MG1
'Hmm,' replies the guard. MG2
'Mff,' the guard replies, and then offers you a paper bag. 'Toffee?'
MG1?
* Greet him
GREET
* Get out of my way
GETOUT
GREET
'Greetings.'
GETOUT
'Get out of my way,' you tell the guard.
MG2?
*?GREET Having a nice day?
* Hmm?
'Hmm?' you reply.
*?GETOUT Shove him aside
You shove him sharply. He stares in reply, and draws his sword! FIGHT_GUARD
So more labels indeed. But these replace the Ink ones that were necessary there to make the conditionals. I personally prefer the Strand flow version as the content is more factored and easy to edit outside of the flow logic. You can be sure that these lines will probably be longer in a real game. And more options.
To cover your last example with Pizza…
CAFE
What now?
ORDER
WAITERREPPLY
// waiter reply is conditional on angry
WAITERREPPLY=
*?WAITERANGRY Ok then
* Coming right up!
ORDER?
* order pizza
ORDER_PIZZA
* something else
You order the daily special.
ORDER_PIZZA?
* With pineapple on it?
WAITERANGRY
* plain
// empty term for conditional
WAITERANGRY
Yes, there are more labels. but they replace variables too and the flow is cleaner.