code:
# Markup {#markup}

Note:
Except where noted, all markup has been available since v2.0.0.

## Naked Variable {#markup-naked-variable}

In addition to using one of the print macros ([`<<print>>`](#macros-macro-print), [`<<=>>`](#macros-macro-equal), [`<<->>`](#macros-macro-hyphen)) to print the values of TwineScript variables, SugarCube's naked variable markup allows printing them simply by including them within your normal passage text—i.e., variables in passage text are interpolated into a string representation of their values.

The following forms are supported by the naked variable markup:

		Type
		Syntax
		Example

		Simple variable

$variable

$name

		Property access,
dot notation

$variable.property

$thing.name

		Index/property access,
square bracket notation

$variable[numericIndex]

$variable["property"]

$variable['property']

$variable[$indexOrPropertyVariable]

$thing[0]

$thing["name"]

$thing['name']

$thing[$member]

If you need to print anything more complex—e.g., using a calculation, `$variable[_i + 1]`, or a method call, `$variable.someMethod()`—then you will still need to use one of the print macros.

For example:

```
/* Explicitly printing the value of $name via the <<print>> macro */
Well hello there, <<print $name>>.

/* Implicitly printing the value of $name via the naked variable markup */
Well hello there, $name.

/* Assuming $name is set to "Mr. Freeman", both should yield the following */
Well hello there, Mr. Freeman.
```

Because variables within your passage text are transformed into their values automatically, if you actually want to output a variable as-is—i.e., without interpolation; e.g., for a tutorial, debug output, or whatever—then you'll need to escape it in some fashion.  For example:

```
/* Using the nowiki markup: """…""" (triple double-quotes) */
The variable """$name""" is set to: $name

/* Using the nowiki markup: <nowiki>…</nowiki> */
The variable <nowiki>$name</nowiki> is set to: $name

/* Using the double dollar-sign markup (which escapes the $-sigil): $$ */
The variable $$name is set to: $name

/* Assuming $name is set to "Mr. Freeman", all of the above should yield the following */
The variable $name is set to: Mr. Freeman
```

Additionally, you could use the inline code markup to escape the variable, though it will also wrap the escaped variable within a `<code>` element, so it's probably best used for examples and tutorials.  For example:

```
/* Using the inline code markup: {{{…}}} (triple curly braces) */
The variable {{{$name}}} is set to: $name

/* Assuming $name is set to "Mr. Freeman", it should yield the following */
The variable <code>$name</code> is set to: Mr. Freeman
```

## Link {#markup-link}

SugarCube's link markup consists of a required `Link` component and optional `Text` and `Setter` components.  The `Link` and `Text` components may be either plain text or any valid TwineScript expression, which will be evaluated early—i.e., when the link is initially processed.  The `Setter` component, which only works with passage links, must be a valid [TwineScript expression](#twinescript-expressions), of the [`<<set>>` macro](#macros-macro-set) variety, which will be evaluated late—i.e., when the link is clicked on.

The `Link` component value may be the title of a passage or any valid URL to a resource (local or remote).

In addition to the standard pipe separator (`|`) used to separate the `Link` and `Text` components (as seen below), SugarCube also supports the arrow separators (`->` & `<-`).  Particular to the arrow separators, the arrows' direction determines the order of the components, with the arrow always pointing at the `Link` component—i.e., the right arrow works like the pipe separator, `Text->Link`, while the left arrow is reversed, `Link<-Text`.

Warning (Twine 2):
Due to how the Twine 2 automatic passage creation feature currently works, using any TwineScript expression for the Link component will cause a passage named after the expression to be created that will need to be deleted.  To avoid this problem, it's suggested that you use the separate argument form of the <<link>> macro in Twine 2 when you need to use an expression.

For the following examples assume: $go is "Grocery" and $show is "Go buy milk"

		Syntax
		Example

[[Link]]

[[Grocery]]

[[$go]]

[[Text|Link]]

[[Go buy milk|Grocery]]

[[$show|$go]]

[[Link][Setter]]

[[Grocery][$bought to "milk"]]

[[$go][$bought to "milk"]]

[[Text|Link][Setter]]

[[Go buy milk|Grocery][$bought to "milk"]]

[[$show|$go][$bought to "milk"]]

## Image {#markup-image}

SugarCube's image markup consists of a required `Image` component and optional `Title`, `Link`, and `Setter` components.  The `Image`, `Title`, and `Link` components may be either plain text or any valid TwineScript expression, which will be evaluated early—i.e., when the link is initially processed.  The `Setter` component, which only works with passage links, must be a valid [TwineScript expression](#twinescript-expressions), of the [`<<set>>` macro](#macros-macro-set) variety, which will be evaluated late—i.e., when the link is clicked on.

The `Image` component value may be any valid URL to an image resource (local or remote) or the title of an [embedded image passage (Twine 1 & Tweego only)](http://twinery.org/wiki/image).  The `Link` component value may be the title of a passage or any valid URL to a resource (local or remote).

In addition to the standard pipe separator (`|`) used to separate the `Image` and `Title` components (as seen below), SugarCube also supports the arrow separators (`->` & `<-`).  Particular to the arrow separators, the arrows' direction determines the order of the components, with the arrow always pointing at the `Image` component—i.e., the right arrow works like the pipe separator, `Title->Image`, while the left arrow is reversed, `Image<-Title`.

Warning (Twine 2):
Due to how the Twine 2 automatic passage creation feature currently works, using any TwineScript expression for the Link component will cause a passage named after the expression to be created that will need to be deleted.  To avoid this problem, it's suggested that you use the separate argument form of the <<link>> macro in Twine 2 when you need to use an expression.

For the following examples assume: $src is home.png, $go is "Home", and $show is "Go home"

		Syntax
		Example

[img[Image]]

[img[home.png]]

[img[$src]]

[img[Image][Link]]

[img[home.png][Home]]

[img[$src][$go]]

[img[Image][Link][Setter]]

[img[home.png][Home][$done to true]]

[img[$src][$go][$done to true]]

[img[Title|Image]]

[img[Go home|home.png]]

[img[$show|$src]]

[img[Title|Image][Link]]

[img[Go home|home.png][Home]]

[img[$show|$src][$go]]

[img[Title|Image][Link][Setter]]

[img[Go home|home.png][Home][$done to true]]

[img[$show|$src][$go][$done to true]]

#### Within stylesheets

A restricted subset of the image markup, allowing only the `Image` component, may be used within stylesheets—primarily to allow the easy use of [image passages](#guide-media-passages).  For example:

```
/* Using the external image "forest.png" as the <body> background. */
body {
	background-image: [img[forest.png]];
}

/* Using the image passage "lagoon" as the <body> background. */
body {
	background-image: [img[lagoon]];
}
```

## HTML Attribute {#markup-html-attribute}

Warning:
None of these features work within the verbatim HTML markup.

### Special Attribute {#markup-html-attribute-special}

SugarCube provides a few special HTML attributes, which you may add to HTML tags to enable special behaviors.  There are attributes for passage links, media passages, and setters.

		Type
		Attribute
		Example

		Passage, Link

data-passage

<a data-passage="PassageName">Do the thing</a>

<area shape="rect" coords="25,25,75,75" data-passage="PassageName">

<button data-passage="PassageName">Do the thing</button>

		Passage, Audio

data-passage

<audio data-passage="AudioPassageName">

		Passage, Image

data-passage

<img data-passage="ImagePassageName">

		Passage, Source

data-passage

<source data-passage="AudioOrVideoPassageName">

		Passage, Video

data-passage

<video data-passage="VideoPassageName">

		Setter

data-setter

<a data-passage="PassageName" data-setter="$thing to 'done'">Do the thing</a>

<area shape="rect" coords="25,25,75,75" data-passage="PassageName"
	data-setter="$thing to 'done'">

<button data-passage="PassageName" data-setter="$thing to 'done'">Do the thing</button>

#### History:

* `v2.0.0`: Introduced.
* `v2.24.0`: Added `data-passage` attribute support to `<audio>`, `<source>`, and `<video>` tags.

### Attribute Directive {#markup-html-attribute-directive}

HTML attributes may be prefixed with directives, special text, which trigger special processing of such attributes.

Evaluation directive: sc-eval:, @

	The evaluation directive causes the attribute's value to be evaluated as TwineScript.  Post-evaluation, the directive will be removed from the attribute's name and the result of the evaluation will be used as the actual value of the attribute.

Warning:
	The evaluation directive is not allowed on the data-setter attribute—as its function is to evaluate its contents upon activation of its own element—and any such attempt will cause an error.

For the following examples assume: _id is "foo"

			Syntax
			Example
			Rendered As

sc-eval:attribute-name

<span sc-eval:id="_id">…</span>

<span id="foo">…</span>

@attribute-name

<span @id="_id">…</span>

<span id="foo">…</span>

#### History:

* `v2.21.0`: Introduced.
* `v2.23.5`: Fixed an issue with the evaluation directive where using multiple directives on a single HTML tag would result in some being unprocessed.

## Line Continuation {#markup-line-continuation}

See Also:
The various no-break features—<<nobr>> macro, nobr special tag, and Config.passages.nobr setting—all perform a similar, though slightly different, function.

Warning:
Line continuations, or any markup that relies on line positioning, are incompatible with the no-break features because of how the latter function.

A backslash (`\`) that begins or ends a line is the line continuation markup.  Upon processing the backslash, associated line break, and all whitespace between them are removed—thus, joining the nearby lines together.  This is mostly useful for controlling whitespace when you want to wrap lines for readability, but not generate extra whitespace upon display, and the [`<<silently>>` macro](#macros-macro-silently) isn't an option because you need to generate output.

For example, all of the following: (n.b., `·` represents whitespace that will be removed, `¬` represents line breaks)

```
The rain in Spain falls \¬
mainly on the plain.

The rain in Spain falls \····¬
mainly on the plain.

The rain in Spain falls¬
\ mainly on the plain.

The rain in Spain falls¬
····\ mainly on the plain.
```

Yield the single line in the final output:

```
The rain in Spain falls mainly on the plain.
```

## Heading {#markup-heading}

An exclamation point (`!`) that begins a line defines the heading markup.  It consists of one to six exclamation points, each additional one beyond the first signifying a lesser heading.

		Type
		Syntax & Example
		Rendered As
		Displays As (roughly)

		Level 1

!Level 1 Heading

<h1>Level 1 Heading</h1>

Level 1 Heading

		Level 2

!!Level 2 Heading

<h2>Level 2 Heading</h2>

Level 2 Heading

		Level 3

!!!Level 3 Heading

<h3>Level 3 Heading</h3>

Level 3 Heading

		Level 4

!!!!Level 4 Heading

<h4>Level 4 Heading</h4>

Level 4 Heading

		Level 5

!!!!!Level 5 Heading

<h5>Level 5 Heading</h5>

Level 5 Heading

		Level 6

!!!!!!Level 6 Heading

<h6>Level 6 Heading</h6>

Level 6 Heading

## Style {#markup-style}

Warning:
Because the style markups use the same tokens to begin and end each markup, the same style cannot be nested within itself.

		Type
		Syntax & Example
		Rendered As
		Displays As (roughly)

		Emphasis

//Emphasis//

<em>Emphasis</em>

		Emphasis

		Strong

''Strong''

<strong>Strong</strong>

		Strong

		Underline

__Underline__

<u>Underline</u>

		Underline

		Strikethrough

==Strikethrough==

<s>Strikethrough</s>

		<s>Strikethrough</s>

		Superscript

Super^^script^^

Super<sup>script</sup>

		Superscript

		Subscript

Sub~~script~~

Sub<sub>script</sub>

		Subscript

## List {#markup-list}

An asterisk (`*`) or number sign (`#`) that begins a line defines a member of the unordered or ordered list markup, respectively.

		Type
		Syntax & Example
		Rendered As
		Displays As (roughly)

		Unordered

* A list item
* Another list item

<ul>
<li>A list item</li>
<li>Another list item</li>
</ul>

A list item

Another list item

		Ordered

# A list item
# Another list item

<ol>
<li>A list item</li>
<li>Another list item</li>
</ol>

A list item

Another list item

## Blockquote {#markup-blockquote}

A right angle bracket (`>`) that begins a line defines the blockquote markup.  It consists of one or more right angle brackets, each additional one beyond the first signifying a level of nested blockquote.

		Syntax & Example
		Rendered As
		Displays As (roughly)

>Line 1
>Line 2
>>Nested 1
>>Nested 2

<blockquote>Line 1<br>
Line 2<br>
<blockquote>Nested 1<br>
Nested 2<br>
</blockquote></blockquote>

Line 1
Line 2

Nested 1
Nested 2

## Code {#markup-code}

		Type
		Syntax & Example
		Rendered As
		Displays As (roughly)

		Inline

{{{Code}}}

<code>Code</code>

Code

		Block

{{{
Code
More code
}}}

<pre><code>Code
More code
</code></pre>

Code
More code

## Horizontal Rule {#markup-horizontal-rule}

A set of four hyphen/minus characters (`-`) that begins a line defines the horizontal rule markup.

		Type
		Syntax & Example
		Rendered As
		Displays As (roughly)

		Horizontal rule

----

<hr>

## Verbatim Text {#markup-verbatim-text}

The verbatim text markup disables processing of *all* markup contained within—both SugarCube and HTML—passing its contents directly into the output as plain text.

		Type
		Syntax & Example
		Rendered As
		Displays As (roughly)

		Triple double quotes

"""No //format//"""

No //format//

		No //format//

		<nowiki> tag

<nowiki>No //format//</nowiki>

No //format//

		No //format//

## Verbatim HTML {#markup-verbatim-html}

A set of opening and closing <html> tags—i.e., `<html></html>`—defines the verbatim HTML markup.  The verbatim HTML markup disables processing of *all* markup contained within—both SugarCube and HTML—passing its contents directly into the output as HTML markup for the browser.  Thus, you should only use plain HTML markup within the verbatim markup—meaning using none of SugarCube's special HTML [attributes](#markup-html-attribute-special) or [directives](#markup-html-attribute-directive).

Note:
You should virtually never need to use the verbatim HTML markup.

## Custom Style {#markup-custom-style}

Warning:
Because the custom style markup uses the same tokens to begin and end the markup, it cannot be nested within itself.

		Type
		Syntax
		Example
		Rendered As

		Inline

@@style-list1;Text@@

@@#alfa;.bravo;Text@@

<span id="alfa" class="bravo">Text</span>

@@color:red;Text@@

<span style="color:red">Text</span>

		Block

@@style-list1;
Text
@@

@@#alfa;.bravo;
Text
@@

<div id="alfa" class="bravo">Text</div>

@@color:red;
Text
@@

<div style="color:red">Text</div>

	The style-list should be a semi-colon (;) separated list consisting of one or more of the following:

A single unique hash-prefixed ID—e.g., #alfa.

Dot-prefixed class names—e.g., .bravo.

Style properties—e.g., color:red.

	As of v2.31.0, the ID and class names components may be conjoined without need of extra semi-colons—e.g., #alfa;.bravo;.charlie; may also be written as #alfa.bravo.charlie;.

## Template {#markup-template}

A text replacement markup.  The template markup begins with a question mark (`?`) followed by the template name—e.g., `?yolo`—and are set up as functions-that-return-strings, strings, or arrays of either—from which a random member is selected whenever the template is processed.  They are defined via the [`Template` API](#template-api).

For example, consider the following markup:

```
?He was always willing to lend ?his ear to anyone.
```

Assuming that `?He` resolves to `She` and `?his` to `her`, then that will produce the following output:

```
She was always willing to lend her ear to anyone.
```

#### History:

* `v2.29.0`: Introduced.

## Comment {#markup-comment}

Note:
Comments used within passage markup are not rendered into the page output.

		Type
		Syntax & Example
		Supported Within…

		C-style, Block

/* This is a comment. */

		Passage markup, JavaScript, Stylesheets

		TiddlyWiki, Block

/% This is a comment. %/

		Passage markup

		HTML, Block

<!-- This is a comment. -->

		Passage markup


code:
# Methods {#methods}

Most of the methods listed below are SugarCube extensions, with the rest being either JavaScript natives or bundled library methods that are listed here for their utility—though, this is not an exhaustive list.

For more information see:

* [MDN's JavaScript reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference) for native JavaScript object methods—and more.
* [jQuery API reference](https://api.jquery.com/) for native jQuery methods.

Additionally.  SugarCube includes polyfills for virtually all JavaScript (ECMAScript) 5 & 6 native object methods—via the [es5-shim](https://github.com/es-shims/es5-shim/) and [es6-shim](https://github.com/paulmillr/es6-shim/) polyfill libraries (shims only, no shams)—so they may be safely used even if your project will be played in ancient browsers that do not natively support them.

## Array Methods {#methods-array}

### `<Array>.concat(members…)` → *Array<any>* {#methods-array-prototype-method-concat}

Concatenates one or more members to the end of the base array and returns the result as a new array.  Does not modify the original.

#### History: *native JavaScript method*

#### Parameters:

* **`members`:** (*any*…) The members to concatenate.  Members that are arrays will be merged—i.e., their members will be concatenated, rather than the array itself.

#### Examples:

```
// Given: $fruits1 = ["Apples", "Oranges"], $fruits2 = ["Pears", "Plums"]
$fruits1.concat($fruits2)            → Returns ["Apples", "Oranges", "Pears", "Plums"]
$fruits1.concat($fruits2, $fruits2)  → Returns ["Apples", "Oranges", "Pears", "Plums", "Pears", "Plums"]
$fruits1.concat("Pears")             → Returns ["Apples", "Oranges", "Pears"]
$fruits1.concat("Pears", "Pears")    → Returns ["Apples", "Oranges", "Pears", "Pears"]
$fruits1.concat($fruits2, "Pears")   → Returns ["Apples", "Oranges", "Pears", "Plums", "Pears"]
```

### `<Array>.concatUnique(members…)` → *Array<any>* {#methods-array-prototype-method-concatunique}

Concatenates one or more unique members to the end of the base array and returns the result as a new array.  Does not modify the original.

#### History:

* `v2.21.0`: Introduced.

#### Parameters:

* **`members`:** (*any*…) The members to concatenate.  Members that are arrays will be merged—i.e., their members will be concatenated, rather than the array itself.

#### Examples:

```
// Given: $fruits1 = ["Apples", "Oranges"], $fruits2 = ["Pears", "Plums"]
$fruits1.concatUnique($fruits2)            → Returns ["Apples", "Oranges", "Pears", "Plums"]
$fruits1.concatUnique($fruits2, $fruits2)  → Returns ["Apples", "Oranges", "Pears", "Plums"]
$fruits1.concatUnique("Pears")             → Returns ["Apples", "Oranges", "Pears"]
$fruits1.concatUnique("Pears", "Pears")    → Returns ["Apples", "Oranges", "Pears"]
$fruits1.concatUnique($fruits2, "Pears")   → Returns ["Apples", "Oranges", "Pears", "Plums"]
```

### `<Array>.count(needle [, position])` → *integer* {#methods-array-prototype-method-count}

Returns the number of times that the given member was found within the array, starting the search at `position`.

#### History:

* `v2.0.0`: Introduced.

#### Parameters:

* **`needle`:** (*any*) The member to count.
* **`position`:** (optional, *integer*) The zero-based index at which to begin searching for `needle`.  If omitted, will default to `0`.

#### Examples:

```
// Given: $fruits = ["Apples", "Oranges", "Plums", "Oranges"]
$fruits.count("Oranges")     → Returns 2
$fruits.count("Oranges", 2)  → Returns 1
```

### `<Array>.countWith(predicate [, thisArg])` → *integer* {#methods-array-prototype-method-countwith}

Returns the number of times that members within the array pass the test implemented by the given predicate function.

#### History:

* `v2.36.0`: Introduced.

#### Parameters:

* **`predicate`:** (*function*) The function used to test each member.  It is called with three arguments:
	* **`value`:** (*any*) The member being processed.
	* **`index`:** (optional, *integer*) The index of member being processed.
	* **`array`:** (optional, *array*) The array being processed.
* **`thisArg`:** (optional, *any*) The value to use as `this` when executing `predicate`.

#### Examples:

```
// Given: $fruits = ["Apples", "Oranges", "Plums", "Oranges"]
$fruits.countWith(function (fruit) { return fruit === "Oranges"; })  → Returns 2
```

```
// Given: $numbers = [1, 2.3, 4, 76, 3.1]
$numbers.countWith(Number.isInteger)  → Returns 3
```

```
// Given: $items = [
// 	{ name : 'Healing potion', kind : 'potion' },
// 	{ name : 'Longsword', kind : 'weapon' },
// 	{ name : 'Mana potion', kind : 'potion' },
// 	{ name : 'Dead rat', kind : 'junk' },
// 	{ name : 'Endurance potion', kind : 'potion' },
// 	{ name : 'Shortbow', kind : 'weapon' }
// ]
$items.countWith(function (item) { return item.kind === 'junk'; })  → Returns 1
```

### `<Array>.delete(needles…)` → *Array<any>* {#methods-array-prototype-method-delete}

Removes all instances of the given members from the array and returns a new array containing the removed members.

#### History:

* `v2.5.0`: Introduced.

#### Parameters:

* **`needles`:** (*any*… | *Array<any>*) The members to remove.  May be a list of members or an array.

#### Examples:

```
// Given: $fruits = ["Apples", "Oranges", "Plums", "Oranges"]
$fruits.delete("Oranges")          → Returns ["Oranges", "Oranges"]; $fruits ["Apples", "Plums"]
$fruits.delete("Apples", "Plums")  → Returns ["Apples", "Plums"]; $fruits ["Oranges", "Oranges"]
```

### `<Array>.deleteAt(indices…)` → *Array<any>* {#methods-array-prototype-method-deleteat}

Removes all of the members at the given indices from the array and returns a new array containing the removed members.

#### History:

* `v2.5.0`: Introduced.

#### Parameters:

* **`indices`:** (*integer*… | *Array<integer>*) The indices of the members to remove.  May be a list or array of indices.

#### Examples:

```
// Given: $fruits = ["Apples", "Oranges", "Plums", "Oranges"]
$fruits.deleteAt(2)     → Returns ["Plums"]; $fruits ["Apples", "Oranges", "Oranges"]
$fruits.deleteAt(1, 3)  → Returns ["Oranges", "Oranges"]; $fruits ["Apples", "Plums"]
$fruits.deleteAt(0, 2)  → Returns ["Apples", "Plums"]; $fruits ["Oranges", "Oranges"]
```

### `<Array>.deleteWith(predicate [, thisArg])` → *Array<any>* {#methods-array-prototype-method-deletewith}

Removes all of the members from the array that pass the test implemented by the given predicate function and returns a new array containing the removed members.

#### History:

* `v2.25.0`: Introduced.

#### Parameters:

* **`predicate`:** (*function*) The function used to test each member.  It is called with three arguments:
	* **`value`:** (*any*) The member being processed.
	* **`index`:** (optional, *integer*) The index of member being processed.
	* **`array`:** (optional, *array*) The array being processed.
* **`thisArg`:** (optional, *any*) The value to use as `this` when executing `predicate`.

#### Examples:

```
// Given: $fruits = ["Apples", "Apricots", "Oranges"]

→ Returns ["Apricots"]; $fruits ["Apples", "Oranges"]
$fruits.deleteWith(function (val) {
	return val === "Apricots";
})

→ Returns ["Apples", "Apricots"]; $fruits ["Oranges"]
$fruits.deleteWith(function (val) {
	return val.startsWith("Ap");
})

// Given: $fruits = [{ name : "Apples" }, { name : "Apricots" }, { name : "Oranges" }]

→ Returns [{ name : "Apricots" }]; $fruits [{ name : "Apples" }, { name : "Oranges" }]
$fruits.deleteWith(function (val) {
	return val.name === "Apricots";
})

→ Returns [{ name : "Apples" }, { name : "Apricots" }]; $fruits [{ name : "Oranges" }]
$fruits.deleteWith(function (val) {
	return val.name.startsWith("Ap");
})
```

### `<Array>.first()` → *any* {#methods-array-prototype-method-first}

Returns the first member from the array.  Does not modify the original.

#### History:

* `v2.27.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
$pies.first()  → Returns "Blueberry"
```

### `<Array>.flat(depth)` → *Array<any>* {#methods-array-prototype-method-flat}

Returns a new array consisting of the source array with all sub-array elements concatenated into it recursively up to the given depth.  Does not modify the original.

#### History: *native JavaScript method*

#### Parameters:

* **`depth`:** (optional, *integer*) The number of nested array levels should be flattened.  If omitted, will default to `1`.

#### Examples:

```
// Given: $npa = [["Alfa", "Bravo"], [["Charlie", "Delta"], ["Echo"]], "Foxtrot"]

$npa.flat()   → Returns ["Alfa", "Bravo", ["Charlie", "Delta"], ["Echo"], "Foxtrot"]
$npa.flat(1)  → Returns ["Alfa", "Bravo", ["Charlie", "Delta"], ["Echo"], "Foxtrot"]
$npa.flat(2)  → Returns ["Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"]
```

### `<Array>.flatMap(callback [, thisArg])` → *Array<any>* {#methods-array-prototype-method-flatmap}

Returns a new array consisting of the result of calling the given mapping function on every element in the source array and then concatenating all sub-array elements into it recursively up to a depth of `1`.  Does not modify the original.

Note:
Identical to calling <Array>.map(…).flat().

#### History: *native JavaScript method*

#### Parameters:

* **`callback`:** (*function*) The function used to produce members of the new array.  It is called with three arguments:
	* **`value`:** (*any*) The member being processed.
	* **`index`:** (optional, *integer*) The index of member being processed.
	* **`array`:** (optional, *array*) The array being processed.
* **`thisArg`:** (optional, *any*) The value to use as `this` when executing `callback`.

#### Examples:

```
// Given: $npa = ["Alfa", "Bravo Charlie", "Delta Echo Foxtrot"]

→ Returns ["Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"]
$npa.flatMap(function (val) {
	return val.split(" ");
})
```

### `<Array>.includes(needle [, position])` → *boolean* {#methods-array-prototype-method-includes}

Returns whether the given member was found within the array, starting the search at `position`.

#### History: *native JavaScript method*

#### Parameters:

* **`needle`:** (*any*) The member to find.
* **`position`:** (optional, *integer*) The zero-based index at which to begin searching for `needle`.  If omitted, will default to `0`.

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
<<if $pies.includes("Cherry")>>…found Cherry pie…<</if>>
<<if $pies.includes("Pecan", 3)>>…found Pecan pie within ["Pecan", "Pumpkin"]…<</if>>
```

### `<Array>.includesAll(needles…)` → *boolean* {#methods-array-prototype-method-includesall}

Returns whether all of the given members were found within the array.

#### History:

* `v2.10.0`: Introduced.

#### Parameters:

* **`needles`:** (*any*… | *Array<any>*) The members to find.  May be a list of members or an array.

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
<<if $pies.includesAll("Cherry", "Pecan")>>…found Cherry and Pecan pies…<</if>>

// Given: $search = ["Blueberry", "Pumpkin"]
<<if $pies.includesAll($search)>>…found Blueberry and Pumpkin pies…<</if>>
```

### `<Array>.includesAny(needles…)` → *boolean* {#methods-array-prototype-method-includesany}

Returns whether any of the given members were found within the array.

#### History:

* `v2.10.0`: Introduced.

#### Parameters:

* **`needles`:** (*any*… | *Array<any>*) The members to find.  May be a list of members or an array.

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
<<if $pies.includesAny("Cherry", "Pecan")>>…found Cherry or Pecan pie…<</if>>

// Given: $search = ["Blueberry", "Pumpkin"]
<<if $pies.includesAny($search)>>…found Blueberry or Pumpkin pie…<</if>>
```

### `<Array>.last()` → *any* {#methods-array-prototype-method-last}

Returns the last member from the array.  Does not modify the original.

#### History:

* `v2.27.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
$pies.last()  → Returns "Pumpkin"
```

### `<Array>.pluck()` → *any* {#methods-array-prototype-method-pluck}

Removes and returns a random member from the base array.

#### History:

* `v2.0.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
$pies.pluck()  → Removes and returns a random pie from the array
```

### `<Array>.pluckMany(want)` → *Array<any>* {#methods-array-prototype-method-pluckmany}

Randomly removes the given number of members from the base array and returns the removed members as a new array.

#### History:

* `v2.20.0`: Introduced.

#### Parameters:

* **`want`:** (optional, *integer*) The number of members to pluck.  Cannot pluck more members than the base array contains.

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
$pies.pluckMany(3)  → Removes three random pies from the array and returns them as a new array
```

### `<Array>.pop()` → *any* {#methods-array-prototype-method-pop}

Removes and returns the last member from the array, or `undefined` if the array is empty.

#### History: *native JavaScript method*

#### Parameters: *none*

#### Examples:

```
// Given: $fruits = ["Apples", "Oranges", "Pears"]
$fruits.pop()  → Returns "Pears"; $fruits ["Apples", "Oranges"]
```

### `<Array>.push(members…)` → *number* {#methods-array-prototype-method-push}

Appends one or more members to the end of the base array and returns its new length.

#### History: *native JavaScript method*

#### Parameters:

* **`members`:** (*any*…) The members to append.

#### Examples:

```
// Given: $fruits = ["Apples", "Oranges"]
$fruits.push("Apples")  → Returns 3; $fruits ["Apples", "Oranges", "Apples"]

// Given: $fruits = ["Apples", "Oranges"]
$fruits.push("Plums", "Plums")  → Returns 4; $fruits ["Apples", "Oranges", "Plums", "Plums"]
```

### `<Array>.pushUnique(members…)` → *number* {#methods-array-prototype-method-pushunique}

Appends one or more unique members to the end of the base array and returns its new length.

#### History:

* `v2.21.0`: Introduced.

#### Parameters:

* **`members`:** (*any*…) The members to append.

#### Examples:

```
// Given: $fruits = ["Apples", "Oranges"]
$fruits.pushUnique("Apples")  → Returns 2; $fruits ["Apples", "Oranges"]

// Given: $fruits = ["Apples", "Oranges"]
$fruits.pushUnique("Plums", "Plums")  → Returns 3; $fruits ["Apples", "Oranges", "Plums"]
```

### `<Array>.random()` → *any* {#methods-array-prototype-method-random}

Returns a random member from the base array.  Does not modify the original.

#### History:

* `v2.0.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
$pies.random()  → Returns a random pie from the array
```

### `<Array>.randomMany(want)` → *Array<any>* {#methods-array-prototype-method-randommany}

Randomly selects the given number of unique members from the base array and returns the selected members as a new array.  Does not modify the original.

#### History:

* `v2.20.0`: Introduced.

#### Parameters:

* **`want`:** (optional, *integer*) The number of members to select.  Cannot select more members than the base array contains.

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
$pies.randomMany(3)  → Returns a new array containing three unique random pies from the array
```

### `<Array>.shift()` → *any* {#methods-array-prototype-method-shift}

Removes and returns the first member from the array, or `undefined` if the array is empty.

#### History: *native JavaScript method*

#### Parameters: *none*

#### Examples:

```
// Given: $fruits = ["Apples", "Oranges", "Pears"]
$fruits.shift()  → Returns "Apples"; $fruits ["Oranges", "Pears"]
```

### `<Array>.shuffle()` → *Array<any>* {#methods-array-prototype-method-shuffle}

Randomly shuffles the array.

#### History:

* `v2.0.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Given: $pies = ["Blueberry", "Cherry", "Cream", "Pecan", "Pumpkin"]
$pies.shuffle()  → Randomizes the order of the pies in the array
```

### `<Array>.unshift(members…)` → *number* {#methods-array-prototype-method-unshift}

Prepends one or more members to the beginning of the base array and returns its new length.

#### History: *native JavaScript method*

#### Parameters:

* **`members`:** (*any*…) The members to append.

#### Examples:

```
// Given: $fruits = ["Oranges", "Plums"]
$fruits.unshift("Oranges")  → Returns 3; $fruits ["Oranges", "Oranges", "Plums"]

// Given: $fruits = ["Oranges", "Plums"]
$fruits.unshift("Apples", "Apples")  → Returns 4; $fruits ["Apples", "Apples", "Oranges", "Plums"]
```

### `<Array>.unshiftUnique(members…)` → *number* {#methods-array-prototype-method-unshiftunique}

Prepends one or more unique members to the beginning of the base array and returns its new length.

#### History:

* `v2.21.0`: Introduced.

#### Parameters:

* **`members`:** (*any*…) The members to append.

#### Examples:

```
// Given: $fruits = ["Oranges", "Plums"]
$fruits.unshiftUnique("Oranges")  → Returns 2; $fruits ["Oranges", "Plums"]

// Given: $fruits = ["Oranges", "Plums"]
$fruits.unshiftUnique("Apples", "Apples")  → Returns 3; $fruits ["Apples", "Oranges", "Plums"]
```

### `<Array>.contains(needle [, position])` → *boolean* {#methods-array-prototype-method-contains}

Deprecated:
This method has been deprecated and should no longer be used.  See the <Array>.includes() method for its replacement.

#### History:

* `v2.0.0`: Introduced.
* `v2.10.0`: Deprecated in favor of `<Array>.includes()`.

### `<Array>.containsAll(needles…)` → *boolean* {#methods-array-prototype-method-containsall}

Deprecated:
This method has been deprecated and should no longer be used.  See the <Array>.includesAll() method for its replacement.

#### History:

* `v2.0.0`: Introduced.
* `v2.10.0`: Deprecated in favor of `<Array>.includesAll()`.

### `<Array>.containsAny(needles…)` → *boolean* {#methods-array-prototype-method-containsany}

Deprecated:
This method has been deprecated and should no longer be used.  See the <Array>.includesAny() method for its replacement.

#### History:

* `v2.0.0`: Introduced.
* `v2.10.0`: Deprecated in favor of `<Array>.includesAny()`.

### `<Array>.flatten()` → *Array<any>* {#methods-array-prototype-method-flatten}

Deprecated:
This method has been deprecated and should no longer be used.  See the <Array>.flat() method for its replacement.  The exactly equivalent call is: <Array>.flat(Infinity).

Returns a new array consisting of the flattened source array.  Does not modify the original.

#### History:

* `v2.0.0`: Introduced.
* `v2.29.0`: Deprecated in favor of `<Array>.flat()`.

### `Array.random(array)` → *any* {#methods-array-method-random}

Deprecated:
This method has been deprecated and should no longer be used.  In general, look to the <Array>.random() method instead.  If you need a random member from an array-like object, use the Array.from() method to convert it to an array, then use <Array>.random().

Returns a random member from the array or array-like object.  Does not modify the original.

#### History:

* `v2.0.0`: Introduced.
* `v2.20.0`: Deprecated.

## JSON Methods {#methods-json}

### `JSON.reviveWrapper(codeString [, reviveData])` → *array* {#methods-json-method-revivewrapper}

Returns the given code string, and optional data chunk, wrapped within the JSON deserialization revive wrapper.  Intended to allow authors to easily wrap their custom object types (a.k.a. classes) revival code and associated data within the revive wrapper, which should be returned from an object instance's `.toJSON()` method, so that the instance may be properly revived upon deserialization.

See:
The Non-generic object types (a.k.a. classes) guide for more detailed information.

#### History:

* `v2.0.0`: Introduced.
* `v2.9.0`: Added `reviveData` parameter.

#### Parameters:

* **`codeString`:** (*string*) The revival code string to wrap.
* **`reviveData`:** (optional, *any*) The data that should be made available to the evaluated revival code during deserialization via the special `$ReviveData$` variable.  **WARNING:** Attempting to pass the value of an object instance's `this` directly as the `reviveData` parameter will trigger out of control recursion in the serializer, so a clone of the instance's own data must be passed instead.

#### Examples:

```
JSON.reviveWrapper( /* valid JavaScript code string */ );             → Without data chunk
JSON.reviveWrapper( /* valid JavaScript code string */ , myOwnData);  → With data chunk

// E.g., Assume that you're attempting to revive an instance of a custom class named
//       `Character`, which is assigned to a story variable named `$pc`.  The call
//       to `JSON.reviveWrapper()` might look something like the following.
var ownData = {};
Object.keys(this).forEach(function (pn) { ownData[pn] = clone(this[pn]); }, this);
return JSON.reviveWrapper('new Character($ReviveData$)', ownData);
```

## jQuery Methods {#methods-jquery}

### `<jQuery>.ariaClick([options ,] handler)` → *`jQuery` object* {#methods-jquery-prototype-method-ariaclick}

Makes the target element(s) WAI-ARIA-compatible clickables—meaning that various accessibility attributes are set and, in addition to mouse clicks, enter/return and spacebar key presses also activate them.  Returns a reference to the current `jQuery` object for chaining.

#### History:

* `v2.0.0`: Introduced.

#### Parameters:

* **`options`:** (optional, *object*) The options to be used when creating the clickables.
* **`handler`:** (*function*) The callback to invoke when the target element(s) are activated.

#### Options object:

An options object should have some of the following properties:

* **`namespace`:** (*string*) A period-separated list of event namespaces.
* **`one`:** (*boolean*) Whether the clickables are single-use—i.e., the handler callback runs only once and then removes itself.  If omitted, defaults to `false`.
* **`selector`:** (*string*) A selector applied to the target element(s) to filter the descendants that triggered the event. If omitted or `null`, the event is always handled when it reaches the target element(s).
* **`data`:** (*any*) Data to be passed to the handler in [`event.data`](http://api.jquery.com/event.data/) when an event is triggered.
* **`controls`:** (*string*) Value for the `aria-controls` attribute.
* **`pressed`:** (*string*) Value for the `aria-pressed` attribute (valid values: `"true"`, `"false"`).
* **`label`:** (*string*) Value for the `aria-label` and `title` attributes.

#### Examples:

```
// Given an existing element: <a id="so-clicky">Click me</a>
$('#so-clicky').ariaClick(function (event) {
	/* do stuff */
});

// Creates a basic link and appends it to the `output` element
$('<a>Click me</a>')
	.ariaClick(function (event) {
		/* do stuff */
	})
	.appendTo(output);

// Creates a basic button and appends it to the `output` element
$('<button>Click me</button>')
	.ariaClick(function (event) {
		/* do stuff */
	})
	.appendTo(output);

// Creates a link with options and appends it to the `output` element
$('<a>Click me</a>')
	.ariaClick({
		one   : true,
		label : 'This single-use link does stuff.'
	}, function (event) {
		/* do stuff */
	})
	.appendTo(output);
```

### `<jQuery>.ariaDisabled(state)` → *`jQuery` object* {#methods-jquery-prototype-method-ariadisabled}

Changes the disabled state of the target WAI-ARIA-compatible clickable element(s).  Returns a reference to the current `jQuery` object for chaining.

Note:
This method is meant to work with clickables created via <jQuery>.ariaClick() and may not work with clickables from other sources.  SugarCube uses <jQuery>.ariaClick() internally to handle all of its various link markup and macros.

#### History:

* `v2.26.0`: Introduced.

#### Parameters:

* **`state`:** (*boolean*) The disabled state to apply.  Truthy to disable the element(s), falsy to enable them.

#### Examples:

```
// Given an existing WAI-ARIA-compatible clickable element with the ID "so-clicky"
$('#so-clicky').ariaDisabled(true)   → Disables the target element
$('#so-clicky').ariaDisabled(false)  → Enables the target element
````

### `<jQuery>.ariaIsDisabled()` → *`boolean`* {#methods-jquery-prototype-method-ariaisdisabled}
Returns whether any of the target WAI-ARIA-compatible clickable element(s) are disabled.

Note:
This method is meant to work with clickables created via <jQuery>.ariaClick() and may not work with clickables from other sources.  SugarCube uses <jQuery>.ariaClick() internally to handle all of its various link markup and macros.

#### History:

* `v2.26.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Given an existing WAI-ARIA-compatible clickable element with the ID "so-clicky"

// If "#so-clicky" is disabled:
$('#so-clicky').ariaIsDisabled()  → Returns true

// If "#so-clicky" is enabled:
$('#so-clicky').ariaIsDisabled()  → Returns false
```

### `jQuery.wiki(sources…)` {#methods-jquery-method-wiki}

Wikifies the given content source(s) and discards the result.  If there were errors, an exception is thrown.  This is only really useful when you want to invoke a macro for its side-effects and aren't interested in its output.

#### History:

* `v2.17.0`: Introduced.

#### Parameters:

* **`sources`:** (*string*…) The list of content sources.

#### Examples:

```
$.wiki('<<somemacro>>');  → Invokes the <<somemacro>> macro, discarding any output
```

### `<jQuery>.wiki(sources…)` → *`jQuery` object* {#methods-jquery-prototype-method-wiki}

Wikifies the given content source(s) and appends the result to the target element(s).  Returns a reference to the current `jQuery` object for chaining.

#### History:

* `v2.0.0`: Introduced.

#### Parameters:

* **`sources`:** (*string*…) The list of content sources.

#### Examples:

```
// Given an element: <div id="the-box"></div>
$('#the-box').wiki('Who //are// you?');  → Appends "Who <em>are</em> you?" to the target element
```

## Math Methods {#methods-math}

### `Math.clamp(num , min , max)` → *number* {#methods-math-method-clamp}

Returns the given number clamped to the specified bounds.  Does not modify the original.

#### History:

* `v2.0.0`: Introduced.

#### Parameters:

* **`num`:** (*number*) The number to clamp.  May be an actual number or a numerical string.
* **`min`:** (*number*) The lower bound of the number.
* **`max`:** (*number*) The upper bound of the number.

#### Examples:

```
Math.clamp($stat, 0, 200)  → Clamps $stat to the bounds 0–200 and returns the new value
Math.clamp($stat, 1, 6.6)  → Clamps $stat to the bounds 1–6.6 and returns the new value
```

### `Math.trunc(num)` → *integer* {#methods-math-method-trunc}

Returns the whole (integer) part of the given number by removing its fractional part, if any.  Does not modify the original.

#### History: *native JavaScript method*

#### Parameters:

* **`num`:** (*number*) The number to truncate to an integer.

#### Examples:

```
Math.trunc(12.7)   → Returns 12
Math.trunc(-12.7)  → Returns -12
```

## Number Methods {#methods-number}

### `<Number>.clamp(min , max)` → *number* {#methods-number-prototype-method-clamp}

Returns the number clamped to the specified bounds.  Does not modify the original.

#### History:

* `v2.0.0`: Introduced.

#### Parameters:

* **`min`:** (*number*) The lower bound of the number.
* **`max`:** (*number*) The upper bound of the number.

#### Examples:

```
$stat.clamp(0, 200)  → Clamps $stat to the bounds 0–200 and returns the new value
$stat.clamp(1, 6.6)  → Clamps $stat to the bounds 1–6.6 and returns the new value
```

## RegExp Methods {#methods-regexp}

### `RegExp.escape(text)` → *string* {#methods-regexp-method-escape}

Returns the given string with all regular expression metacharacters escaped.  Does not modify the original.

#### History:

* `v2.0.0`: Introduced.

#### Parameters:

* **`text`:** (*string*) The string to escape.

#### Examples:

```
RegExp.escape('That will be $5 (cash only)')   → Returns 'That will be \$5 \(cash only\)'
```

## String Methods {#methods-string}

Note:
Strings in TwineScript/JavaScript are Unicode, however, due to historic reasons they are comprised of, and indexed by, individual UTF-16 code units rather than code points.  This means that some code points may span multiple code units—e.g., the emoji 💩 is one code point, but two code units.

### `<String>.count(needle [, position])` → *integer* {#methods-string-prototype-method-count}

Returns the number of times that the given substring was found within the string, starting the search at `position`.

#### History:

* `v2.0.0`: Introduced.

#### Parameters:

* **`needle`:** (*any*) The substring to count.
* **`position`:** (optional, *integer*) The zero-based index at which to begin searching for `needle`.  If omitted, will default to `0`.

#### Examples:

```
// Given: $text = "How now, brown cow."
$text.count("ow")     → Returns 4
$text.count("ow", 8)  → Returns 2
```

### `<String>.first()` → *string* {#methods-string-prototype-method-first}

Returns the first Unicode code point within the string.  Does not modify the original.

See:
String methods note.

#### History:

* `v2.27.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Given: $text = "abc"
$text.first()  → Returns "a"

// Given: $text = "🙈🙉🙊"
$text.first()  → Returns "🙈"
```

### `String.format(format , arguments…)` → *string* {#methods-string-method-format}

Returns a formatted string, after replacing each format item in the given format string with the text equivalent of the corresponding argument's value.

#### History:

* `v2.0.0`: Introduced.

#### Parameters:

* **`format`:** (*string*) The format string, which consists of normal text and format items.
* **`arguments`:** (*any*… | *Array<any>*) Either a list of arguments, which correspond by-index to the format items within the format string, or an array, whose members correspond by-index.

#### Format items:

A format item has the syntax `{index[,alignment]}`, square-brackets denoting optional elements.

* **`index`:** (*integer*) The (zero-based) index of the argument whose string representation will replace the format item.
* **`alignment`:** (optional, *integer*) The total length of the field into which the argument is inserted, and whether it's right- or left-aligned (positive aligns right, negative aligns left).

#### Examples:

```
String.format("{0}, {1}!", "Hello", "World")      → List of arguments; Returns "Hello, World!"
String.format("{0}, {1}!", [ "Hello", "World" ])  → Array argument; Returns "Hello, World!"
String.format("{0,6}", "foo")                     → Returns "   foo"
String.format("{0,-6}", "foo")                    → Returns "foo   "
```

### `<String>.includes(needle [, position])` → *boolean* {#methods-string-prototype-method-includes}

Returns whether the given substring was found within the string, starting the search at `position`.

#### History: *native JavaScript method*

#### Parameters:

* **`needle`:** (*any*) The substring to find.
* **`position`:** (optional, *integer*) The zero-based index at which to begin searching for `needle`.  If omitted, will default to `0`.

#### Examples:

```
// Given: $text = "How now, brown cow."
$text.includes("row")      → Returns true
$text.includes("row", 14)  → Returns false
$text.includes("cow", 14)  → Returns true
$text.includes("pow")      → Returns false
```

### `<String>.last()` → *string* {#methods-string-prototype-method-last}

Returns the last Unicode code point within the string.  Does not modify the original.

See:
String methods note.

#### History:

* `v2.27.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Given: $text = "abc"
$text.last()  → Returns "c"

// Given: $text = "🙈🙉🙊"
$text.last()  → Returns "🙊"
```

### `<String>.toLocaleUpperFirst()` → *string* {#methods-string-prototype-method-tolocaleupperfirst}

Returns the string with its first Unicode code point converted to upper case, according to any locale-specific rules.  Does not modify the original.

See:
String methods note.

#### History:

* `v2.9.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Using the Turkish (Türkçe) locale and given: $text = "ışık"
$text.toLocaleUpperFirst()  → Returns "Işık"

// Using the Turkish (Türkçe) locale and given: $text = "iki"
$text.toLocaleUpperFirst()  → Returns "İki"
```

### `<String>.toUpperFirst()` → *string* {#methods-string-prototype-method-toupperfirst}

Returns the string with its first Unicode code point converted to upper case.  Does not modify the original.

See:
String methods note.

#### History:

* `v2.9.0`: Introduced.

#### Parameters: *none*

#### Examples:

```
// Given: $text = "hello."
$text.toUpperFirst()  → Returns "Hello."

// Given: $text = "χαίρετε."
$text.toUpperFirst()  → Returns "Χαίρετε."
```


code:
# Special Names {#special-names}

Passage, tag, and variable names that have special meaning to SugarCube.

#### Warning {#special-names-warning}

1. All special names listed herein are case sensitive, so their spelling and capitalization must be ***exactly*** as shown.
2. ***Never*** combine special passages with special tags.  By doing so, you will probably break things in subtle and hard to detect ways.

## Passage Names {#special-passages}

### `PassageDone` {#special-passage-passagedone}

Used for post-passage-display tasks, like redoing dynamic changes (happens after the rendering and display of each passage).  Generates no output.

Roughly equivalent to the [`:passagedisplay` event](#events-navigation-event-passagedisplay).

#### History:

* `v2.0.0`: Introduced.

### `PassageFooter` {#special-passage-passagefooter}

Appended to each rendered passage.

Roughly equivalent to the [`:passagerender` event](#events-navigation-event-passagerender).

#### History:

* `v2.0.0`: Introduced.

### `PassageHeader` {#special-passage-passageheader}

Prepended to each rendered passage.

Roughly equivalent to the [`:passagestart` event](#events-navigation-event-passagestart).

#### History:

* `v2.0.0`: Introduced.

### `PassageReady` {#special-passage-passageready}

Used for pre-passage-display tasks, like redoing dynamic changes (happens before the rendering of each passage).  Generates no output.

Roughly equivalent to the [`:passagestart` event](#events-navigation-event-passagestart).

#### History:

* `v2.0.0`: Introduced.

### `Start` {#special-passage-start}

**Twine 2:**  *Not special.*  Any passage may be chosen as the starting passage by selecting it via the *Start Story Here* passage context-menu item—n.b. older versions of Twine 2 used a  icon for the same purpose.

**Twine 1/Twee:**  *Required.*  The starting passage, the first passage displayed.  Configurable, see [`Config.passages.start`](#config-api-property-passages-start) for more information.

#### History:

* `v2.0.0`: Introduced.

### `StoryAuthor` {#special-passage-storyauthor}

Used to populate the authorial byline area in the UI bar (element ID: `story-author`).

#### History:

* `v2.0.0`: Introduced.

### `StoryBanner` {#special-passage-storybanner}

Used to populate the story's banner area in the UI bar (element ID: `story-banner`).

#### History:

* `v2.0.0`: Introduced.

### `StoryCaption` {#special-passage-storycaption}

Used to populate the story's caption area in the UI bar (element ID: `story-caption`).  May also be, and often is, used to add additional story UI elements and content to the UI bar.

#### History:

* `v2.0.0`: Introduced.

### `StoryDisplayTitle` {#special-passage-storydisplaytitle}

Sets the story's display title in the browser's titlebar and the UI bar (element ID: `story-title`).  If omitted, the story title will be used instead.

#### History:

* `v2.31.0`: Introduced.

### `StoryInit` {#special-passage-storyinit}

Used for pre-story-start initialization tasks, like variable initialization (happens at the beginning of story initialization).  Generates no output.

#### History:

* `v2.0.0`: Introduced.

### `StoryInterface` {#special-passage-storyinterface}

Used to replace SugarCube's default UI.  Its contents are treated as raw HTML markup—i.e., *none* of SugarCube's special HTML processing is performed.  It must contain, at least, an element with the ID `passages` that will be the main passage display area.

Additional elements, aside from the `#passages` element, may include either the `data-init-passage` or `data-passage` content attribute, whose value is the name of the passage used to populate the element—the passage will be processed as normal, meaning that markup and macros will work as expected.  The `data-init-passage` attribute causes the element to be updated once at initialization, while the `data-passage` attribute causes the element to be updated upon each passage navigation.

Warning:
Elements that include either a data-init-passage or data-passage content attribute should not themselves contain additional elements—since such elements' contents are replaced each turn via their associated passage, any child elements would be lost.

#### History:

* `v2.18.0`: Introduced.
* `v2.28.0`: Added processing of the `data-passage` content attribute.
* `v2.36.0`: Added processing of the `data-init-passage` content attribute.

#### Examples:

##### Minimal working example

```
<div id="passages"></div>
```

##### With `data-init-passage` and `data-passage` content attributes

```
<div id="interface">
	<div id="menu" data-init-passage="Menu"></div>
	<div id="notifications" data-passage="Notifications"></div>
	<div id="passages"></div>
</div>
```

### `StoryMenu` {#special-passage-storymenu}

Used to populate the story's menu items in the UI bar (element ID: `menu-story`).

Note:
The story menu only displays links—specifically, anything that creates an anchor element (<a>).  While it renders content just as any other passage does, instead of displaying the rendered output as-is, it sifts through the output and builds its menu from the generated links contained therein.

#### History:

* `v2.0.0`: Introduced.

#### Examples:

```
[[Inventory]]
<<link "Schedule">>…<</link>>
```

### `StorySettings` {#special-passage-storysettings}

Warning:
Unused by SugarCube.  The Config API serves the same basic purpose.

### `StoryShare` {#special-passage-storyshare}

Used to populate the contents of the Share dialog.  Intended for social media links.

Note:
The Share dialog only displays links—specifically, anything that creates an anchor element (<a>).  While it renders content just as any other passage does, instead of displaying the rendered output as-is, it sifts through the output and builds its contents from the generated links contained therein.

#### History:

* `v2.0.0`: Introduced.

### `StorySubtitle` {#special-passage-storysubtitle}

Sets the story's subtitle in the UI bar (element ID: `story-subtitle`).

#### History:

* `v2.0.0`: Introduced.

### `StoryTitle` {#special-passage-storytitle}

Warning:
The story title is used to create the storage ID that is used to store all player data, both temporary and persistent.  It should be plain text, containing no code, markup, or macros of any kind.

Tip:
If you want to set a title for display that contains code, markup, or macros, see the StoryDisplayTitle special passage.

**Twine 2:**  *Unused.*  The story's title is part of the story project.

**Twine 1/Twee:**  *Required.*  Sets the story's title.

#### History:

* `v2.0.0`: Introduced.

## Tag Names {#special-tags}

### `bookmark` {#special-tag-bookmark}

Registers the passage into the *Jump To* menu.

#### History:

* `v2.0.0`: Introduced.

### `nobr` {#special-tag-nobr}

Causes leading/trailing newlines to be removed and all remaining sequences of newlines to be replaced with single spaces before the passage is rendered.  Equivalent to wrapping the entire passage in a [`<<nobr>>` macro](#macros-macro-nobr).  See the [`Config.passages.nobr` setting](#config-api-property-passages-nobr) for a way to apply the same processing to all passages at once.

Note:
Does not affect script or stylesheet tagged passages, for Twine 1/Twee.

#### History:

* `v2.0.0`: Introduced.

### `init` {#special-tag-init}

Registers the passage as an initialization passage.  Used for pre-story-start initialization tasks, like variable initialization (happens at the beginning of story initialization).  Generates no output.

Note:
This is chiefly intended for use by add-ons/libraries.  For normal projects, authors are encouraged to continue to use the StoryInit special named passage.

#### History:

* `v2.36.0`: Introduced.

### `script` {#special-tag-script}

**Twine 2:**  *Not special.*  Use the *Edit Story JavaScript* story editor menu item for scripts.

**Twine 1/Twee:**  Registers the passage as JavaScript code, which is executed during startup.

#### History:

* `v2.0.0`: Introduced.

### `stylesheet` {#special-tag-stylesheet}

**Twine 2:**  *Not special.*  Use the *Edit Story Stylesheet* story editor menu item for styles.

**Twine 1/Twee:**  Registers the passage as a CSS stylesheet, which is loaded during startup.  It is ***strongly*** recommended that you use only one stylesheet passage.  Additionally, see the [tagged stylesheet warning](#css-warnings).

#### History:

* `v2.0.0`: Introduced.

### `Twine.audio` {#special-tag-twine-audio}

Registers the passage as an audio passage.  See [Guide: Media Passages](#guide-media-passages) for more information.

#### History:

* `v2.24.0`: Introduced.

### `Twine.image` {#special-tag-twine-image}

Registers the passage as an image passage.  See [Guide: Media Passages](#guide-media-passages) for more information.

#### History:

* `v2.0.0`: Introduced.

### `Twine.video` {#special-tag-twine-video}

Registers the passage as a video passage.  See [Guide: Media Passages](#guide-media-passages) for more information.

#### History:

* `v2.24.0`: Introduced.

### `Twine.vtt` {#special-tag-twine-vtt}

Registers the passage as a VTT passage.  See [Guide: Media Passages](#guide-media-passages) for more information.

#### History:

* `v2.24.0`: Introduced.

### `widget` {#special-tag-widget}

Registers the passage as [`<<widget>>` macro](#macros-macro-widget) definitions, which are loaded during startup.

#### History:

* `v2.0.0`: Introduced.

## Variable Names {#special-variables}

### `$` {#special-variable-dollar}

Alias for `jQuery`, by default.  **NOTE:** This should not be confused with [story variables](#twinescript-variables), which start with a `$`—e.g., `$foo`.

#### History:

* `v2.0.0`: Introduced.

### `_args` {#special-variable-underscore-args}

Widget arguments array (only inside widgets).  See [`<<widget>>`](#macros-macro-widget) for more information.

#### History:

* `v2.36.0`: Introduced.

### `_contents` {#special-variable-underscore-contents}

Widget contents string (only inside block widgets).  See [`<<widget>>`](#macros-macro-widget) for more information.

#### History:

* `v2.36.0`: Introduced.

### `Config` {#special-variable-config}

Configuration API.  See [`Config` API](#config-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `Dialog` {#special-variable-dialog}

Dialog API.  See [`Dialog` API](#dialog-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `Engine` {#special-variable-engine}

Engine API.  See [`Engine` API](#engine-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `Fullscreen` {#special-variable-fullscreen}

Fullscreen API.  See [`Fullscreen` API](#fullscreen-api) for more information.

#### History:

* `v2.31.0`: Introduced.

### `jQuery` {#special-variable-jquery}

jQuery library function.

#### History:

* `v2.0.0`: Introduced.

### `l10nStrings` {#special-variable-l10nstrings}

Strings localization object.  See [Localization](#guide-localization) for more information.

#### History:

* `v2.10.0`: Introduced.

### `LoadScreen` {#special-variable-loadscreen}

LoadScreen API.  See [`LoadScreen` API](#loadscreen-api) for more information.

#### History:

* `v2.15.0`: Introduced.

### `Macro` {#special-variable-macro}

Macro API.  See [`Macro` API](#macro-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `Passage` {#special-variable-passage}

Passage API.  See [`Passage` API](#passage-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `Save` {#special-variable-save}

Save API.  See [`Save` API](#save-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `Setting` {#special-variable-setting}

Setting API.  See [`Setting` API](#setting-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `settings` {#special-variable-settings}

Player settings object, set up by the author/developer.  See [`Setting` API](#setting-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `setup` {#special-variable-setup}

Object that authors/developers may use to set up various bits of static data.  Generally, you would use this for data that does not change and should not be stored within story variables, which would make it part of the history.

#### History:

* `v2.0.0`: Introduced.

### `SimpleAudio` {#special-variable-simpleaudio}

SimpleAudio API.  See [`SimpleAudio` API](#simpleaudio-api) for more information.

#### History:

* `v2.28.0`: Introduced.

### `State` {#special-variable-state}

State API.  See [`State` API](#state-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `Story` {#special-variable-story}

Story API.  See [`Story` API](#story-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `Template` {#special-variable-template}

Template API.  See [`Template` API](#template-api) for more information.

#### History:

* `v2.29.0`: Introduced.

### `UI` {#special-variable-ui}

UI API.  See [`UI` API](#ui-api) for more information.

#### History:

* `v2.0.0`: Introduced.

### `UIBar` {#special-variable-uibar}

UIBar API.  See [`UIBar` API](#uibar-api) for more information.

#### History:

* `v2.17.0`: Introduced.

### `$args` {#special-variable-dollar-args}

Deprecated:
The $args special variable has been deprecated and should no longer be used.  See the _args special variable for its replacement.

#### History:

* `v2.0.0`: Introduced.
* `v2.36.0`: Deprecated.

### `postdisplay` {#special-variable-postdisplay}

Deprecated:
postdisplay tasks have been deprecated and should no longer be used.  See the :passagedisplay event for its replacement.

#### History:

* `v2.0.0`: Introduced.
* `v2.31.0`: Deprecated.

### `postrender` {#special-variable-postrender}

Deprecated:
postrender tasks have been deprecated and should no longer be used.  See the :passagerender event for its replacement.

#### History:

* `v2.0.0`: Introduced.
* `v2.31.0`: Deprecated.

### `predisplay` {#special-variable-predisplay}

Deprecated:
predisplay tasks have been deprecated and should no longer be used.  See the :passagestart event for its replacement.

#### History:

* `v2.0.0`: Introduced.
* `v2.31.0`: Deprecated.

### `prehistory` {#special-variable-prehistory}

Deprecated:
prehistory tasks have been deprecated and should no longer be used.  See the :passageinit event for its replacement.

#### History:

* `v2.0.0`: Introduced.
* `v2.31.0`: Deprecated.

### `prerender` {#special-variable-prerender}

Deprecated:
prerender tasks have been deprecated and should no longer be used.  See the :passagestart event for its replacement.

#### History:

* `v2.0.0`: Introduced.
* `v2.31.0`: Deprecated.


code:
# TwineScript {#twinescript}

TwineScript in SugarCube is, essentially, JavaScript with an extra spoonful of sugar on top to make it a bit nicer for the uninitiated.

## Variables {#twinescript-variables}

Note:
Temporary variables were added in v2.3.0.

A variable is a bit of storage where you may stash a value for later use.  In SugarCube, they come in two types: story variables and temporary variables.  Story variables are a part of the story history and exist for the lifetime of a playthrough session.  Temporary variables do not become part of the story history and only exist for the lifetime of the moment/turn that they're created in.  You'll likely use story variables most often throughout your project—though, temporary variables are perfect candidates for things like loop variables, if you're using the [`<<for>>`](#macros-macro-for) macro.

For example, you might use the story variable `$name` to store the main player character's name or the story variable `$cash` to store how much money the player has on hand.

Values may be of most primitive types and some object types, see [Supported Types](#twinescript-supported-types) for more information.

### Variable Names

The names of both story and temporary variables have a certain format that they must follow—which signifies that they are variables and not some other kind of data.

The very first, and mandatory, character is their sigil, which denotes whether they are a story or temporary variable.  The sigil must be a dollar sign (`$`) for story variables or an underscore (`_`) for temporary variables.

The second, and also mandatory, character of the variable name may be one of the following: the letters A though Z (in upper or lower case), the dollar sign, and the underscore (i.e., `A-Za-z$_`)—after their initial use as the sigil, the dollar sign and underscore become regular variable characters.

Subsequent, optional, characters have the same set as the second with the addition of numerals (i.e., `0-9`, so the full set is `A-Za-z0-9$_`).  No other characters are allowed.

A few examples of valid names:

```
/* Story variables */
$cash
$hasKeyCard5
$met_alice
$TIMES_POKED_MR_BEAR

/* Temporary variables */
_i
_something2
_some_loop_value
_COUNT
```

### Using Variables

Note:
This is not an exhaustive list.  There are many ways to use and interact with variables.

To modify the values contained within variables, see the [`<<set>>`](#macros-macro-set) macro and [setter links](#markup-link).

To print the values contained within variables, see the [naked variable markup](#markup-naked-variable) and the [`<<print>>`](#macros-macro-print), [`<<=>>`](#macros-macro-equal), and [`<<->>`](#macros-macro-hyphen) macros.

To control aspects of your project based on the values contained within variables, see the [`<<if>>`](#macros-macro-if) and [`<<switch>>`](#macros-macro-switch) macros.

## Supported Types {#twinescript-supported-types}

The following types of values are natively supported by SugarCube and may be safely used within story and temporary variables.

### Primitives

* Booleans—e.g., `true` & `false`
* Numbers—e.g., `42`, `3.14`,  & `-17.01`
* Strings—e.g., `"I like pie"` & `'You like pie'`
* `null`
* `undefined`

### Objects

* `Array`
* `Date`
* `Map`
* `Set`
* Generic objects

Any supported object type may itself contain any supported primitive or object type.

Unsupported object types, either native or custom, can be made compatible by implementing `.clone()` and `.toJSON()` methods for them—see the [*Non-generic object types (a.k.a. classes)* guide](#guide-tips-non-generic-object-types) for more information.

Warning:

Due to how SugarCube stores the state history a few constructs are not supported within story variables.

Circular references.  If you need them, then you'll need to keep them out of story variables.

Property attributes, including getters/setters, and symbol properties.  If you need them, then you'll need to use a class or similar non-generic object.

Functions, including static—i.e., non-instance—methods, due to a few issues.

A function's scope cannot be restored.  Thus, if your function depends upon its scope, then it will not work properly when revived from sessions or saves.

Function behavior is immutable.  Thus, storing them within story variables is generally wasteful.

Instance methods of classes are not affected by either issue, as they're never actually stored within story variables, being referenced from their classes' prototypes instead.

## Expressions {#twinescript-expressions}

See Also:
While not specifically about SugarCube, the About Expressions section of the Twine 1 reference documentation may also be helpful.

Expressions are simply units of code that yield values when evaluated.  For example:

```
2 + 2       → Yields: 4
"a" + "bc"  → Yields: "abc"
turns()     → Yields: 1 (assuming that it is the first turn)
```

While every valid expression—even those you might not expect—yields a value, there are essentially two types of expressions: those with side effects and those without.  A side effect simply means that the evaluation of the expression modifies some state.  For example:

```
$a = 5   → Yields: 5; Side effect: assigns 5 to the story variable $a
$x + 10  → Yields: 25 (assuming $x is 15); No side effects
```

In general, you can group expressions into categories based on what kind of value they yield and/or what side effects they cause.  For example: *(not an exhaustive list)*

* Arithmetic: The expression yields a number value—e.g., `42` or `3.14`.
* String: The expression yields a string value—e.g., `"Lulamoon"` or `"5678"`.
* Logical: The expression yields a boolean value—e.g., `true` or `false`.
* Assignment: The expression causes an assignment to occur—e.g., `$a = 5`.

### Using Expressions

You will, in all likelihood, use expressions most often within macros—e.g., [`<<set>>`](#macros-macro-set), [`<<print>>`](#macros-macro-print), [`<<if>>`](#macros-macro-if), [`<<for>>`](#macros-macro-for).


code:
# Guide: Code Updates {#guide-code-updates}

This is a reference on how to update existing SugarCube code to work with newer versions of SugarCube.

Note:
The majority of newer SugarCube versions do not have any changes that would require an update.  For those versions that do, the updates are normally completely elective and may be addressed at your leisure, or not at all.  Sometimes there are breaking changes, however, and these must be addressed immediately.

## Updating to any version ≥2.30.0 from a lesser version {#guide-code-updates-2.30.0}

All changes within this version are elective changes that you may address at your leisure.

### `Config` API

			Property
			Changes

			Config.saves.autosave
			This setting property has been updated to accept function values and its acceptance of string values has been deprecated.  String values will still be accepted for further releases of v2, however, switching to an array is recommended—e.g., the string value "autosave" would become the array ["autosave"].  See the Config.saves.autosave property for more information.

## Updating to any version ≥2.29.0 from a lesser version {#guide-code-updates-2.29.0}

All changes within this version are elective changes that you may address at your leisure.

### `Dialog` API

			Method
			Changes

			Dialog.addClickHandler()
			This method has been deprecated and should no longer be used.  The core of what it does is simply to wrap a call to Dialog.open() within a call to <jQuery>.ariaClick(), which can be done directly and with greater flexibility.

### Macro library

			Macro
			Changes

			<<track>> (of: <<createplaylist>>)
			The <<createplaylist>> macro's <<track>> child macro has had its copy keyword deprecated in favor of own.  See the <<createplaylist>> macro for more information.

			<<forget>>
			The <<forget>> macro has been deprecated in favor of the forget() function.

			<<remember>>
			The <<remember>> macro has been deprecated in favor of the memorize() and recall() functions.

### Method library

			Method
			Changes

			<Array>.flatten()
			This method has been deprecated in favor of the <Array>.flat() method.

### `State` API

			Method
			Changes

			State.initPRNG()
			This method has been deprecated in favor of the State.prng.init() method.

## Updating to any version ≥2.28.0 from a lesser version {#guide-code-updates-2.28.0}

All changes within this version are elective changes that you may address at your leisure.

### Macro library

			Macro
			Changes

			<<cacheaudio>>
			The <<cacheaudio>> macro's original optional format specifier syntax, format:formatId;…, has been deprecated in favor of the new syntax, formatId|…..

## Updating to any version ≥2.20.0 from a lesser version {#guide-code-updates-2.20.0}

All changes within this version are elective changes that you may address at your leisure.

### Method library

			Method
			Changes

			Array.random()
			This method has been deprecated and should no longer be used.  In general, look to the <Array>.random() method instead.  If you need a random member from an array-like object or iterable, use the Array.from() method to convert it to an array, then use <Array>.random()—e.g., Array.from(something).random().

## Updating to any version ≥2.15.0 from a lesser version {#guide-code-updates-2.15.0}

All changes within this version are elective changes that you may address at your leisure.

### Macro library

			Macro
			Changes

			<<display>>
			The <<display>> macro has been deprecated in favor of the <<include>> macro.

## Updating to any version ≥2.10.0 from a lesser version {#guide-code-updates-2.10.0}

All changes within this version are elective changes that you may address at your leisure.

### Method library

			Method
			Changes

			<Array>.contains()
			The <Array>.contains() method has been deprecated in favor of the <Array>.includes() method.

			<Array>.containsAll()
			The <Array>.containsAll() method has been deprecated in favor of the <Array>.includesAll() method.

			<Array>.containsAny()
			The <Array>.containsAny() method has been deprecated in favor of the <Array>.includesAny() method.

### `strings` object

The `strings` API object has been replaced by the `l10nStrings` object.  See the [Localization guide](#guide-localization) for more information.

## Updating to any version ≥2.8.0 from a lesser version {#guide-code-updates-2.8.0}

All changes within this version are elective changes that you may address at your leisure.

### Macro library

			Macro
			Changes

			<<click>>
			The <<click>> macro has been deprecated in favor of the <<link>> macro.

			<<playlist>>
			The <<playlist>> macro has had its argument list changed, for compatibility with <<createplaylist>>.  See the <<playlist>> macro for more information.

			<<setplaylist>>
			The <<setplaylist>> macro has been deprecated in favor of the <<createplaylist>> macro.

			<<stopallaudio>>
			The <<stopallaudio>> macro has been deprecated in favor of <<audio ":all" stop>>.  See the <<audio>> macro for more information.

## Updating to any version ≥2.5.0 from a lesser version {#guide-code-updates-2.5.0}

All changes within this version are elective changes that you may address at your leisure.

### `config` API

The `config` API has been renamed `Config` for better consistency with the other APIs.

### `State` API

Several `State` API methods have moved to the new `Engine` API.  See the [`Engine` API](#engine-api) docs for more information.

			Old State method
			New Engine method

			State.backward()
			Engine.backward()

			State.display()
			Engine.display()1

			State.forward()
			Engine.forward()

			State.play()
			Engine.play()

			State.restart()
			Engine.restart()

			State.show()
			Engine.show()

While the Engine.display() static methods exists, it, like State.display() before it, is deprecated.  See the Engine.play() static method for the replacement.  NOTE: Their parameters differ, so read the description of Engine.play() carefully.

### `UI` API

Several `UI` API methods have moved to the new `Dialog` API.  See the [`Dialog` API](#dialog-api) docs for more information.

			Old UI method
			New Dialog method

			UI.addClickHandler()
			Dialog.addClickHandler()

			UI.body()
			Dialog.body()

			UI.close()
			Dialog.close()

			UI.isOpen()
			Dialog.isOpen()

			UI.open()
			Dialog.open()

			UI.setup()
			Dialog.setup()

## Updating to any version ≥2.0.0 from a lesser version {#guide-code-updates-2.0.0}

Warning:
All changes within this version are breaking changes that you must address immediately.

### HTML & CSS

The HTML & CSS have undergone ***significant*** changes.  See the [`HTML`](#html) and [`CSS`](#css) docs for more information.

### Special passages

			Passage
			Changes

			MenuOptions
			The MenuOptions special passage has been removed.  See the Options system section for more information.

			MenuShare
			The MenuShare special passage has been removed.  Instead, use the StoryShare special passage.

			MenuStory
			The MenuStory special passage has been removed.  Instead, use the StoryMenu special passage.

### `config` object

The `config` object has been renamed to `Config` and some of its properties have also changed.  See the [`Config` API](#config-api) docs for more information.

			Property
			Changes

			config.altPassageDescription
			Changed the config.altPassageDescription property to Config.passages.descriptions.

			config.disableHistoryControls
			Changed the config.disableHistoryControls property to Config.history.controls.  This change also inverted the meaning of the property, so take note of that.

			config.disableHistoryTracking
			Replaced the config.disableHistoryTracking property with Config.history.maxStates.  The new property works differently, so take note of that.

			config.displayPassageTitles
			Changed the config.displayPassageTitles property to Config.passages.displayTitles.

			config.historyMode
			Removed the config.historyMode property.  It's unnecessary since there's now only one history mode in the engine.

			config.macros.disableIfAssignmentError
			Changed the config.macros.disableIfAssignmentError property to Config.macros.ifAssignmentError.  This change also inverted the meaning of the property, so take note of that.

			config.passageTransitionOut
			Changed the config.passageTransitionOut property to Config.passages.transitionOut.  Additionally, it no longer accepts a boolean value, which has been replaced by the name of the animating property (necessitated by changes to browser handling of transition animations).

			config.startPassage
			Changed the config.startPassage property to Config.passages.start.

			config.updatePageElements
			Changed the config.updatePageElements property to Config.ui.updateStoryElements.

### History object & prototype (instance: `state`)

The `History` API object has been renamed to `State` and some of its methods have also changed.  Furthermore, it is no longer instantiated into the legacy `state` object—which still exists, so legacy code will continue to work.  See the [`State` API](#state-api) docs for more information.

The `State.display()` method—formerly `state.display()`—is no longer overridable, meaning it cannot be wrapped—e.g., the "StoryRegions" 3rd-party add-ons do this.  Instead, use [Navigation Events or Tasks](#navigation-events-tasks).

Calling the [`State.prng.init()` method](#state-api-method-prng-init)—formerly `History.initPRNG()`—outside of story initialization will now throw an error.  It has always been required that the call happen during story initialization, the only change is the throwing of the error.

### Seedable pseudo-random number generator (PRNG)

`Math.random()` is no longer replaced by the integrated seedable PRNG when `State.prng.init()` is called.  Instead, use either the built-in functions [`random()`](#functions-function-random) & [`randomFloat()`](#functions-function-randomfloat) or the [`State.random()` method](#state-api-method-random), if you need direct access to the PRNG—since it returns a call to either `Math.random()` or the seedable PRNG, as appropriate.

### Macro system

The `Macros` API object has been renamed to `Macro` and several of its methods have also changed, for better consistency with the other APIs.  Furthermore, it is no longer instantiated into the legacy `macros` object—which still exists, so SugarCube-compatible legacy macros will continue to work.  See the [`Macro` API](#macro-api) docs for more information.

### Macro library

			Macro
			Changes

			<<back>> & <<return>>
			Replaced the ungainly link text syntax—<<back::linktext "…">>/<<return::linktext "…">>—with l10nStrings object properties—l10nStrings.macroBackText and l10nStrings.macroReturnText.

			<<if>> & <<elseif>>
			The <<if>> macro will now, optionally, return an error if the JavaScript = assignment operator is used (default: enabled).  Configured via the Config.macros.ifAssignmentError config property.

			Options macros
			The various Options macros have been removed.  See the Options system section for more information.

### Options system

The entire Options system—`MenuOptions` special passage, `options` special variable, and associated macros—has been scrapped for numerous reasons—it was always a hack, required copious amounts of boilerplate code to be useful, etc.  It is replaced by the `Setting` API and `settings` special variable.  See the [`Setting` API](#setting-api) docs for more information.

### Save system

The `SaveSystem` API object has been renamed to `Save` and several of its methods have also changed, for better consistency with the other APIs.  See the [`Save` API](#save-api) docs for more information.

### UI system

The `UISystem` API object has been split into two APIs `Dialog` and `UI`, and some of its methods have also changed.  In particular, the parameter list for the [`Dialog.setup()` method](#dialog-api-method-setup) has changed.  See the [`Dialog` API](#dialog-api) and [`UI` API](#ui-api) docs for more information.


code:
# Guide: Harlowe to SugarCube {#guide-harlowe-to-sugarcube}

There are many differences between Harlowe and SugarCube, this guide will document some of the most critical you will need to account for if you're coming to SugarCube from a background in Harlowe.

## Macro Overview {#guide-harlowe-to-sugarcube-macro-overview}

Aside from general syntax, SugarCube macros do not use hooks, separate arguments differently, and don't allow other macros to be passed as arguments.

### Macro Arguments

Like in Harlowe, some SugarCube macros accept expressions and others accept discreet arguments.  In SugarCube, discreet arguments passed to a macro are separated by spaces instead of commas.  To pass expressions or the results of functions to macros as an argument, you must wrap the expression in backquotes (`` ` ``).

Additionally, macros in SugarCube do not return values, so macros cannot be used as arguments to other macros.  SugarCube provides a variety of functions and methods that may be used instead, and standard JavaScript functions and methods may also be used.

Consider the following Harlowe code:

```
(link-goto: "Go somewhere else", (either: "this passage", "that passage", "the other passage"))
```

A version of the above code in SugarCube might look like this:

```
<<link "Go somewhere else" `either("this passage", "that passage", "the other passage")`>><</link>>
```

See:
Macro Arguments.

### Container Macros

Where Harlowe uses its hook syntax (square brackets) to associate a macro with its contents, SugarCube instead uses "container" macros—macros that can have content associated with them have opening and closing tags.

Consider the following Harlowe code:

```
(if: $var is 1)[
	The variable is 1.
]
```

In SugarCube, you instead open and close the [`<<if>>`](#macros-macro-if) macro itself:

```
<<if $var is 1>>
	The variable is 1.
<</if>>
```

## Specific Macros {#guide-harlowe-to-sugarcube-specific-macros}

Some macros in Harlowe and SugarCube share a name but work a bit differently.  We'll cover some of these differences below.

### Link and Click Macros

SugarCube does not have any equivalents to Harlowe's `(click:)` family of macros.  Additionally, SugarCube's normal [`<<link>>`](#macros-macro-link) macro does not have an output element associated with it and is not, by default, a single-use link like its Harlowe equivalent.  Both of these features can be constructed in SugarCube, however, using macros like [`<<linkreplace>>`](#macros-macro-linkreplace) or by combining `<<link>>` macros with [DOM macros](#macros-dom).  Additionally, SugarCube's link macro accepts a passage argument, that, if included, turns any `<<link>>` into something similar to Harlowe's `(link-goto:)` macro.

Consider the following Harlowe link macros:

```
(link: "Hey there.")[Hay is for horses.]
(link-repeat: "Get some money")[(set: $cash to it + 1)]
(link-goto: "Move on", "next passage")
```

The equivalent SugarCube code for each link might look something like this:

```
<<linkreplace "Hey there.">>Hay is for horses.<</linkreplace>>
<<link "Get some money">><<set $cash += 1>><</link>>
<<link "Move on" "next passage">><</link>>
```

SugarCube's `<<link>>` and `<<button>>` macros can also accept the link markup as an argument:

```
<<link [[Move on|next passage]]>><</link>>
```

### DOM Macros

Note:
Harlowe refers to these as "revision macros".

SugarCube's DOM macros can target any HTML element on the page, not just hooks, and unlike their Harlowe equivalents, they cannot target arbitrary strings.  You can use custom style markup or HTML to create the elements, and then target them with a query selector.

Consider the following Harlowe code:

```
(set: _greetings to (a: "hi", "hello", "good day", "greetings"))\
The man says, "|target>[(either: ..._greetings)]."

{
(link-repeat: "Change")[
	(replace: ?target)[(either: ..._greetings)]
]
}
```

The equivalent SugarCube code to achieve a similar result would be:

```
<<set _greetings to ["hi", "hello", "good day", "greetings"]>>\
The man says, "@@#target;<<= _greetings.random()>>@@."

<<link "Change">>
	<<replace "#target">><<= _greetings.random()>><</replace>>
<</link>>
```

Note:
The DOM macros do have a limitation that you should familiarize yourself with.

### The Goto Macro

Harlowe's implementation of the `(goto:)` macro terminates the rendering passage.  In SugarCube, the passage is not terminated, and anything in the code below the [`<<goto>>`](#macros-macro-goto) macro will have side effects.

Consider this Harlowe code:

```
:: some passage
(set: $count to 0)
(goto: "next")
(set: $count to it + 1)

:: next
$count <!-- 0 -->
```

In the above, the second `(set:)` macro is never run, and the `$count` variable remains at 0.

The equivalent SugarCube code works a bit differently:

```
:: some passage
<<set $count to 0>>
<<goto "next">>
<<set $count += 1>>

:: next
$count /* 1 */
```

SugarCube does not terminate the parsing of the calling passage, so some care is required when calling `<<goto>>`.

As with `<<link>>` and `<<button>>`, `<<goto>>` can accept link markup as its argument:

```
<<goto [[next]]>>
```

## User Input {#guide-harlowe-to-sugarcube-user-input}

SugarCube's user input macros, like [`<<textbox>>`](#macros-macro-textbox), cannot be nested inside a [`<<set>>`](#macros-macro-set) macro, as you might do with a `(prompt:)` and a `(set:)` in Harlowe.  Instead, the macro is passed a *receiver variable* which is set to the value input by the user.

For example, if you wanted to ask the user to enter a name, your code may look like this in Harlowe:

```
(set: $name to (prompt: "What is your name?", "Frank"))
```

In SugarCube, you would likely want to use the `<<textbox>>` macro instead, and pass `$name` in as the receiving variable:

```
<label>What is your name? <<textbox "$name" "Frank">></label>
```

Harlowe's newer input macros, like `(dropdown:)` and `(cycling-link:)` use "bound" variables, which are similar in concept to SugarCube's receiver variables.

## Data Types {#guide-harlowe-to-sugarcube-data-types}

Harlowe's implementation of data types differs significantly from SugarCube's.  A data type refers to the "type" of data a variable is holding, such as a number, a string, an array, or anything else.  Harlowe has stricter typing than SugarCube, requiring authors to call macros like `(str:)` or `(num:)` on variables to change their type.  SugarCube, like JavaScript, uses *dynamic* typing.

### Dynamic Typing

SugarCube, like JavaScript, will try to make sense of expressions passed to it by *coercing* their values if necessary:

```
<<set $number to 1>>
<<set $string to "2">>
<<= $string + $number>> /* "21" */
```

In the above case, since the string value `"2"` cannot be added to a number value, the number value is *coerced* into a string, and the two strings are then *concatenated*.  In Harlowe, the same operation will yield an error:

```
(set: $number to 1)
(set: $string to "2")
(print: $string + $number) <!-- error! -->
```

You *must* convert the values to the same type in Harlowe.  In SugarCube you *can* convert them if you need to.

In Harlowe:

```
(set: $number to 1)
(set: $string to "2")
(print: $string + $number) <!-- error! -->
(print: $string + (str: $number)) <!-- "21" -->
(print: (num: $string) + $number) <!-- 3 -->
```

In SugarCube:

```
<<set $number to 1>>
<<set $string to "2">>
<<= $string + $number>> /* "21" */
<<= $string + String($number)>> /* "21" */
<<= Number($string) + $number>> /* 3 */
```

### Arrays, Datamaps, and Datasets

Harlowe's arrays, datamaps, and datasets are functionally similar to JavaScript `Array`s, `Map`s, and `Set`s, but with a few key differences.  SugarCube requires authors to define and work with these data types using the standard JavaScript methods rather than providing macros for them.

Using an array in Harlowe:

```
(set: $array to (a:))
(set: $array to it + (a: "something"))
(if: $array contains "something")[…]
```

In SugarCube:

```
<<set $array to []>>
<<run $array.push("something")>>
<<if $array.includes("something")>>…<</if>>
```

Using a datamap in Harlowe:

```
(set: $map to (dm: "key", "value"))
(set: $map's key to "another value")
(if: $map contains key)[…]
```

In SugarCube:

```
<<set $map to new Map([["key", "value"]])>>
<<run $map.set("key", "another value")>>
<<if $map.has("key")>>…<</if>>
```

SugarCube also allows the use of JavaScript generic objects, which may be better in some situations than a map:

```
<<set $object to { key : "value" }>>
<<set $object.key to "another value">>
<<if $object.hasOwnProperty("key")>>…<</if>>
```

Another important difference in the way Harlowe handles its non-primitive data types like arrays, datamaps, and datasets is that they are *passed by value* rather than *passed by reference*.

Consider the following Harlowe code:

```
(set: $player to (dm: "hp", 100, "mp", 50))
(set: $partyMember to $player)
(set: $partyMember's hp to it - 50)
(print: $player's hp) <!-- 100 -->
(print: $partyMember's hp) <!-- 50 -->
```

As you can see, Harlowe creates a deep copy/clone of its non-primitive data types each time they're modified.

In SugarCube, both variables would still point to the same underlying object—at least initially (see below):

```
<<set $player to { hp : 100, mp : 50 }>>
<<set $partyMember to $player>>
<<set $partyMember.hp -= 50>>
$player.hp /* 50 */
$partyMember.hp /* 50 */
```

SugarCube does eventually clone its non-primitive data types as well, but does at the start of passage navigation, rather than each time they're modified.


code:
# Guide: Installation {#guide-installation}

This is a reference on how to install SugarCube in Tweego, Twine 2, and Twine 1/Twee.

Note (Twine 2):
Newer versions of Twine 2 come bundled with a version of SugarCube v2, so you only need to read these instructions if you want to install a newer version of SugarCube v2 than is bundled or a non-standard release.

## Local Install For Tweego {#guide-installation-tweego}

See [Tweego's documentation](http://www.motoslave.net/tweego/docs/) for more information.

## Local Install For Twine 2 {#guide-installation-twine2}

There are two primary branches of Twine 2 as far as SugarCube is concerned:

* Those that bundle SugarCube v2: Any series of Twine 2 with a version ≥2.1.
* Those that do not bundle SugarCube v2: Only the older Twine 2.0 series.

Regardless of the version of Twine 2 you're using, follow these instructions to install a local copy of SugarCube v2:

1. Download the current version of [SugarCube v2 for Twine 2](http://www.motoslave.net/sugarcube/2/#downloads)—comes as a ZIP archive.  **NOTE:** There are separate downloads for Twine ≥2.1 and Twine 2.0, so you ***must*** ensure that you download the one that matches your version of Twine 2 or you will likely run into issues.
2. Extract the archive to a safe location on your computer and make note of the path to it.  Make sure to keep the files together if you move them out of the included directory.
3. Launch Twine 2.
4. Click on the `Formats` link in the Twine 2 sidebar.
5. In the dialog that opens, click on the `Add a New Format` tab.
6. Finally, paste a [file URL](http://en.wikipedia.org/wiki/File_URI_scheme) to the `format.js` file, based upon the path from step #2, into the textbox and click the `+Add` button (see below for examples).

### UNIX (and similar) file URL examples

Note:
If constructing the file URL from a shell path, ensure that either it does not contain escapes or you properly convert them into the correct URL percent-encoded form.

If the full path to the contents of the archive is something like:

```
/home/soandso/Twine/StoryFormats/SugarCube-2/format.js
```

Then the file URL to it would be:

```
file:///home/soandso/Twine/StoryFormats/SugarCube-2/format.js
```

### Windows file URL examples
If the full path to the contents of the archive is something like:

```
C:\Users\soandso\Documents\Twine\StoryFormats\SugarCube-2\format.js
```

Then the file URL to it would be (note the changed slashes):

```
file:///C:/Users/soandso/Documents/Twine/StoryFormats/SugarCube-2/format.js
```

## Online Install For Twine 2 {#guide-installation-twine2-online}

The online SugarCube install, delivered by the [jsDelivr CDN](https://www.jsdelivr.com/), supports only versions of Twine 2 ≥2.1.

Copy the following URL and paste it into the *Add a New Format* tab of the *Formats* menu, from Twine 2's sidebar.

**URL:** [https://cdn.jsdelivr.net/gh/tmedwards/sugarcube-2/dist/format.js](https://cdn.jsdelivr.net/gh/tmedwards/sugarcube-2/dist/format.js)

## Local Install For Twine 1/Twee {#guide-installation-twine1-twee}

Follow these instructions to install a local copy of SugarCube v2:

1. Download the current version of [SugarCube v2 for Twine 1/Twee](http://www.motoslave.net/sugarcube/2/#downloads)—comes as a ZIP archive.
2. Go to your Twine 1/Twee installation directory and open the `targets` directory within.
3. Move the downloaded archive into the `targets` directory and extract it, included directory and all.

If you followed the steps correctly, within Twine 1/Twee's `targets` directory you should now have a `sugarcube-2` directory, which contains several files—e.g., `header.html`, `sugarcube-2.py`, etc.

Warning (Twine 1):

Due to a flaw in the current release of Twine 1/Twee (v1.4.2), if you rename the directory included in the archive (or simply copy its contents to your current SugarCube v2 install), then you must ensure that the file with the extension .py (the story format's custom Twine 1 Header class file) within is named the same as the directory—i.e., the name of the directory and .py file must match.

For example, if the name of SugarCube's directory is sugarcube, then the name of the .py file within must be sugarcube.py.  Similarly, if the directory is sugarcube-2, then the name of the .py file within must be sugarcube-2.py.  Etc.

The directory and .py file names within the archive available for download are already properly matched—as sugarcube-2 and sugarcube-2.py—and to avoid issues it recommended that you simply do not rename them.


code:
# Guide: Localization {#guide-localization}

This is a reference for localizing SugarCube's default UI text, in general, and its `l10nStrings` object specifically.

Note:
If you're simply looking to download ready-to-use localizations, see SugarCube's website (under Downloads > Localizations).

#### History:

* `v2.0.0`: Introduced.
* `v2.10.0`: Added `l10nStrings` object.  Deprecated `strings` object.

#### A note about `strings` vs. `l10nStrings`

Prior to SugarCube `v2.10.0`, the strings localization object was named `strings`.  The new `l10nStrings` object has a simpler, flatter, set of properties and better support for replacement strings.  Unfortunately, this means that the two objects are incompatible.

To ensure backwards compatibility of existing `strings` objects, if one exists within a project's scripts, the older object is mapped to the new `l10nStrings` object.

## Translation Notes {#guide-localization-translation-notes}

The capitalization and punctuation used within the default replacement strings is deliberate, especially within the error and warning strings.  You would do well to keep your translations similar when possible.

Replacement patterns have the format `{NAME}`—e.g., `{identity}`—where NAME is the name of a property within either the `l10nStrings` object or, in a few cases, an object supplied locally where the string is used—these instances will be commented.

By convention, properties starting with an underscore—e.g., `_warningIntroLacking`—are used as templates, only being included within other localized strings.  Feel free to add your own if that makes localization easier—e.g., for gender, plurals, and whatnot.  As an example, the default replacement strings make use of this to handle various warning intros and outros.

In use, replacement patterns are replaced recursively, so replacement strings may contain patterns whose replacements contain other patterns.  Because replacement is recursive, care must be taken to ensure infinite loops are not created—the system will detect an infinite loop and throw an error.

## Usage {#guide-localization-usage}

Properties on the strings localization object (`l10nStrings`) should be set within your project's JavaScript section (Twine 2: the Story JavaScript; Twine 1/Twee: a script-tagged passage) to override the defaults.

For the template that should be used as the basis of localizations, see the [`locale/l10n-template.js` file @github.com](https://github.com/tmedwards/sugarcube-2/tree/develop/locale/).

### Examples

```
// Changing the project's reported identity to "story"
l10nStrings.identity = "story";

// Changing the text of all dialog OK buttons to "Eeyup"
l10nStrings.ok = "Eeyup";

// Localizing the title of the Restart dialog (n.b. machine translations, for example only)
l10nStrings.restartTitle = "Neustart";  // German (de)
l10nStrings.restartTitle = "Reiniciar"; // Spanish (es)
```