Unofficial-Ink-Cookbook

Unofficial Ink Cookbook

View the Project on GitHub videlais/Unofficial-Ink-Cookbook

Chapter 11: LIST-ing to a Side

Summary: In this chapter, you will learn how to work with LISTs, some of the basic functionality, and how they can be used within projects.


LIST

Beyond using variables, Ink also provides a data type call a LIST. These store collections of values that can be accessed, changed, and manipulated in different ways in connection to each other.

LIST moods = happy, angry, sad

Rules for Lists:

Because lists will create new variables if included and not previous created, this allows for creating a list of possibilities and then having a new, separate variable.

These can also be used as part of the flow once set earlier, allowing for changing states throughout a story.


Automatically Set to false

The values used in a LIST are automatically set to false. What this means in practice is that any values include in a LIST are in it, but do not count toward its total unless they are “enabled,” set to true.

The following code will show a value of 0.

LIST moods = happy, angry, sad

{ LIST_COUNT(moods) }

Note: function LIST_COUNT() returns the total number of enabled entries in a LIST. If they are not true, they are not counted toward its total.

Enabling Values

Values in a LIST are considered true if they have opening and closing parentheses around them.

The same code which shown a total of zero will change to three when all of its values are now set to true.

LIST moods = (happy), (angry), (sad)

{ LIST_COUNT(moods) }

Built-in Functions

For dealing directly with lists, Ink also has several specific functions. As a LIST can have both true and false values, each of these functions deals with and understands the entries in a LIST in different ways.

LIST_COUNT()

The function LIST_COUNT() returns the number of values in the LIST that are set to true .

LIST moods = (happy), angry, (sad)

{ LIST_COUNT(moods) }

LIST_MIN()

The function LIST_MIN() returns the first true entry in a LIST or nothing if there are no true entries in the LIST.

LIST moods = happy, angry, (sad)

{ LIST_MIN(moods) }

LIST_MAX()

The function LIST_MAX() returns the last true entry in a LIST or nothing if there are no true entries in the LIST.

LIST moods = happy, angry, (sad)

{ LIST_MAX(moods) }

LIST_ALL()

The function LIST_ALL() returns all entries regardless if true or not as comma-separated values.

LIST moods = happy, angry, (sad)

{ LIST_ALL(moods) }

LIST_RANGE(list_name, min_value, max_value)

The function LIST_RANGE() returns a selection from a LIST starting at the minimum value and extending to the maximum values of true values in the LIST. The minimum and maximum values are the numerical values, positions, starting at 1 (unless overwritten).

If the minimum or maximum value is outside the list of values, its nearest correct values is used.

LIST moods = happy, (angry), sad, melancholy

{ LIST_RANGE(moods, 2, 3) }

LIST_VALUE()

The function LIST_VALUE() returns the numerical value of a LIST entry regardless of if it is true or not.

LIST moods = happy, angry, sad, melancholy

{ LIST_VALUE(sad) }

LIST_INVERT()

The function LIST_INVERT() returns a new LIST with each entry’s value to its opposite, true to false and false to true.

LIST moods = happy, angry, sad, melancholy

{ LIST_COUNT(moods) }
~ moods = LIST_INVERT(moods)
{ LIST_COUNT(moods) }

LIST_RANDOM()

The function LIST_RANDOM() returns a random true entry from a LIST. If there are no true entries, the function returns nothing.

LIST moods = (happy), (angry), (sad), (melancholy)

{ LIST_RANDOM(moods) }

Inclusion Testing

Beyond functions to work with LIST values, Ink also has special symbols for working with testing for inclusion in a LIST. When comparing multiple values, they should be within an opening and closing parentheses.

LIST moods = (happy), (angry), (sad), (melancholy)

{ moods ? (happy, angry): Both happy and angry }

The keyword has works the same as using the question mark, ?.

LIST moods = (happy), (angry), (sad), (melancholy)

{ moods has (happy, angry): Both happy and angry }

The exclamation mark works as a negation to the inclusion, question mark, ?, symbol.

LIST moods = happy, angry, sad, melancholy

{ moods !? (happy, angry): Neither happy nor angry }

The keyword hasnt is the same as using the symbols, !?

LIST moods = happy, angry, sad, melancholy

{ moods hasnt (happy, angry): Neither happy nor angry }

Manipulating List Values

Like other variable values, a LIST can also use some of the same mathematical symbols others can. However, a LIST can only use values associated with either itself or another LIST within the same project.

Addition

Adding a value to a LIST, VAR, or CONST using existing LIST values works through the += symbol pairing. It means “set the current value to itself plus this new value.” When used with LIST values, they can be “added” to the existing LIST.

LIST Items = (Dagger), (Lead_Pipe), (Spanner), (Candlestick), (Revolver), (Rope)

LIST clues = Main_Room

~ clues += (Dagger)

Current Clues: {clues}

Subtraction

Removing values from a LIST or using LIST values works similar to addition. It uses the -= symbols to mean “set the current value to itself minus this new value.”

LIST Items = (Dagger), (Lead_Pipe), (Spanner), (Candlestick), (Revolver), (Rope)

LIST clues = Main_Room

~ Items -= (Dagger)
~ clues += (Dagger)

Current Clues: {clues}

Conflicting Values and Variable Names

One of the rules of LIST is that they must contain unique variable names. A value cannot exist in two separate LISTs! Therefore, when moving values from one LIST to another, it is recommended to remove first and then add to the new LIST.

LIST Items = (Dagger), (Lead_Pipe), (Spanner), (Candlestick), (Revolver), (Rope)

LIST clues = Main_Room

~ temp randomClue = LIST_RANDOM(Items)

The random clue is {randomClue}.

~ Items -= randomClue
~ clues += randomClue

Current Clues: {clues}

Comparing LISTS

While Ink supplies the ability to compare two different LISTs and their entries, it is not as helpful as it may first seem. Comparing LISTs only work on the numerical values of entries. However, the operators >, <, >=, and <= all work.

Less Than

LIST_A < LIST_B

The smallest value in A is less than the smallest values in B.

Greater Than

LIST_A > LIST_B

The smallest value in A is bigger than the largest values in B.

Greater Than Or Equal To

LIST_A >= LIST_B

The smallest value in A is at least the smallest value in B, and the largest value in A is at least the largest value in B.

Less Than Or Equal To

LIST_A <= LIST_B

The smallest value is A is smaller than all values in B, and the largest value in A smaller than the largest value in B.


Multi-listed Lists

Once a LIST value exists, it can be used by any LIST, VAR, or temp variable. Beyond moving values between LISTs, it is also possible to intermix values from LISTs once they are created.

In more complex projects, this can be a way to define all possible values in a LIST and then use them to define different states or descriptions during the running of a project.

LIST Items = (Dagger), (Lead_Pipe), (Spanner), (Candlestick), (Revolver), (Rope)
LIST Rooms = (Dining_Room), (Lounge), (Kitchen), (Study), (Hall), (Billiard_Room), (Conservatory), (Ballroom), (Library), (Cellar)

VAR CLUE = ()

~ temp item = LIST_RANDOM(Items)

You found {item}

~ temp room = LIST_RANDOM(Rooms)

You are in the {room}

~ CLUE += item
~ CLUE += room

Current clues are: {CLUE}

Example:

LIST allPeople = (Major_Mustard), (Lt_Lemon), (Sam_White)

~ temp randomPerson = LIST_RANDOM(allPeople)

VAR clues = ()
~ clues += randomPerson

Who do you accuse?
* [Major Mustard]
    {checkClues(Major_Mustard):
    - 1:
        It is her!
     -0:
        It is not her!
    }
    -> DONE
* [Lt. Lemon]
    {checkClues(Major_Mustard):
    - 1:
        It is him!
     -0:
        It is not him!
    }
    -> DONE
* [Sam White]
    { checkClues(Sam_White):
    - 1:
        It is them!
     -0:
        It is not them!
    }
    -> DONE

=== function checkClues(x) ===
~ return clues ? x