SugarCube v2 Documentation

repository·develop·Indexed 42 days ago

https://github.com/tmedwards/sugarcube-2

A free, open-source story format for the Twine/Twee game engine designed for creating interactive fiction. Includes documentation on the Config object for engine behavior, the Dialog API for creating UI elements, build instructions for version 2.38.0-alpha.10, and guidelines for localization.

Tokens
106K
Snippets
381
Records
470
Agent score
52%

What's inside SugarCube

  1. Use the Setting API to manage user settings

    develop

    The Setting API manages the built-in Settings dialog and the global settings object.

    CRITICAL: All Setting API method calls must be placed within your project's JavaScript section (Twine 2: Story JavaScript; Twine 1/Twee: a script-tagged passage) to function correctly.

  2. SugarCube v2 Core Documentation Overview

    develop

    SugarCube v2 is a story format for Twine that provides a robust set of tools for interactive fiction development. The core documentation covers several key areas:

    • Markup: Syntax for naked variables, links, images, headings, lists, and more.
    • TwineScript: The scripting language used for variables, supported types, expressions, and operators.
    • Macros: A wide array of specialized commands for logic, display, interaction, DOM manipulation, and audio.
    • Functions & Methods: Built-in utility functions and extended methods for Arrays, Strings, Math, and jQuery.
    • Special Names: Reserved passage names (like StoryInit), code tags (like stylesheet or widget), and special variable names (like $, Config, and Engine).
    • Styling: Guidance on CSS usage, passage conversions, and built-in stylesheets.
    • HTML: Integration of HTML and SVG within the engine.
  3. What is Test Mode in SugarCube?

    develop

    In Test Mode, SugarCube wraps macros and certain non-macro markup (like link and image markup) in additional HTML elements called "debug views" (or "views").

    These views provide onscreen feedback by making the underlying code visible. Hovering over a view generally exposes additional information about the code it represents.

    Warning: Because Test Mode injects additional HTML elements, some nested markup and CSS selectors may break. This behavior is exclusive to Test Mode and should not be relied upon for production builds.

  4. What is an AudioRunner and how to use it

    develop

    An AudioRunner is an abstraction used to perform actions on multiple audio tracks simultaneously. It provides a unified interface to control playback, volume, and events for a selection of tracks. Many AudioRunner methods return the AudioRunner instance itself, allowing for method chaining.

    // Example of chaining methods on an AudioRunner
    someTracks.volume(0.5).loop(true).play();
  5. Understanding the Startup Sequence and StoryInit

    develop

    Every time a story starts or restarts (including browser refreshes), it undergoes a startup sequence. This sequence occurs before a playthrough session is restored or the starting passage is run.

    Startup Order:

    1. CSS, JavaScript, and Widget sections are processed.
    2. init-tagged passages and the StoryInit special passage are processed.
    3. Either the existing playthrough session is restored or the starting passage is run.

    Note on StoryInit execution:

    Even if a playthrough session is restored, StoryInit is still executed. However, because the restored state replaces the current state, any changes made to story variables (e.g., <<set $x to 1>>) in StoryInit will appear to have no effect.

    To perform setup tasks that persist regardless of whether a save is loaded, use the setup object, as it is not part of the story state.

    ```twee
    :: StoryInit
    <<set $x to 0>>
    <<set setup.y to 1>>
    
    :: Start
    $$x is <<if def $x>> $x <<else>> undefined <</if>>
    setup.y is <<if def setup.y>> <<= setup.y>> <<else>> undefined <</if>>

    In this example, setup.y will correctly display 1 even after a save is loaded, because setup is not part of the state being replaced.

  6. Use SugarCube Array extension methods

    develop
    SugarCube extends the standard JavaScript Array prototype with several utility methods designed for easier manipulation of collections within stories. These methods include specialized concatenation, counting, and deletion operations that are not available in standard JavaScript.
  7. Understand the behavior of the <<goto>> macro

    develop

    In Harlowe, (goto:) terminates the rendering of the current passage. In SugarCube, <<goto>> does not terminate the passage. Any code written below the <<goto>> macro will still execute and cause side effects.

    Example of side effect risk:

    :: some passage
    <<set $count to 0>>
    <<goto "next":>
    <<set $count += 1>>
    
    :: next
    $count /* Result is 1, not 0 */
    <<goto "next">
    <<set $count += 1>>
  8. How <<do>> and <<redo>> work together for dynamic updates

    develop

    The <<do>> ... <</do>> macro displays its contents and listens for <<redo>> commands to update itself dynamically without a full passage transition.

    Arguments

    • tag tags: (optional) A space-separated list of tags used to filter which <<redo>> commands affect this specific <<do>> block.
    • element tag: (optional) The HTML element to use as the container (e.g., div, span). Defaults to span.

    Usage Pattern

    1. Wrap a dynamic area in <<do>>.
    2. Use <<redo>> (optionally with tags) to trigger an update to that area.

    Example: Filtering updates

    ''Foo:'' <<do tag "foo foobar"><<= ["fee", "fie", "foe", "fum"].random()><</do>>
    ''Bar:'' <<do tag "bar foobar"><<= ["alfa", "bravo", "charlie", "delta"].random()><</do>>
    
    <<link "Update foo">">
    	<<redo "foo">
    <</link>>
    
    <<link "Update foo & bar (1)">
    	<<redo "foo bar">
    <</link>>
    <<set $money to 10>>
    
    ''Money:'' <<do>>$money<</do>>
    
    <<link "Update money display">">
    	<<set $money += 10>>
    	<<redo>>
    <</link>>
  9. Configure the Story Title and Display Title

    develop

    SugarCube distinguishes between the internal storage title and the visible display title:

    • StoryTitle: Used to create the storage ID for player data (temporary and persistent). This must be plain text and should contain no code, markup, or macros.
    • StoryDisplayTitle: A code passage used to set the visible title in the browser's titlebar and the UI bar (#story-title). Use this if your desired title requires code, markup, or macros.
  10. How Playthrough Sessions prevent progress loss

    develop

    A playthrough session is a temporary, automatic storage mechanism that uses the browser's sessionStorage. It is distinct from manual or auto saves.

    Lifecycle:

    • Storage: SugarCube automatically stores the current playthrough state to sessionStorage whenever a new moment is created.
    • Restoration: If the browser reloads the page (due to a refresh, back/forward navigation, or the mobile browser unloading the tab in the background), SugarCube checks for a playthrough session and restores it automatically.
    • Bypassing: If the story is restarted using built-in methods like UI.restart() or Engine.restart(), the playthrough session is not restored.

    This system ensures that accidental refreshes or background unloads do not cause players to lose their progress.

  11. What happens when a save is loaded

    develop

    When a save (or a playthrough session) is loaded, the incoming state replaces the current state in its entirety. The previous state is not merged or combined with the new state; it is completely discarded.

    Important Implication: If you add new variables to StoryInit in a newer version of your story, loading an old save will result in those new variables being undefined, because they did not exist in the state captured by the old save.

    ```twee
    :: StoryInit
    <<set $x to 0>>
    <<set $y to 1>>
    
    :: Start
    $$x is <<if def $x>> $x <<else>> undefined <</if>>
    $$y is <<if def $y>> $y <<else>> undefined <</if>>

    If you load a save created before $y was added to StoryInit, $y will be undefined.