Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/pompom454/tea/llms.txt

Use this file to discover all available pages before exploring further.

The Config object is a frozen singleton that controls virtually every behavioral aspect of a Tea story. All settings must be written to it from within your project’s Story JavaScript section (Twine 2) or a script-tagged passage (Twine 1/Twee). Properties are grouped into eight namespaced categories below.
Config object settings take effect at initialization. Avoid mutating them during gameplay unless a property’s documentation explicitly permits it.

Config.addVisitedLinkClass

Type: booleanDefault: falseAdds the link-visited CSS class to internal passage links whose destination has already been visited (i.e., exists within the story history). You must supply your own .link-visited styles — none are provided by default.
When true, internal links to visited passages gain the link-visited class.
Config.addVisitedLinkClass = true;
/* Example visited-link style */
.link-visited {
  color: purple;
}

Config.cleanupWikifierOutput

Type: booleanDefault: falsePost-processes Wikifier output to convert stacks of <br> elements into <p> elements where appropriate, producing cleaner HTML markup.
Config.cleanupWikifierOutput
boolean
default:"false"
When true, the Wikifier’s output is sanitized into paragraph-based markup.
Config.cleanupWikifierOutput = true;

Config.debug

Type: booleanDefault: falseIndicates whether Tea is running in test mode, which enables debug views and optional debugging errors. This is automatically set when using Twine 2’s Test mode, Twine 1’s Test Play From Here, or Tweego’s --test flag. You may also set it directly.
Config.debug
boolean
default:"false"
When true, debug views and optional warnings are enabled.
You can branch on Config.debug inside passage markup using <<if Config.debug>>.
// Forcibly enable test mode
Config.debug = true;

// Conditional code block in JavaScript
if (Config.debug) {
  // do something debug-related
}
<<if Config.debug>>
  /* do something debug-related */
<</if>>

Config.enableOptionalDebugging

Type: booleanDefault: falseEnables optional debugging errors and warnings outside of test mode. For example, when enabled, using = (assignment) instead of == (comparison) inside <<if>> conditions raises an error.
Config.enableOptionalDebugging
boolean
default:"false"
When true, optional assignment-error checks and similar warnings are active.
Config.enableOptionalDebugging = true;

Config.loadDelay

Type: integer numberDefault: 0Sets a delay (in milliseconds) before the loading screen is dismissed once the document signals readiness. Useful for media-heavy stories on slow-rendering browsers.
Config.loadDelay
number
default:"0"
Must be a non-negative integer. Throws RangeError otherwise.
// Hold the loading screen for an extra 2 seconds
Config.loadDelay = 2000;

Config.audio.pauseOnFadeToZero

Type: booleanDefault: trueDetermines whether the audio subsystem automatically pauses tracks that have been faded to 0 volume (silent). Disable this if you want faded-out tracks to remain technically playing.
Config.audio.pauseOnFadeToZero
boolean
default:"true"
When true, tracks faded to zero volume are paused automatically.
Config.audio.pauseOnFadeToZero = false;

Config.audio.preloadMetadata

Type: booleanDefault: trueControls whether the audio subsystem attempts to preload track metadata (duration, codec info, etc.) at startup. Disabling this is rarely necessary.
Config.audio.preloadMetadata
boolean
default:"true"
When true, track metadata is eagerly preloaded for faster playback.
It is unlikely you will ever need to set this to false.
Config.audio.preloadMetadata = false;

Config.history.controls

Type: booleanDefault: trueDetermines whether the history navigation controls (Backward, Jump To, and Forward buttons) are shown in the UI bar.
Config.history.controls
boolean
default:"true"
When false, the history buttons are removed from the UI bar. Must be false when Config.history.maxStates is 1.
Config.history.controls = false;

Config.history.disableDeltas

Type: booleanDefault: falseDetermines whether history states are stored as delta-encoded diffs (false) or as full moment snapshots (true). Delta encoding is the default and is strongly recommended for most projects.
Config.history.disableDeltas
boolean
default:"false"
When true, full history snapshots are stored instead of diffs.
Changing this setting invalidates all saves and sessions created under the opposite value. Private class fields in JavaScript are only supported when this is true.
For the vast majority of projects, leave this at the default value of false.
// Disable delta encoding (use full snapshots)
Config.history.disableDeltas = true;

Config.history.maxStates

Type: integer numberDefault: 40Sets the maximum number of moments the history is allowed to hold. Once exceeded, the oldest moments are dropped. Must be a positive integer.
Config.history.maxStates
number
default:"40"
Positive integer. When set to 1, Config.history.controls is automatically forced to false.
For game-oriented projects, a value of 1 is strongly recommended.
// Recommended for games — single-moment history
Config.history.maxStates = 1;

// Allow 25 moments
Config.history.maxStates = 25;

Config.macros.maxLoopIterations

Type: integer numberDefault: 1000Sets the maximum number of iterations permitted for <<for>> macro conditional loops before they are terminated with an error. This guard prevents runaway loops from hanging the browser.
Config.macros.maxLoopIterations
number
default:"1000"
Must be a positive integer. Throws RangeError otherwise.
// Raise the ceiling to 5000 iterations
Config.macros.maxLoopIterations = 5000;

Config.macros.typeSkipKey

Type: stringDefault: " " (space)Sets the KeyboardEvent.key value that causes a running <<type>> macro to immediately finish typing its content.
Config.macros.typeSkipKey
string
default:" "
Any valid KeyboardEvent.key string value.
// Change the skip key to Control (Ctrl)
Config.macros.typeSkipKey = 'Control';

Config.macros.typeVisitedPassages

Type: booleanDefault: trueDetermines whether the <<type>> macro animates text on previously visited passages. When false, text on revisited passages appears instantly.
Config.macros.typeVisitedPassages
boolean
default:"true"
When false, <<type>> skips the animation on passages already in the history.
Config.macros.typeVisitedPassages = false;

Config.passages.displayTitles

Type: booleanDefault: falseDetermines whether the current passage name is appended to the story name in the browser tab title bar.
Config.passages.displayTitles
boolean
default:"false"
When true, the title bar shows "Story Name: Passage Name".
Config.passages.displayTitles = true;

Config.passages.nobr

Type: booleanDefault: falseWhen enabled, strips leading/trailing newlines from every rendered passage and collapses internal newline sequences into single spaces. Equivalent to tagging every passage with nobr.
Config.passages.nobr
boolean
default:"false"
Does not affect script- or stylesheet-tagged passages or Story JavaScript/CSS sections.
Config.passages.nobr = true;

Config.passages.onProcess

Type: FunctionDefault: noneA callback invoked each time <Passage>.processText() is called, enabling custom text transformations. The function receives an abbreviated passage object with name, tags, and text properties. Its return value replaces the passage text.
Config.passages.onProcess
Function
Receives { name, tags, text }. Must return the post-processed text string. Called before nobr processing. Must be a function, null, or undefined.
// Replace every instance of "cat" with "dog"
Config.passages.onProcess = (p) => p.text.replace(/\bcat(s?)\b/g, 'dog$1');

Config.passages.start

Type: stringDefault: user-selected (Twine 2) / "Start" (Twine 1/Twee)Sets the name of the very first passage displayed when the story loads.
Config.passages.start
string
Must be a string, null, or undefined. Throws TypeError otherwise.
Config.passages.start = 'That Other Starting Passage';

Config.passages.transitionOut

Type: string | integer numberDefault: noneEnables outgoing passage transition animations. Accepts either a CSS property name (the element is removed when that transition ends) or an integer millisecond delay (the element is removed after that many ms). Requires corresponding CSS styles.
Config.passages.transitionOut
string | number
String: CSS property name to watch. Integer: millisecond delay. Must be a string, non-negative integer, null, or undefined.
// Remove the outgoing element when its opacity transition ends
Config.passages.transitionOut = 'opacity';

Config.saves.descriptions

Type: FunctionDefault: noneSets a callback that generates save descriptions. When unset, a brief default description is used. The callback receives the save type and should return a truthy string (used as the description) or a falsy value (falls back to the default).
Config.saves.descriptions
Function
Receives saveType: Save.Type. Return a string or falsy value. Must be a function, null, or undefined.
// Use the current passage name as the description
Config.saves.descriptions = (saveType) => passage();

// Include the turn count for all save types
Config.saves.descriptions = (saveType) => {
  const base = `(Turn ${State.turns})`;
  switch (saveType) {
    case Save.Type.Auto: return `${base} Auto save…`;
    case Save.Type.Disk: return `${base} Disk save…`;
    case Save.Type.Slot: return `${base} Slot save…`;
  }
};

Config.saves.id

Type: stringDefault: slugified story nameSets the storage ID used to namespace saves for this story. Override this when multiple stories might produce the same slug.
Config.saves.id
string
Must be a non-empty string. Throws TypeError otherwise.
Config.saves.id = 'a-big-huge-story-part-1';

Config.saves.isAllowed

Type: FunctionDefault: noneControls whether saving is permitted in the current context. When unset, saves are always allowed. The callback receives the save type; returning a truthy value allows the save.
Config.saves.isAllowed
Function
Receives saveType: Save.Type. Return truthy to allow, falsy to disallow. Must be a function, null, or undefined.
// Disallow saves on passages tagged with "menu"
Config.saves.isAllowed = (saveType) => !tags().includes('menu');

// Auto saves only on "autosave"-tagged passages; other types unrestricted
Config.saves.isAllowed = (saveType) => {
  if (saveType === Save.Type.Auto) {
    return tags().includes('autosave');
  }
  return true;
};

Config.saves.maxAutoSaves

Type: integer numberDefault: 0Sets the maximum number of auto saves. A value of 0 disables auto saves entirely. An auto save is attempted each turn by default, so pairing this with Config.saves.isAllowed is recommended.
Config.saves.maxAutoSaves
number
default:"0"
Integer in the range 0Save.MAX_INDEX + 1. Throws TypeError or RangeError otherwise.
Browser-based storage is limited. A range of 1–10 is suggested.
Config.saves.maxAutoSaves = 3;

Config.saves.maxSlotSaves

Type: integer numberDefault: 8Sets the maximum number of manual slot saves. A value of 0 disables slot saves.
Config.saves.maxSlotSaves
number
default:"8"
Integer in the range 0Save.MAX_INDEX + 1. Throws TypeError or RangeError otherwise.
Browser-based storage is limited. A range of 1–10 is suggested.
Config.saves.maxSlotSaves = 4;

Config.saves.metadata

Type: FunctionDefault: noneAttaches a metadata property to every save. The callback is invoked at save time and receives the save type; its return value (a JSON-serializable Object) is stored as save metadata.
Config.saves.metadata
Function
Receives saveType: Save.Type. Must return a JSON-serializable Object. Must be a function, null, or undefined.
Config.saves.metadata = (saveType) => {
  const sv = State.variables;
  return {
    party : sv.party, // e.g., ['Celes', 'Locke']
    gold  : sv.gold
  };
};

Config.saves.version

Type: anyDefault: noneSets the version property on all saves. Primarily useful for upgrading stale saves via the Save.onLoad API. An integer value is strongly recommended.
Config.saves.version
any
Any value. An integer is strongly recommended.
// Strongly recommended: integer version
Config.saves.version = 3;

Config.ui.stowBarInitially

Type: boolean | integer numberDefault: 800Controls whether the UI bar (sidebar) starts in the stowed (closed) state. A boolean always/never stows it; an integer stows it when the viewport width (in pixels) is less than or equal to that value.
Config.ui.stowBarInitially
boolean | number
default:"800"
true — always stow. false — never stow. Non-negative integer — stow when viewport ≤ that many pixels. Throws TypeError otherwise.
// Always start stowed
Config.ui.stowBarInitially = true;

// Never start stowed
Config.ui.stowBarInitially = false;

// Stow when viewport is 800px or less (default)
Config.ui.stowBarInitially = 800;

Config.ui.updateStoryElements

Type: booleanDefault: trueDetermines whether the special UI bar passages (StoryDisplayTitle, StoryBanner, StorySubtitle, StoryAuthor, StoryCaption, StoryMenu) are re-rendered on every passage navigation.
Config.ui.updateStoryElements
boolean
default:"true"
When false, those UI bar elements are rendered once and remain static.
StoryTitle is intentionally excluded from updates because Tea uses it as a key for storage and saves. Use StoryDisplayTitle for a dynamic title.
Config.ui.updateStoryElements = false;

Build docs developers (and LLMs) love