Skip to content

Play mode

Walking the story and dressing it — the toolbar, every key, what a save carries, the three container kinds, the five looks and the twenty-one elements.

All documentation — Playing and styling
On this page

Two tabs: Play (walk the story) and Design (dress it). Neither is on the rail. Play in the bar above a board opens the Play tab beside the board and plays that board from its start; the list on the left and the tabs you had open stay where they are. The palette button on the player’s toolbar opens the Design tab on the moment you are looking at, and so does Design how it plays and looks in a node type’s play-mode read-out. Each exists once per project: opening it again brings the same tab to the front.

The player’s Close (Esc) closes the Play tab. Clicking another tab only puts Play behind it, and it carries on from where you left it when you come back.

They are the same renderer over the same project. Neither is a preview of the other, and a public share link runs the same thing again.

One step in the player: Ryn Zhao's portrait and name beside her line, "Security is thight, but I should be able to override my way in.."
A moment, as the player draws it.

Is this the engine the game runs?

Not the same code — the same rules, pinned by shared fixtures.

In the browserIn Unity
ReadsThe live project, on every stepA resolved payload built at sync
Relationship—A port of the browser’s traversal

The browser’s test suite runs a corpus of fixtures through the real traversal engine and writes both the payload and the expected transcript into the C# test project; C# replays the same transcripts and asserts they still match. Thirty-eight fixture pairs are committed, covering gates, jumps, requirements, roll-forward, board entries and language switching.

What happens at a node, in order

  1. Run every script slot, in document order.
  2. Present a step if the node has content.
  3. Resolve the exits: any exit with content means choose — an edge’s label counts, and when several unlabelled, ungated exits leave the node, each borrows the text of the node it leads to and the player is asked; otherwise the first passing gated exit is taken; otherwise exactly one exit advances; otherwise the story ends.
  4. A jumpTarget field overrides all of that; a returnAfter pushes a frame to come back to.

A moment

FieldWhat it is
nodeIts id, its board, its type
verbchoose or present
arrivedBystart · walk · jump · return
fieldsThe resolved field values
choicesThe options, including the blocked ones
choiceKindexit or boardEntry
cast, audio, variablesThe state on stage
traceWhy this step happened
flagsisLatest, isTerminal, awaiting

awaiting is advance, choice, timer, or nothing. The engine itself is idle, presenting, awaiting-choice, or finished — and finished is one of end of path, stopped or error.

A blocked choice

An option drawn but not takeable carries: its kind (a gate or a requirement), the failing expression — diagnostics only, never shown to a player — the tag id and label that become the [STRENGTH] badge (requirements only), an optional author reason, and the failing terms: one per failed check, naming the variable, never the tag.

Saving, loading and rewinding

A save carriesWhere you are (board, node, call stack), the whole language runtime state, which exits have been taken, the active language, and the last 50 moments each with a full state copy
The runtime stateVariables, the entity overlay, the random generator’s state, visit counts, the current node
A save does NOT carryThe moments’ rendered content — it is re-derived, so a save cannot go stale against an edited board. Nor the roll-forward stack, nor which scripts ran, nor anything past the 50-moment window.
WhereYour browser, one slot per project
RestoringEvery moment is re-drawn from its recorded state. No script re-runs and no visit is re-counted.

Back steps to the previous moment. Forward re-advances into a step you rolled back, replaying the recorded decision instead of asking it again — which is what makes rewinding useful for testing rather than merely undoing.

Variable presets let you start mid-story with the state you would have arrived with. The presets themselves live in the project; which one is active is per device.

The toolbar

Controls marked Author are absent — not disabled — for someone playing a share link.

Every tooltip below is quoted exactly, in the order the controls appear.

TooltipShown to
Player settingsEveryone
Why this step? (debug)Author
Design this look (opens the Design tab)Author
Share this story (make a link someone else can play)Author
Back (Backspace)Everyone
Forward — replays the decision you rolled back (→)Everyone
RestartEveryone
The step counterAuthor
Save this playthrough on this deviceEveryone
Load the saved playthroughEveryone
LanguageEveryone, only when the project has more than one
Fullscreen / Leave fullscreen (Esc)Everyone
Close (Esc)Author, in the Play tab only — it closes the tab

Player settings

  • Text speed — Slow · Normal · Fast · Instant
  • Accessibility — Text size, 100–200% in steps of 10; and Turn timed choices off
  • Play voice-over — ticked by default, and offered whether or not the project has any recorded lines yet. While it is ticked a Volume slider sits beside it, 0–100% in steps of 5, starting at 100%. The two are remembered on this device for each project, and they are the only player settings that outlast the visit; turning voice-over off and on again keeps your level. The same switch and slider govern sound effects too — there is no separate effects volume.

Sound on a node

A node whose Asset field holds an audio file plays that sound once, when the story shows the node. It never holds the story up: a sound still playing when you move on runs to its end, unless the next node carries a sound of its own. A picture or video in an Asset field is drawn, never played. If a node carries several sounds, only the first plays.

Keys

KeyAction
Space / EnterSkip a running reveal, otherwise advance
1–9Take that option — claimed only when the option exists
BackspaceBack
→Roll forward — claimed only when there is something to replay
EscapeClose
DeleteRemove the selected design box (never Backspace)

Ctrl+Z and Ctrl+Y / Ctrl+Shift+Z are handed back to the editor while you are designing.

Design — how a moment is drawn

Keys as — the device preview

The Design tab’s bar carries Keys as: Keyboard & mouse · Xbox · PlayStation · Switch · Touch. A mention of an input action — a record whose definition draws its mentions as a keycap (see definitions) — draws the way that device would: the Xbox pad’s B button, the PlayStation circle, the Switch’s A, or the gesture. Every line on the stage and in a log redraws at once, and nothing is replayed. Nothing it shows is stored, and a game draws the player’s own binding instead. The Play tab and a share link draw the keyboard.

The pictures are glyphs, drawn in the stage’s text colour; a control the glyph set does not draw shows its words in a keycap instead. A Stage’s CSS can reach a glyph keycap through .mention-keycap--glyph, its .mention-keycap__glyph and its visually hidden .mention-keycap__text.

Three container kinds

KindThe vocabulary it speaks to its childrenOptions
stackA row or a columndirection, gap, padding, align, justify, wrap
gridCellscolumns (a track list, not a count), rows, gap, padding, align, justify
overlayNine named pointspadding; the child answers with its point, an offset and a z-order

Twenty-one elements, in five families

FamilyElementWhat it is
LayoutStackBoxes in a row or a column
GridBoxes in columns and rows you set
OverlayBoxes stacked on top of each other
SpacerEmpty space
ScrollA region that scrolls on its own
TextTextOne line of text
RichTextFormatted writing, with its styling kept
TextRevealText that types itself out
DataFieldValueWhatever a field of this node holds
PortraitA picture of a character
MediaAn image, a sound or a video
MeterA bar for a number — health, trust, time
DieWhat the story rolled — the die, the total, the outcome
TallyRecords with counts — what was handed over, or a field’s list
FlowChoiceListThe options the player can take
ChoiceOne option, drawn your way
AdvanceHintThe “press to continue” affordance
TimerA countdown on a timed choice
StructureLogThe story so far, line after line
StageSlotWhoever is on stage right now
CardThis node, drawn the standard way

Eight of the twenty-one hold children. Card deliberately does not.

Values in the text are live. A {…} value in a line or in an option’s text — a variable or an expression, inserted with { while writing in a node — is filled with its value when the step is drawn: You have {gold} coins plays as You have 120 coins. A value that cannot be worked out shows its own source, such as {gold}, never a blank. Text you typed with literal braces stays as you typed it.

ChoiceList draws tiles when the options carry pictures. When every option is a row of a list whose rows carry a port, and at least one of those rows holds a picture — a media field, or a record with a portrait — the options become tiles instead of lines: the picture on top, the row’s title under it, and its next text as one small line. A row whose picture has not loaded yet draws an empty frame. The number keys and a click still pick by position, and a locked option is dimmed and explained exactly as in a list. Only the default drawing becomes tiles: a ChoiceList you have filled with your own Choice children keeps them, and the board-entry menu is never tiled. A Stage’s CSS can reach them through .ts-choicelist--tiles, .ts-tile, .ts-tile__face, .ts-tile__title and .ts-tile__line.

The Die shows on a step whose script rolled — a Skill check’s roll(20), or any script of your own that calls roll, pick or another random builtin — and on no other; a story that never rolls never sees it. A check that says nothing to the player is not a step of its own, so its roll rides to the next line that is: the die lands on the line after the check, with the verdict beside it. Its three knobs name the variables the verdict is read from (Total from, Target from, Outcome from), defaulting to the Dialogue, studio grade pack’s checkTotal, checkDifficulty and checkPassed; a Scripted check that writes its own names points them there. No look ships one — place it where the roll should land, usually between the line and the options.

The Tally shows records with counts — a tile per record, its picture with the count in the corner — under a heading you name (Call it; Received unless you say otherwise). Left unbound, it shows what the step handed over: the items on the outcome a Loot roll drew, and nothing on a step that handed nothing over. Bound to an Entities with counts field — a Recipe’s ingredients, a shop’s stock — it shows that field’s entries instead, so the same element is Received on one Stage and Ingredients on another. The same record listed twice is two tiles. No look ships one.

The five looks

Look
JRPG box
Subtitle + list
Big portraitThe default
Side portrait
NVL page

Each carries a palette as well as a layout, and the text colours are derived from it by contrast measurement rather than chosen. Hex only.

Player settings a look can set

revealSpeed (default 40), autoAdvanceMs (default none), timerPolicy (default none) and appendText (default false).

Timer policy is one of three: highlighted default, silence is a choice, or interrupt and restart. With none chosen, the Timer element is withheld.

A look is stored in the project, so it travels to your collaborators and to a share link.

Custom CSS

Two surfaces, and conflating them is the usual mistake:

Custom CSSStyle classes
What it isA raw stylesheetProperty rows that define named classes
Layerts-author — the outermostts-stage
Can express a selectorYesby design

Layer order, emitted before any rule: ts-base, ts-theme, ts-layout, ts-stage, ts-author. The player’s own chrome is deliberately unlayered, so author CSS cannot hide the way out.

Custom CSS now lives on the look, in the project. An older per-device copy is offered for adoption on a gesture rather than migrated automatically, and archived rather than deleted.

The Theme Editor is a different thing

The Theme Editor at the bottom of the activity bar themes the TaleShard editor’s own chrome, not your game — see the workspace. A game’s look is the Design tab above. The two share no settings.

It is stored per browser and never shared with collaborators.

Sharing

A share link comes in three shapes: anyone with the link, link plus password, or a named link per person, individually revocable.

What breaks

SituationWhat happens
A gate errorsThe exit reads false, recorded in the trace
A gate is present but blankOn an automatic exit the exit fails; on an option the player picks it is no condition — see boards
A script errorsScript error in “«field label»”: «error» — and the step still happens. Each script slot runs separately so the message can name the field.
A save is loaded against an edited projectDropped moments, entities and variables are reported, not silently discarded
A playthrough is older than 50 momentsThe window is what a save carries; earlier moments are gone
Author CSS tries to hide the toolbarIt cannot — the player’s chrome is outside every author layer
Written for
Writers · Unity developers · Advanced integrators
Last updated