# Arcscript

Source: https://docs.arcweave.com/project-items/arcscript
Section: Project Items
Description: Arcweave's scripting language, use, syntax, and functions

Arcweave has its own scripting language, **Arcscript**, with basic scripting capabilities. You can use Arcscript in the following two ways:

- As **conditions**, in [branches](https://docs.arcweave.com/project-items/branches).
- As **segments**, in [element content](https://docs.arcweave.com/project-items/elements#add-arcscript) and [connection labels](https://docs.arcweave.com/project-items/labels#arcscript-in-labels).

## Arcscript in branches

Context: Arcweave docs > Project Items > Arcscript > Arcscript in branches

Arcscript is used in **branches** to control flow with `if`, `elseif`, and `else` conditions.

![Arcweave project environment showing a branch that includes `if`, `elseif`, and `else` conditions evaluating board variables.](https://docs.arcweave.com/assets/branches-if-elseif-else.DssujV9V.png)

Branch conditions use the [expressions](https://docs.arcweave.com/project-items/arcscript#expressions) and [condition operators](https://docs.arcweave.com/project-items/arcscript#conditions) described on this page. For how a branch evaluates its conditions, see [branches](https://docs.arcweave.com/project-items/branches).

## Arcscript segments

Context: Arcweave docs > Project Items > Arcscript > Arcscript segments

Arcscript segments are single lines of code that you can add into the content of [elements](https://docs.arcweave.com/project-items/elements) and [labels](https://docs.arcweave.com/project-items/labels).

![A label and an element with contents that include rich text and Arcscript code.](https://docs.arcweave.com/assets/element-label-richtext-arcscript.CBFrUdz9.png)

They support [assignment statements](https://docs.arcweave.com/project-items/arcscript#assignment-statements), [conditional statements](https://docs.arcweave.com/project-items/arcscript#conditional-statements), and calls to [built-in functions](https://docs.arcweave.com/project-items/arcscript#built-in-functions) such as `show()` or `reset()`.

> ℹ️ In Play Mode, an Arcscript segment does not start a new paragraph. Text before and after a segment, including text produced by a conditional statement or `show()`, joins the same paragraph, separated by a space. To keep the text after a segment in a separate paragraph, leave an empty line after the segment.

## Add Arcscript

Context: Arcweave docs > Project Items > Arcscript > Add Arcscript

To insert an Arcscript segment into the content of an [element](https://docs.arcweave.com/project-items/elements) or connection [label](https://docs.arcweave.com/project-items/labels), you use the **Arcscript** icon of the [formatting menu](https://docs.arcweave.com/project-tools/rich-text), the one with the symbol `<>`.

![Arcweave's project environment, while editing an element. An orange arrow and an orange rectangle emphasize the position of the Arcscript icon in the formatting bar.](https://docs.arcweave.com/assets/arcscript-segments-icon.sqO3lJkR.png)

1. Double-click the element or label to enter content editing mode.
2. Place the cursor on the line where you want to insert the Arcscript segment.
3. Click the **Arcscript** icon (`<>`) in the formatting menu.
4. Press **Enter** to exit the Arcscript segment and continue writing in the next line.

> ✅ You can also toggle an Arcscript segment using the shortcut **Ctrl/Cmd + Shift + C**.

## Auto-complete

Context: Arcweave docs > Project Items > Arcscript > Auto-complete

While you type in an Arcscript segment or branch condition, Arcweave provides auto-complete suggestions.

![Animated GIF demonstrating the auto-complete feature in Arcscript.](https://docs.arcweave.com/assets/auto-complete.8qWJtNCz.gif)

Suggestions include:

- Global variables, and board and component variables with their scope, such as `hero.health`
- [Built-in functions](https://docs.arcweave.com/project-items/arcscript#built-in-functions)
- The keywords `if`, `elseif`, `else`, and `endif`
- The word operators `and`, `or`, `not`, and `is`
- The literals `true` and `false`

Use the arrow keys to select the relevant suggestion and press **Enter** or **Tab** to insert it in your code. Press **Esc** to close the suggestions.

## Variables and scope

Context: Arcweave docs > Project Items > Arcscript > Variables and scope

Global variables use their name directly. Board and component variables are String Field, Boolean, Integer, or Float attributes and use the owning board or component's custom ID as a scope:

```arcscript
${ health = 100 }
${ castle.health = 10 }
${ hero.health = 20 }
```

In this example, `health`, `castle.health`, and `hero.health` are three distinct variables. Unqualified names such as `health` resolve global variables only.

Scoped variables support string, boolean, integer, and float values. See [Variable scope](https://docs.arcweave.com/project-items/variables/overview#variable-scope), [Board variables](https://docs.arcweave.com/project-items/variables/board), and [Component variables](https://docs.arcweave.com/project-items/variables/component) for setup instructions.

## Assignment statements

Context: Arcweave docs > Project Items > Arcscript > Assignment statements

Assignment statements are of the form of `variable = expression`. For example:

```arcscript
${ x = 5 }
${ x = y + 5 }
${ name = "Tim" }
${ has_key = true }
```

> ℹ️ Before using a variable, create it in **Global variables** or add a **String Field**, **Boolean**, **Integer**, or **Float** attribute to a board or component. Arcweave's auto-complete uses the variable's current name and scope.

Arcscript also supports the following operations, with their respective operators:

| Operation      | Operator | Description                                                                       |
| :------------- | :------: | :-------------------------------------------------------------------------------- |
| Addition       |   `+=`   | Adds the right-hand value to the variable and assigns the result.                 |
| Subtraction    |   `-=`   | Subtracts the right-hand value from the variable and assigns the result.          |
| Multiplication |   `*=`   | Multiplies the variable by the right-hand value and assigns the result.           |
| Division       |   `/=`   | Divides the variable by the right-hand value and assigns the result.              |
| Modulo         |   `%=`   | Applies modulo to the variable using the right-hand value and assigns the result. |

For example:

```arcscript
${ x = 5 }
${ x += 10 }
${ x -= 2 }
```

With string values, `+=` appends the right-hand text, for example `${ name += " Smith" }`. The other compound operators cause an error when used with strings.

## Conditional statements

Context: Arcweave docs > Project Items > Arcscript > Conditional statements

Conditional statements are of the form: `if...`/`elseif...`/`else`/`endif`.

> ℹ️ This section applies to conditional statements found in [elements](https://docs.arcweave.com/project-items/elements) and [labels](https://docs.arcweave.com/project-items/labels). Conditional statements in branches follow the same logic, but do not close with `endif` expressions. See [Condition evaluation](https://docs.arcweave.com/project-items/branches#condition-evaluation).

Inside conditional statements you may have:

- other statements (assignments, function calls, or conditionals).
- text content.

> ⚠️ The `if`, `elseif`, `else`, and `endif` segments of a conditional statement cannot be inside a blockquote, although the text between them can. Inside a blockquote, you can use assignments and function calls.

Example of a conditional statement containing an assignment:

```arcscript
${ if x == 5 }
  ${ y = 4 }
${ endif }
```

Example of a conditional statement containing some text content:

```arcscript
${ if wielding_shield }
  The knight is wielding a large shield.
${ endif }
```

Example of a conditional statement containing some text content and a variable assignment:

```arcscript
${ if hasKey }
  You unlock the door!
  ${ doorUnlocked = true }
${ else }
  You cannot open the door
${ endif }
```

Example of using `elseif` for multiple outcomes:

```arcscript
${ if age >= 18 }
  Look at you! All grown up!
  ${ type = "adult" }
${ elseif age > 0 }
  You are not an adult yet.
  ${ type = "child" }
${ else }
  Are you sure you have been born?
  ${ type = "unborn" }
${ endif }
```

## Expressions

Context: Arcweave docs > Project Items > Arcscript > Expressions

Arcscript supports expressions that use the following arithmetic operators:

| Operator | Name           | Description                                                     |
| :------: | :------------- | :-------------------------------------------------------------- |
|   `+`    | Addition       | Adds two numbers, or joins them as text if either is a string.  |
|   `-`    | Subtraction    | Subtracts the right-hand value from the left-hand value.        |
|   `*`    | Multiplication | Multiplies two numeric values.                                  |
|   `/`    | Division       | Divides the left-hand value by the right-hand value.            |
|   `%`    | Modulo         | Returns the remainder of a division between two numeric values. |
| `(` `)`  | Parentheses    | Groups parts of an expression to control evaluation order.      |

Expressions may combine literals, function calls, and variables. Write string literals in double or single quotes, such as `"Tim"` or `'Tim'`. A minus sign before a value negates it, such as `-x`.

## Conditions

Context: Arcweave docs > Project Items > Arcscript > Conditions

### Conditional operators

Context: Arcweave docs > Project Items > Arcscript > Conditions > Conditional operators

|    Operator    | Name                  | Description                                                                          |
| :------------: | :-------------------- | :----------------------------------------------------------------------------------- |
|   `==`, `is`   | Equality              | Checks whether two values are equal. `5` and `"5"` are not equal.                    |
| `!=`, `is not` | Inequality            | Checks whether two values are not equal.                                             |
|      `>`       | Greater than          | Checks whether the left-hand value is greater than the right-hand value.             |
|      `>=`      | Greater than or equal | Checks whether the left-hand value is greater than or equal to the right-hand value. |
|      `<`       | Less than             | Checks whether the left-hand value is less than the right-hand value.                |
|      `<=`      | Less than or equal    | Checks whether the left-hand value is less than or equal to the right-hand value.    |

### Logical operators

Context: Arcweave docs > Project Items > Arcscript > Conditions > Logical operators

|   Operator   | Name        | Description                                                      |
| :----------: | :---------- | :--------------------------------------------------------------- |
| `&&`, `and`  | Logical AND | Evaluates to `true` if both conditions are true.                 |
| `\|\|`, `or` | Logical OR  | Evaluates to `true` if at least one condition is true.           |
|  `!`, `not`  | Logical NOT | Negates a condition, turning `true` into `false` and vice versa. |

## Built-in functions

Context: Arcweave docs > Project Items > Arcscript > Built-in functions

The functions that are currently supported in Arcscript:

| Function                | Returns                                                                                  |
| ----------------------- | ---------------------------------------------------------------------------------------- |
| `abs(n)`                | The absolute value of a number                                                           |
| `sqr(n)`                | The square of a number                                                                   |
| `sqrt(n)`               | The square root of a number                                                              |
| `min(n1, n2, ...)`      | The minimum of two or more numbers                                                       |
| `max(n1, n2, ...)`      | The maximum of two or more numbers                                                       |
| `random()`              | A random decimal between (and including) 0 and (excluding) 1, i.e. in `[0, 1)`           |
| `reset(v1, v2, ...)`    | Has no return value; resets one or more given variables to their initial value           |
| `resetAll(v1, v2, ...)` | Has no return value; resets all variables, except the given ones, to their initial value |
| `resetVisits()`         | Has no return value; resets all elements' visits to 0                                    |
| `roll(m, n)`            | The sum of `n` rolls of an `m`-sided die (`n` defaults to 1)                             |
| `round(n)`              | The number rounded to the nearest integer                                                |
| `show(e1, e2, ...)`     | Has no return value; renders the concatenation of its evaluated arguments as text        |
| `visits(el)`            | The number of visits to an element; without an argument, to the current element          |

`reset()` and `resetAll()` apply to global, board, and component variables. Call `resetAll()` without arguments to reset every variable.

### `roll`

Context: Arcweave docs > Project Items > Arcscript > Built-in functions > `roll`

![A part of an Arcweave flowchart demonstrating a simple use of the roll function: roll returns a value that gets stored in a variable. Then, a branch compares the variable with a number and diverts the flow accordingly.](https://docs.arcweave.com/assets/roll.CXzWJU8f.png)

The `roll(m, n)` function simulates polyhedral die rolls from the classic tabletop RPGs.

Roll takes up to 2 positive integers as its arguments:

- `m`: the number of sides of the rolled die.
- `n`: the number of dice rolled.

The function returns a random integer between (and including both) `n` and `n*m`, i.e. `[n, n*m]`.

> ✅ If `n = 1`, you can omit the second argument and simply type `roll(m)`.

For example, rolling for a number from 1 to 12:

```arcscript
${ damage = roll(12) }
```

Example of rolling 3d6 (3 six-sided dice) for a character's ability scores in _Dungeons & Dragons:_

```arcscript
${ dexterity = roll(6, 3) }
```

Example of a dynamic use, where the player suffers damage from `1` to `max_damage`:

```arcscript
${ player_hp = player_hp - roll(max_damage) }
```

But the `roll(m, n)` function can also be used in a conditional statement:

```arcscript
${ if roll(max_damage) > player_hp }
  Oops... This isn't good...
${ endif }
```

### `show`

Context: Arcweave docs > Project Items > Arcscript > Built-in functions > `show`

The `show(e1, e2, ...)` function renders its arguments and concatenates them as one string.

For example, the following:

```arcscript
${ show("Your score is ", score, "/", max_score, ".") }
```

... for `score == 3` and `max_score == 256` renders:

> Your score is 3/256.

You can use the `show(e1, e2, ...)` function in combination with text content, in elements. For example:

```arcscript
${ if roll(max_damage) > player_hp }
  Oops... This isn't good...
  You have died. In this game you scored
  ${ show(score, " out of ", max_score, ".") }
${ endif }
```

### `visits`

Context: Arcweave docs > Project Items > Arcscript > Built-in functions > `visits`

#### Call `visits()` with an `element` argument

Context: Arcweave docs > Project Items > Arcscript > Built-in functions > `visits` > Call `visits()` with an `element` argument

The `visits(element)` function returns the number of times a specific element has been visited during the current playthrough. The count includes the current visit: while the player is on an element for the first time, its count is `1`.

The `element` argument must be a **mention** to an element. To mention an element inside `visits()`:

1. Place your cursor within the parentheses of `visits()`.
2. Type `@` and begin entering the element's title. You can mention elements from any board.
3. Select the correct element from the autocomplete list.

> ✅ Mentioning an element in Arcscript works similarly to [mentioning a component or board](https://docs.arcweave.com/project-tools/mentions) in rich text fields.

#### Call `visits()` without an argument

Context: Arcweave docs > Project Items > Arcscript > Built-in functions > `visits` > Call `visits()` without an argument

If `visits()` is called without an argument, it refers to the element the player is currently on:

- When used inside an **element's content**, it refers to that element itself.
- When used inside a **connection label** or **branch condition**, it refers to the element whose options are being prepared: the element where the option's path starts.

> ✅ To reset the visits of all elements of your project, use the `resetVisits()` function. It is always called without arguments.

#### Examples

Context: Arcweave docs > Project Items > Arcscript > Built-in functions > `visits` > Examples

In the following example, `examine_the_painting` stands for a mention of the **Examine the painting** element:

```arcscript
The knight is guarding a mysterious gate. You see a name written above his head:
| "Conrad IV, Count of Exeter"
${ if visits(examine_the_painting) > 1 }
  You make a mental note of the knight's name.
${ endif }
```

And if we are already in the **Examine the painting** element, we can write:

```arcscript
The knight is guarding a mysterious gate. You see a name written above his head:
| "Conrad IV, Count of Exeter"
${ if visits() > 1 }
  You make a mental note of the knight's name.
${ endif }
```

## Errors

Context: Arcweave docs > Project Items > Arcscript > Errors

Arcweave checks your Arcscript as you write it. When a script has a syntax error, uses a variable that does not exist, calls a function with the wrong number of arguments, or mentions an element that does not exist, an **exclamation mark symbol** appears at the corner of the element, label, or branch condition that contains it.

> ✅ Hover your mouse cursor over the symbol to see the error message and the line and column where the error occurs.

Other errors occur only when Play Mode runs the script, such as dividing by zero or passing text to a function that expects a number. Play Mode shows these errors below the element's content or below its options. An option whose label causes an error is not shown, and a branch condition that causes an error counts as not met.
