Book Image

Dynamic Story Scripting with the ink Scripting Language

By : Daniel Cox
Book Image

Dynamic Story Scripting with the ink Scripting Language

By: Daniel Cox

Overview of this book

ink is a narrative scripting language designed for use with game engines such as Unity through a plugin that provides an application programming interface (API) to help you to move between the branches of a story and access the values within it. Hands-On Dynamic Story Scripting with the ink Scripting Language begins by showing you how ink understands stories and how to write some simple branching projects. You'll then move on to advanced usage with looping structures, discovering how to use variables to set up dynamic events in a story and defining simple rules to create complex narratives for use with larger Unity projects. As you advance, you'll learn how the Unity plugin allows access to a running story through its API and explore the ways in which this can be used to move data in and out of an ink story to adapt to different interactions and forms of user input. You'll also work with three specific use cases of ink with Unity by writing a dialogue system and creating quest structures and other branching narrative patterns. Finally, this will help you to find out how ink can be used to generate procedural storytelling patterns for Unity projects using different forms of data input. By the end of this book, you will be able to move from a simple story to an intricate Unity project using ink to power complex narrative structures.
Table of Contents (18 chapters)
1
Section 1: ink Language Basics
7
Section 2: ink Unity API
12
Section 3: Narrative Scripting with ink

Creating choices and making weaves

While having code pick parts of a story to produce a new possible narrative for a user could be exciting, most users want some input on what happens next. They want an interactive story. In ink, interactivity is created by presenting the user with choices. Depending on which choice the reader makes, the narrative could then branch in different ways.

Making weaves

Choices in ink are a part of another important concept, weaves. As a user creates a flow from one part to another, they often encounter intersections within a story where branches might be possible depending on what choice is made. This is what is known as a weave within ink. These are collections of choices where each one has the potential to branch the story in different ways.

Choices are written in ink using an asterisk, *. What might appear as a list of things is, in ink, each a different choice within a single weave:

What did I want to eat?
* Apples
* Oranges
* Pears

In the previous code, each line starting with an asterisk is a choice. It starts from the asterisk and extends to the end of the line. Everything that is part of the line becomes a part of the choice. Each asterisk on a new line creates a new choice within the weave:

We smiled again at each other across the coffee shop. I had seen her coming in at this same time for over a week now. We had spoken a couple of times, but I could not bring myself to talk to her more.
As I looked back down at my coffee, I needed to decide.
* I decided to go talk to her.
"Uh. Hi!" I said, maybe a little too loud as I approached her.
* I gave up for now. Maybe tomorrow.
I shook my head to myself and looked away from her and out the window. Today was not the day.

Each choice in a weave has the potential to branch the narrative. In the previous code, there are two choices. However, after each choice is another line of code. When run, ink would understand each line following a choice as being the result of choosing the reader. To help to visually differentiate the result of the choice better, the line following a choice is often indented at its start.

Changing the previous code to use indentation would look as follows:

We smiled at each other again across the coffee shop. I had seen her coming in at this same time for over a week now. We had spoken a couple of times, but I could not bring myself to talk to her more.
As I looked back down at my coffee, I needed to decide.
* I decided to go talk to her.
    "Uh. Hi!" I said, maybe a little too loud, as I approached       her.
* I gave up for now. Maybe tomorrow.
    I shook my head to myself and looked away from her and out       the window. Today was not the day.

Choices within choices

Choices can also appear inside other choices. These are sub-choices and use an additional asterisk to indicate that they are the result of a previous layer of a weave:

Should I really forgive her again? I thought about the options in front of me as I considered what she told me.
* I forgive her.
    ** She does the same behavior again.
        I just end up hurt again.
    ** She really does change.
        She does not have another affair and maybe we can save           our relationship.
* I do not forgive her.
    ** I would have to move out.
        I would need to find another apartment.
    ** I stay with her and try to live again without being in a          relationship.
        I could try going back to being friends like we were           before our relationship.

In the previous code, there are two choices that each lead to their own choices, branching off the central set. This is an example of a complex weave. The first layer of the weave is the initial two choices. The result of either choice is then another weave, which then ends in text. Depending on the user's flow, they might only see part of the overall story when moving between these parts.

One possible branch within the complex weave could be the following output for the reader:

Should I really forgive her again? I thought about the options in front of me as I considered what she told me.
I forgive her.
She does the same behavior again.
I just end up hurt again.

A different series of branches within the story might also create the following output:

Should I really forgive her again? I thought about the options in front of me as I considered what she told me.
I do not forgive her.
I would have to move out.
I would need to find another apartment.

Selective choice output

When using choices, the text of the choice itself appears in its output. This can be changed by using a special concept with choices called selective output. By using open and closing square brackets around any text in the line of the choice, it will not appear as part of the output as a result of making the choice:

What did I want to eat?
* [Apples]
* [Oranges]
* [Pears]
I got some food.

In the previous code, the output, regardless of the choice made by the reader, would be the same:

What did I want to eat?
I got some food.

In the cases where the text of the choice is different from what is shown to the reader, the term option is used. A choice is created in ink using code. What is ultimately shown to the reader is an option.

In more advanced code examples, ink can generate choices dynamically. In these cases, as with selective output, it can be important to understand the use of a choice as something written by a developer and an option as selected by the reader. Often, these can be the same thing, but they do not have to be when writing code in ink.

Selective output also allows creating more dynamic output by selectively showing text from an option in the output. An effect of using selective output is that the closing square bracket in a line signals an end to what is shown to the reader. Any additional text on the same line is ignored:

I looked at the timer again and then at the wires in front of me. I had five seconds to stop this bomb from exploding.
* [I cut the wire.] It was the green one.
* [I cut the wire.] It was the red one.
* [I cut the wire.] It was the blue one.
I looked at the timer again and then at the wires in front me. I had five seconds to stop this bomb from exploding.
It was the green one.

From the reader's perspective, the previous code would show three options. Each one would read I cut the wire. However, the use of selective output is telling ink to ignore the additional text of each color. After making a choice, the user would then see the result of the choice as a new line, with the use of square brackets excluding anything they enclose.

Selective output can often be useful to hide additional information behind a choice where the reader must pick an option and then see the additional text of a line.

Gathering points

Each choice in a weave can potentially branch a narrative. However, sometimes there is a need to gather one or more branches back to where they began. Instead of leading off in a new direction, a gathering point can be used to collapse a more complex weave into a central point. In ink, gathering points are created using a single minus sign (-) on a line:

You peer down at the desk with two drawers.
* Try to open the top drawer.
    It does not open.
    ** Try again more forcefully.
    ** Give up for now
* Try to open the side drawer.
    It does not open.
    ** Try again more forcefully.
    ** Give up for now
- All the drawers seem locked tight.

In the previous code, there are two choices with two sub-choices each. However, at the bottom of the weave is a gathering point. No matter what branch is taken across the first weave and then into the next layer, the flow will always gather at the last line. This is the power of gathering points: they allow a complex weave with multiple layers to collapse into a single point.

The placement of gathering points is important. In ink, stories flow down from the top to the bottom. If the gathering point appeared before the weave, it would be ignored. Without anything to gather, the gathering point does nothing. This also only affects weaves. Multiple gathering points in a story would do nothing without a weave above them to act as a point of collapsing them.

Gathering points only work on a single weave at a time. As the last line of a weave, they act to gather the choices. However, they only apply to one branching structure at a time. A new gathering point is needed per weave to collapse those branches back together:

You peer down at the desk with two drawers to open.
* [Try the top drawer.]
* [Try the side drawer.]
- All the drawers seem locked tight.
You give up on the drawers and look at the top of the desk.
* [Look at the papers on top of the desk.]
* [Pick up the papers and look through them.]
- You find nothing of interest.

In the previous code, both selective output and gathering points are used to create the illusion of two weaves with two choices each. The outcome of each, because they are using gathering points, is the last line of each. Options are presented to the reader, but the code itself collapses any possible branching of each weave and flows the story from the first weave to the second layer.