Twine for Beginners: Displaying Random Text

Even using only the most basic range of tools, Twine gives you a lot to work with. You can produce a fully featured interactive story with nothing more than plain old hyperlinks, and if you’re willing to sink just a little time into learning how to use variables, you can introduce some very sophisticated adventure game elements with minimal effort. But those tools only take you so far. No matter what you do with them, games produced with only hyperlinks and variables will always be entirely deterministic: the same sequence of actions will always produce the same effect.

That’s actually a perfectly good way to go. Sometimes – if anything most of the time – you want people to know that what happens in the game will be a direct result of what they’ve decided to do. But an element of chance can spice things up, and if the player is going to be coming back to the same passage again and again (maybe it’s a room they pass through several times, or an action they must take repeatedly) then it never hurts to vary the text they see. There’s a really easy way of doing this:

The (either:) Macro:

Simply writing (either: “one thing”, “another”) is enough to display one thing or another. If you don’t have a whole lot of possible options in mind you can just stick this in the story where you want the random text to appear and it’ll do the job nicely.

This looks like a mess, but the text it generates when played is perfectly serviceable. It might look like this:

Or this:

Or this:

Even this minimal level of randomness – a handful of different options available at three different places in the passage – can produce a pretty bewildering array of possible combinations. Three times of morning, multiplied by six adjectives to describe Randy’s awakening, multiplied by four ways in which his monkey butler does that job: that’s 72 possible paragraphs right there. But as you might have noticed from the three examples above, there’s every chance you’ll see the same combinations crop up more than once, even in pretty quick succession.

If you want to ensure a good range of possible outcomes, it’s more practical to provide a small number of options in many, many different places than it is to write dozens of options for just one or two specific bits of text. Think about it like a slot machine: if you’re running a casino and you don’t want players to line up the same symbols too easily, you could build a slot machine with two reels, each with ten different symbols on them, giving you 100 possible combinations. Alternatively, you could build a slot machine with ten reels, each with just two symbols on them, giving you 1,024 possible combinations.

Looking at it a different way, any text you write that isn’t randomly selected is invisible to the reader. So although a pair of 100-option (either:) macros would repeat text far less often than a set of ten two-option macros, 99% of your writing would have gone to waste on any given playthrough.

The problem with including a ton of (either:) macros is that they make it a bit difficult to read the text around them. When you write or edit your work, you want to be looking at a story, not an overwhelming mess of brackets, commas and quotes. Fortunately, there’s an easy solution:

The (display:) macro:

There are a million uses for (display:) which I’m sure you’ll discover with a bit of thought, but by far the most welcome is the ability to take cumbersome bits of text and shove them somewhere out of the way. Think of it as the Twine equivalent of cramming all your mess in a wardrobe.

What I’ve done here is created three new passages to display the same (either:) macros as in the previous passage. I’ve literally just copied and pasted them. When you (display: “any passage name you like”), all the text in there appears as if it were written in place of that (display:) macro. In this case, (display: “time”) is functionally identical to writing (either: “early”, “late”, “first thing”). So the “get up” passage looks like this in the editor:

A little easier on the eyes, right? This sort of setup is ideal any time you’ve got a particularly long (either:) macro hogging space in the editor, or any time you’re likely to use the same (either:) macro multiple times. Having set up these passages, the sensible thing to do here would actually be to (display:) them in the opening, too, but as this is just an example I’ll leave them as-is for comparison.

It’s worth bearing in mind that in keeping with the mess-in-wardrobe analogy, it’s easy to forget what you’ve tucked away in a passage to be (display:)ed, and hard to see at a glance whether or not every single option fits in the sentence it’ll appear in (especially if it appears in more than one). Be cautious, test your work thoroughly, and take especially good care when rewriting. It’s probably safest to write the (either:) macro where it’s supposed to appear, and then only move it into a passage to (display:) once you’re confident every option makes sense in context. Good random text should appear as though you wrote it deliberately: it’s jarring (though potentially also quite funny) for the reader when things go wrong. Pay close attention to the next example because it includes just such a mishap. This is most definitely a deliberate exercise for you, the student, and not simply an oversight on my part that I didn’t catch until after taking the screenshot.

Random Numbers:

It’s not just strings of text you can pick at random: you can do numbers too. (random: 1, 100) will pick a number from one to 100, and there are a couple of ways you can make use of this. The most straightforward is to simply write a random number:

This, as you might expect, generates a random number of some kind of eggs. I could have used (random: 1, 100000000) to introduce the possibility of truly astronomical egg numbers, or I could have used (random: 50, 100) to make sure that the minimum possible number of eggs is still comically large.

Did you spot my mistake, though?

Currently there is a 1% chance that the sentence generated will be “1 boiled eggs,” “1 poached eggs,” etc. You might just get away with describing two eggs as a feast, but “1 eggs” doesn’t even work grammatically. Handily, though, there’s a way to fix that that also helps to illustrate my next how-to.

See how deliberate that “mistake” was? I totally planned this!

Random Variables:

Although simply getting Twine to write random chunks of text can be very handy in its own right, (random:) and (either:) are particularly useful when combined with the (set:), (if:)[] and (else:)[] macros described in this earlier tutorial. Here are a couple of examples:

  • (set: $gold to it + (random: 1, 7)) will increase a variable called “gold” by between one and seven inclusive: handy if you’ve got some kind of “treasure chest” passage intended to give the player a small amount of money.
  • (set: $coin to (either: “heads”, “tails”)) will simulate a coinflip, setting a variable called “coin” to either “heads” or “tails.”

Variables set in this way work exactly the same as variables you’ve (set:) to specific values yourself. If you’ve done any programming in the past, this might actually be a little counter-intuitive because I’m aware that at least some languages will handle things differently, but you’re not setting the variable to “either heads or tails,” you’re setting it to “either heads or tails.” So if you write:

(set: $coin to (either: “heads”, “tails”)) $coin $coin $coin $coin $coin

What you get when you test the game will  look something like this:

tails tails tails tails tails

If you’re hoping to write some kind of complicated RPG where $firespell will cause 15-25 damage every time it’s used, this might be a bit of a disappointment, but it actually makes things like coinflips very easy to deal with. You could easily write something like this, for example:

(set: $coin to (either: “heads”, “tails”))“I bet the coin comes up heads!” you say, with confidence.

The dragon flips for it.

“It’s $coin,” she says. “Definitely $coin. I double-checked. It absolutely, 100% came up $coin. Yep, it’s $coin for sure.

(if: $coin is “heads”)[Wow, that sure was lucky! And the dragon sure is gracious in defeat.](else:)[Geez. You know you lost but the dragon really shouldn’t rub your nose in it like that.]

In this example, $coin will be consistently “heads” or “tails” every time the dragon says it, whereas if $coin was itself a random value you’d have a much harder time referring to the result of the flip itself. If you do want something like the $firespell example outlined above, (display:) might actually be a better option, since you could write a passage called “fire spell” containing the (set: $firespell to (random: 15, 25)) macro and then simply (display: “fire spell”) any time you wanted to use it.

This is getting away from Random McRandomface and his eggs, though. If you want to make sure your random number of items makes sense whether or not it ends up being only one thing, here’s how you do it:

(set: $eggs to (random: 1, 100))The monkey butler makes $eggs egg(if: $eggs > 1)[s]!

Basically, you’re setting a variable called “eggs” to a random number, using $eggs to display that number, and then tagging an “s” onto the end of “egg” any time there’s more than one egg. Setting the number of eggs as a variable has the added advantage of letting you refer to it more than once and have the same number appear every time, but honestly the easiest way of dealing with the plural problem is simply to have the smallest possible number of random objects be two so you don’t have to worry about it in the first place. “You can’t believe you ate $eggs eggs!” will never give you a problem as long as $eggs will only ever be greater than one.

Making Things Really Random:

Okay. I said a while ago that there were lots of things you could use (display:) for and that you’d probably work them out on your own. This one, however, I’m giving you for free. (display: (either: “one passage”, “another passage”) will display one passage or another at random, and there’s no reason the passages you’re displaying can’t have their own (either:) or (display:) macros inside them.

That sounds a little complicated, but it’s easy to see the advantages when you consider that you might want to, for example, display either a good event or a bad event. Perhaps it’s important for the game that the odds of that are 50/50, but you don’t want to be limited to creating exactly as many good events as bad ones.

This kind of setup gives you that 50/50 split no matter what. Your “good event” passage could be an (either:) macro with fifty different possible options in it, and your “bad event” passage could be an (either:) macro with just two, and the reader would still get one of those two bad outcomes a full 50% of the time. Roughly. Being random, you’ve got no idea what’ll happen on any given occasion.

This goes beyond building slot machines: now you’re building machines that build slot machines. Or possibly slot machines whose reels are smaller slot machines. I’m not sure. It’s been a while since I was last in a casino. The point is that although the passages that you’re displaying with (display: (either:)) can include (display: (either:)) macros of their own, that’s not all they can include.

This passage sets $event to “good” so that I can generate character(s) and object(s) appropriately. I (display: (either: “group”, “loner”) because much like with the eggs, it’s quite difficult to write a sentence that makes sense for both one character and many. You might also notice that there’s some straightforward prose mixed in with the macros: that’s because it’s easier to keep track of what should go in all these new passages when you can see at a glance what’s going on immediately outside of them.

Yeah. Unfortunately, when you’re building slot machines within slot machines you’re also cramming wardrobes within wardrobes. But you can generate some very sophisticated random text this way, so it’s worth persevering and experimenting and generally seeing what you can make Twine come out with beyond the things you directly tell it to.

This if/else setup isn’t strictly necessary in this example – the whole story is small and simple enough that there would be no harm in simply creating a “good group” passage and a “bad group” passage and (display:)ing those in the relevant places – but in a longer work it could be quite handy to have a single passage that displays a random character (or in this case group of characters) appropriate to whatever situation they turn up in.

To recap, the “something incredibly random” passage displays either the “good event” or “bad event” passage, and those in turn display text from the “object” and “loner” or “group” passages to form a random section of story. It might look like this:

Or this:

Or this:

I should mention that I’ve literally picked the first three that came up when I tested the “something incredibly random” passage. It just so happens that all three were bad events (which at 50/50 each time is hardly unexpected), but even so there’s a good deal of variety in there.

If you’d like to find out just how much variety there is, you can explore my Randy McRandomface example game right here. You might also be interested in Project Pythias, an April Fools’ prank for 2017 that was based on exactly the same principles but took them way further.

6 comments

  1. Pingback: Twine for Beginners: Timers and Live Text | Damon L. Wakes
  2. Pingback: Twine for Beginners: Colouring Text | Damon L. Wakes
  3. Pingback: Twine for Beginners: Adding Images as Base64 | Damon L. Wakes
  4. Pingback: Twine for Beginners: Adding Local Images | Damon L. Wakes
  5. heatmiser

    thank fucking god for you dude, honestly. clearest, results-oriented explanation of twine tricks i’ve found so far. either is going to change my life.

    • Damon L. Wakes

      Hey, thanks! This has really made my day.

      (either:) is spectacularly helpful. If you’re dealing with really extreme probabilities (say, something should only appear 1% of the time) then you’re probably better off using (random:) to set a variable, but for the most part (either:) is much more versatile and much easier to read. If you end up doing anything with it, do let me know! I’d be really keen to see what you come up with.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.