# Blocks

Source: https://docs.skaz.io/guide/blocks

> Every block in Skaz: text, dialogue, wheel of fortune, user input, variables, routers and sound. What each does, plus choice timers and auto-advance.

Blocks (also called **nodes**) are the building pieces of a story. Each block
does one thing — show some text, ask a question, or quietly update the
story's state — and then leads to the next block via one or more
[choices](/guide/choices).

You add blocks using the buttons on the left toolbar of the editor. There are
ten block types:

| Block | Toolbar tooltip | Shown to players? |
|---|---|---|
| [Text](#text) | Create new node | Yes |
| [Dialogue](#dialogue) | Dialogue | Yes |
| [Wheel of Fortune](#wheel-of-fortune) | Wheel of fortune | Yes |
| [User Input](#user-input) | User input node | Yes |
| [Audio](#audio) | Audio node | Yes |
| [Start Background Audio](#start-background-audio) | Start background audio node | No (instant) |
| [Stop Background Audio](#stop-background-audio) | Stop background audio node | No (instant) |
| [Set Variable Value](#set-variable-value) | Set variable value node | No (instant) |
| [Change Variable Value](#change-variable-value) | Change variable value node | No (instant) |
| [Variable Router](#variable-router) | Variable router node | No (instant) |

> Blocks marked **No (instant)** don't show a screen to the player. As soon as
> the player reaches one, it runs immediately and the story moves straight on
> to the next block.

## Text

The basic narrative block. Use it for any scene, description, or piece of
dialogue.

**Fields**

- **text** — the text shown to the player. Supports `{{variable_name}}`
  placeholders — see [Displaying variables in text](/guide/variables#displaying-variables-in-text).
- **image** (optional) — an image shown alongside the text.

The player reads the text/image, then picks one of the block's choices to
continue. See [Choices & Branching](/guide/choices).

### Auto-advance

When a Text block has **no choices** and is simply wired to the next block, the
inspector offers an **Auto-advance** field. Set it to a number of seconds and
the scene runs on a timer: the player sees no Next button, just a small bar
draining where the button would be, and the story continues on its own when the
bar empties.

Use it for beats you want to control — a single line landing before the next
one, a pause after a door slams. Leave it at `0` and the reader presses Next at
their own pace.

### Choice timer

A Text or [Dialogue](#dialogue) block with **two or more choices** gets a
**Choice timer** in the inspector. Set a number of seconds and pick what
happens **when time runs out** — one of the block's own choices. Players see a
bar draining above the choices; if it empties before they pick, the story
takes that choice for them.

Use it where hesitation is the point: a customer who hangs up if you stall, a
safety call that has to be made now, a quiz answered on instinct. In a Dialogue
block the clock starts once the last line has been read.

> On a Text block the clock is kept by Skaz, not just the player's browser:
> reloading the page doesn't restart it, and an answer that arrives after time ran
> out counts as the timeout choice. That makes timed choices safe to use in
> assessments.

If you delete the choice a timer falls back to, the
[pre-publish check](/guide/publishing#before-you-publish) flags the block until
you pick another.

## Dialogue

A conversation between your [characters](/guide/characters), shown one line
at a time in front of a background, visual-novel style.

**Fields**

- **background** (optional) — the image the conversation happens in front of.
- **lines** — edited in the inspector's **Lines** section: for each line, who
  speaks, with which emotion, and what they say. Supports `{{variable_name}}`
  placeholders, like text.

Players click through the lines; the block's choices appear after the last one.
If your story has a player character, those choices read as the player's
replies. See [Characters & Dialogue](/guide/characters).

## Wheel of Fortune

A wheel the player spins; the story goes down whichever slice it lands on.
Add it from the **Scene** group — it starts with three slices to edit.

**Fields**

- **title** — shown above the wheel ("Spin to see your fate"). Supports
  `{{variable_name}}` placeholders.
- **spin label** (optional) — the button's text; *Spin* when empty.
- **Outcomes** — edited in the inspector. Each slice has a **label**, an
  **icon** (an emoji works well), a **colour** and a **weight**. A bigger weight
  is a bigger slice and a likelier landing; the inspector shows each slice's
  chance as a percentage.

Every slice is a branch: connect it on the canvas to where that outcome leads,
exactly like a [choice](/guide/choices).

> The landing is drawn by Skaz the moment the player reaches the wheel, not by
> their browser. Reloading the page shows the same result rather than a fresh
> spin, and nobody can pick their own outcome. The spin they watch simply ends
> there.

## User Input

Asks the player a question and lets them type a free-text answer, which is
saved into one of your story's [variables](/guide/variables).

**Fields**

- **text** — the question/prompt shown to the player. Supports
  `{{variable_name}}` placeholders, just like a [Text](#text) block.
- **hint** — placeholder text shown inside the empty input field (e.g. "Enter
  your name..."). Also supports `{{variable_name}}` placeholders.
- **image** (optional) — an image shown alongside the prompt.
- **save_to** — which variable the player's answer is saved into.

Once the player submits their answer, it's stored in the chosen variable and
the story continues to the block's next choice.

> Use User Input early in a story to let players name their character, then
> reference that variable later — for example, route the story differently
> based on what they typed with a [Variable Router](#variable-router).

## Audio

Plays a sound — narration, music, an ambient effect — on its own scene. The
player sees a big **play** button and presses it to start the track.

**Fields**

- **title** — a heading shown above the play button. Supports
  `{{variable_name}}` placeholders.
- **text** (optional) — text shown under the player, for a transcript, a
  caption, or the scene that goes with the sound.
- **audio** — the sound file. Upload it right in the block's inspector; MP3
  works everywhere.

Like a [Text](#text) block, an Audio block waits for the player: they listen,
then pick one of its [choices](/guide/choices) to continue. The track stops
automatically when the story moves on.

> Browsers don't allow sound to start by itself, which is why the block always
> shows a play button instead of auto-playing. Keep clips short — players on
> mobile data will thank you.

## Start Background Audio

Starts a track that keeps playing **across the blocks that follow** — a music
bed, rain, a distant hum. Instant: the player sees no screen for it, the story
moves straight on to the next block while the sound keeps going.

**Fields**

- **audio** — the sound file to start.
- **channel** — which layer to play it on: *Music*, *Ambience* or *Effects*.
  Each channel plays independently, so music and a sound effect can overlap.
  Starting a second track on the **same** channel replaces the first one.
- **loop** — on for anything that should keep going (music, ambience); off for
  a one-shot sound.
- **volume** — 0–100% of the player's own volume. Keep music around 30–50% so
  it sits under the text rather than over it.

The track is part of the player's saved progress, so someone who reloads the
page mid-story gets the sound back where it belongs.

> Browsers won't start sound before the player has clicked something. In
> practice that's covered — the player has already pressed **Start the story** —
> but on a reloaded page the sound resumes on their next click.

## Stop Background Audio

Stops what a [Start Background Audio](#start-background-audio) block started.
Also instant.

**Fields**

- **channel** — the channel to silence, or *All channels* to stop everything
  at once.

Background audio keeps playing until something stops it, including on your
story's ending screen — put a Stop block before an ending if you'd rather it
faded out with the story.

> An instant block with nothing connected after it ends the story — the player
> sees the ending screen, and the block still does its job on the way out, so
> finishing on a Stop Background Audio block is a fine way to fade a story to
> silence. If that wasn't what you meant, connect it to the block that comes
> next.

## Set Variable Value

Sets one of your story's variables to a fixed value. This block is **instant**
— it doesn't show anything to the player.

**Fields**

- **variable_name** — which variable to update.
- **value** — the value to set it to. Works for any variable type (string,
  int, float, or bool) — the value you type is converted to match the
  variable's type.

Use this to initialize a variable, record that the player reached a certain
point ("visited_secret_room = true"), or reset something back to a known
state.

## Change Variable Value

Adds (or subtracts) a number from a numeric variable. Also **instant** — the
player doesn't see this block.

**Fields**

- **variable_name** — which variable to change. Must be an `int` or `float`
  variable.
- **delta** — the amount to add. Use a negative number to subtract (e.g.
  `-1`).

Use this for things like score counters, health, or reputation — for example,
add `+1` to a `trust` variable whenever the player makes a kind choice.

## Variable Router

Branches the story automatically based on the current value of a variable, with
no input from the player. Also **instant**.

**Fields**

- **routing_variable_name** — the variable to check.

Unlike other blocks, a Variable Router's branches aren't buttons the player
clicks — instead, each branch is a *condition* (an operator plus a value, like
`>= 50` or `== true`). The router checks its branches **in order** and jumps to
the first one whose condition matches the variable's current value. See
[Variable Router conditions](/guide/choices#variable-router-conditions) for the
available operators.

> If none of a Variable Router's conditions match, the story won't advance.
> End the router with an **Otherwise** branch — it always matches, so the router
> never gets stuck.

## Endings

A block with nothing connected after it ends the story. Select it and the
inspector offers an **Ending name** — fill it in and players see which ending
they reached instead of a plain "The End", along with how many endings your
story has in total. That count is what makes someone go back and look for the
others.

Named endings also show up in your story's
[statistics](/guide/tracking-plays#statistics), split by how many players
reached each one.

> The name is recorded on each playthrough as it happens, so renaming an ending
> later won't rewrite what past players saw in your numbers.

## What's next

- [Choices & Branching](/guide/choices) — how blocks connect to each other,
  and how Variable Router conditions work.
- [Variables](/guide/variables) — creating and typing the variables these
  blocks read and write.
