This is an edition of Robin Sloan’s video game development diary.
Welcome: to returning readers as well as everyone newly subscribed. If you missed it, week 1 sets up the motivation behind this project. All the previous editions are available over on my blog.
The k in the headine at the top of the page is—oh no. Ohhh no. There are two of them.
Good news: the surprise writing project that consumed two of my weeks is drafted and submitted. The project hasn’t been announced yet, but when it is—soon—I’ll be sure to note it here so you can find out what the fuss was about.
I return to Perils of the Overworld this week with a fresh mind and a hot hand.
Exactly the same game I had two weeks ago!
This week’s edition will be single-minded; I want to use it as an opportunity to introduce you to Ink, the scripting language that controls POTO’s branching story and, indeed, the entire logic of the game. Even if you are not a programmer, I think you’ll quickly see how you could use Ink to assemble a branching story of your own.
As I have mentioned before, Ink is the creation of Inkle Studios, and, unlike many systems of its kind that I’ve encountered, it is not at all academic or “experimental.” Totally the opposite, in fact; Ink feels like a tool that has been well-used. There are smooth spots—signs of wear. Patina. It’s wonderful.
One of Ink’s essential characteristics is that it looks like plain text. This scripting language is not littered with braces and parentheses like the rest of POTO’s source code. In fact, you could easily mistake a simple Ink script for a screenplay. Maybe a screenplay crossed with a shopping list.
Here: I’ll show you a supremely simple Ink script, then explain how it works.
It's time to write the newsletter. I belly up to the computer. * I ought to show exactly what I have. It's embarrassing, but the point is to really document the process. I drop the latest screenshots into the email. * I want to send one really sparkly screenshot. Nobody needs to see how the sausage gets made, right? I spend an hour combing through my computer. * First... I need more coffee. Yes. Coffee will help. -> MokaPot - Finally, I press "send." -> DONE = MokaPot I fill the moka pot and set it on the front burner. While I wait, I peer out the window. Wind rustles the bougainvillea across the alley. A sparrow flickers past. Above the warehouse, high up in the sky, a glittering rent has opened, from which an armada of Xrr'vanian warships now emerges. -> DONE
The Ink engine functions as a “text provider” in your game. Reading an Ink script, the engine serves up blocks of text, one by one. A very simple Ink game might show this text directly to the player, plain as a web page with blue inks, but, of course, you don’t have to do that. You can display the text as a page from an enchanted storybook, or as dialogue shown beneath an animated character (as Neo Cab does), or as towering 3D letters made of flame. You could even have your game speak the text, never displaying any at all! The presentation is totally up to you; Ink only takes responsibility for the text itself.
By default, an Ink script runs straight through, going line-by-line, top to bottom. If you want the story to branch, you need to provide options.
You indicate those options with asterisks, like a bulleted list in a text file. The three options I offer in the script above would be displayed together, like so:
I ought to show exactly what I have.
I want to send one really sparkly screenshot.
First... I need more coffee.
and the game would then wait for the player to make a selection.
This, right here, might be the soul of the branching story game—but not because of the options. Because of the display.
Ron Gilbert, legendary creator of The Secret of Monkey Island and many other games, often makes this observation about dialogue options: it is the only format in which you can tell a joke that has three simultaneous punchlines. (Or four, or two, or six…)
For me, this is counterintuitive, but, as soon as you start writing Ink, undeniable: the experience of playing a game with a branching story is more about the options offered than the option chosen.
This carries with it the burdensome realization that the options must be very well-written—as well-written as the game’s narration and dialogue.
Writing for Neo Cab, I proposed a rule—I’m not sure anyone else followed it, but I did—that every option presented had to be, in some sense, true. So, if a passenger riding in the back of your cab asked “what’s your favorite food?” rather than offer options like
* Pizza, of course. * A big, rare burger. * Steamed broccoli. Mmm.
I might offer
* Pizza, I think? Yeah, pizza. * My favorite is exactly the same as everyone else's. * Whatever's cheap.
Do you see how, instead of negating each other, those options all kinda work together, and even the ones you don’t choose tell you something about the character? But they’re not interchangeable, either; each pushes the conversation in a different direction. One is straightforward, another is surly, etc.
(This rule obviously doesn’t work everywhere. Sometimes you really do have to choose between the poison swamp and the haunted forest.)
Back to my Ink example. Beneath each bulleted option, there’s additional text:
* I want to send one really sparkly screenshot. Nobody needs to see how the sausage gets made, right? I spend an hour combing through my computer.
That text is only displayed if the player chooses that option. It can go on as long as you want, and it can even contain nested options. For example, I might build out my second option like this:
* I want to send one really sparkly screenshot. Nobody needs to see how the sausage gets made, right? * * I find one screenshot that looks extra slick. It's a render from a 3D program, but, close enough. * * I photoshop a few of the best screenshots together. I mean, it's still technically a picture of the game. Right?
But we can’t build our entire game out of increasingly-nested options. Besides the fact that the Ink script would be impossible to read and/or edit, we often want two or more options to flow into the same outcome.
Ink offers a bunch of tools for leaping around. One of the most basic is the “divert” arrow,
->, which is a simple GOTO. In the example above, where I’ve written
-> MokaPot, the Ink engine reads: “Jump immediately to the module named MokaPot.”
Further down, you’ll find that module, which Ink calls a “knot.” In practice, Ink scripts tend to be large-ish collections of knots,
=CelestialObservatory and so forth. Alternatively,
=RunAfterTrain and so forth. (Wait, why “alternatively”? Maybe those are all in the same game!) Then, options in each knot send the player bouncing between them.
Those are the absolute ground-floor basics of Ink. What really distinguishes this scripting language are the affordances available one level up.
For example, there’s something called a “gather,” indicated with a dash. You can find one in my example above, just above the word “Finally.” A gather tells the Ink engine: “Whatever’s happened before this point—whatever options the player has chosen—just bring it all together here, and keep going.”
It turns out you want to do that a lot in a branching story game. Not every option can, or should, send the story careening off in a new direction! Many options are offered for reasons orthogonal to the story. Maybe you want to do a little worldbuilding; maybe you want to give the player a break from reading; maybe you want to tell a joke with three punchlines! Doing any of those things should not require you to splinter your game into three or more divergent realities, each to be resolved with equal richness.
This is the shape of a lot of the Ink that I write: narration, options, gather; narration, options, gather—with particularly momentous options diverting to a different knot.
Does that make sense? There’s a ton more. I mean, I implemented the game of blackjack using Ink; it has variables, if/then statements, logical operators, all of that. Ink also has terrific documentation, and a quick scroll through this page will reveal how much power is hiding under the hood. But the nice thing is, you can ignore almost all of it.
(Steve Jobs voice:) One more thing.
Not only has Inkle Studios developed, released, and maintained this rich, useful scripting language; they’ve also developed, released, and maintained an editor for it. I draft all my Ink using this editor, called Inky, which is free to download.
So! If any of this seems interesting to you, I encourage you to check it out. You can open up Inky, paste in my supremely simple script above, and immediately “play through it” in the editor’s built-in viewer. Then add some options of your own! It’s all very minimal, but it turns out minimal is exactly what you want when you’re prototyping these branches, these stories, these games.
I am back at it, writing new locations. Hot hand!
P.S. Don’t worry!! We’ll have a tasty new sound snack from Jesse next week.
P.P.S. I’d be remiss if I didn’t link to my friend (and Ink mentor!!) Patrick’s Ink tutorial series on YouTube. It’s ideal for visual/auditory learners, and, Patrick delves into the language’s deeper magick.
This has been an edition of my video game development diary, sent by email every few weeks. You can subscribe: