@aibex/botscripten

Craft rich bot conversations using the Twine/Twee format

Usage no npm install needed!

<script type="module">
  import aibexBotscripten from 'https://cdn.skypack.dev/@aibex/botscripten';
</script>

README

Botscripten

A modified Trialogue/Twine engine specifically for Building, Testing, and Exporting conversations as Minimal HTML5

Botscripten logo

Story Format Version npm Twine Version CircleCI Dependabot Status

Upgrading? Check the Changelog

Botscripten is a chat-style Twine Story Fromat based on Trialogue and its predecessors. Unlike other Twine sources, Botscripten is optimized for an external runtime. That is, while you can use Botscripten for Interactive Fiction, that's not this story format's intent.

Botscripten is also available as an npm parser, able to handle Passage-specific features found in the Botscripten format. It's available via npm install @aibex/botscripten or yarn add @aibex/botscripten.

✅ You want to use Twine to author complex branching dialogue
✅ You want a conversation format (think chatbot)
✅ You want simple built-in testing to step through flows and get feedback
✅ You want a minimal output format for an external runtime

If "yes", then Botscripten is worth looking into.

🔮 A Sample Conversation

Botscripten comes with two distinct flavors: An Interactive Output for testing and stepping through conversations in a pseudo chat interface based on the Trialogue code, and built in proofing version. External JavaScript keeps the output file small, making it easy to use the pure HTML in other systems.

🚀 Setup and Your First "Chat"

Add Botscripten as a Twine Story Format

add

  1. From the Twine menu, select Formats
  2. Then, select the Add a New Format tab
  3. Paste https://cdn.jsdelivr.net/gh/aibexhq/botscripten@master/dist/Twine2/Botscripten/format.js
  4. Click Add

Once you've done this, you will have access to the Botscripten story format in Twine. If you're migrating, be sure to check the Changelog for a migration guide.

Upgrading is as simple as removing your old Botscripten and adding the new URL above. Any stories you publish will automatically work in the new format.

(If you are interested in the next version of botscripten, you may use https://cdn.jsdelivr.net/gh/aibexhq/botscripten@next/dist/Twine2/Botscripten/format.js as your story format URL)

Create your first chat story

create a chat

  1. Create a story in the Twine editor.
  2. Set your story format to Botscripten
  3. Edit the start passage to include:
    • Title (e.g. start)
    • Passage text (e.g. "Hi 👋")
    • One or more links (e.g. [[What's your name?]])
    • Speaker tag (e.g. speaker-bot). This will display the speaker's name (in this case bot) in standalone viewer
  4. Edit the newly created passage(s) to include:
    • Passage text (e.g. "My name is Bot")
    • One or more links (e.g. [[Back to start->start]])
    • Speaker tag (e.g. speaker-bot)
  5. Hit Play to test the result

🏷 Botscripten Tags

Botscripten is designed to work exclusively with Twine's tag system. That means no code in your conversation nodes. This is important because behind the scenes, many other Twine formats convert Passages containing <% ... %> into JavaScript code, defeating the goal of portability.

The following passage tags are supported by Botscripten. It is assumed that anyone consuming a Botscripten formatted Twine story will also support these tags.

tag explanation
oneline By default, chat bots will display one message per line, similar to an SMS conversation. If you'd like to send content as a paragraph, use the oneline tag. The entire Twine node will then be treated as a single message.
speaker-* (prefix) The speaker-* tag describes "who" the message is from. For example, a tag of speaker-bob would imply the message should come from bob. The speaker tag is arbitrary, but should be consistent to identify "who" is talking.
wait Adding wait will prevent the conversation from automatically advancing. Automatic advancement happens when there is exactly 1 link to follow, and the wait tag is not set. The most common reason for wait is to present some form of "continue" to the user.

To maintain compatibility with the Twee 3 Specification, the tags script and stylesheet should never be used.

🙈 Comments in Botscripten

The Botscripten story format allows for simple comments. Lines beginning with an octothorpe # are removed from chat lines when playing a story, but remain in the source code for external tools.

If you'd like to place a comment across multiple lines, you can use a triple-octothorpe ###. Everything until the next ### will be considered a comment.

The following are all comments in Botscripten:

# I'm a comment, because I have a "#" at the start of the line

# It can
# cover
# multiple lines

###
You can also use a triple # to denote a block
and everything is ommitted until the next
triple #
###

###
If you need a literal #, you can escape it with a
backslash like this: \###
###

🗂 Recipies

Below are some common challenges & solutions to writing Twine scripts in Botscripten format

"Special" Comments (Directives)

If you look at the sample, you'll notice many of the comments contain an @yaml statement. While Botscripten (viewer) doesn't care about these items (they're comments after all), any other system parsing the Twine file can read these statements out of the comment blocks. Additionally, if you use botscripen's npm engine, you'll have access to these special comments as part of the story parsing.

These special comments are called Directives and they consist of the comment identifier (# or ###) immediatly followed by @ and a word. These are all Directives:

#@doAThing

#@make party

###@sql
INSERT INTO winners (name, time) VALUES ('you', NOW())
###

Anyone parsing Botscripten Twine files can assume that the regular expressions /^#@([\S]+)(.*)/g (inline) and /^###@([\S]+)([\s\S]*?)###/gm (block) will match and extract the directive and the remainder of the comment.

For consistency between systems, directives should be run when a Passage is parsed, but before any tag behavior (such as wait or speaker-* are applied) This allows directives to form opinions about the Passage and it's output before rendering occurs.

There is no set definition for directives, as adding a directive to Botscripten would require every external parser to also support it. This is also why Botscripten is so light- there's almost no parsing being done of the individual Passages.

But if you'd like some examples, these are some directives we think are pretty useful and are worth implementing in your own conversation engine:

  • #@set <name> <value> - A directive that sets a local variable <name> to value <value> within the conversation
  • #@increment <name> <amount> - A directive to increment a local variable <name> by amount <amount>
  • #@end - A directive that tells the system to end a conversation (don't put any [[links]] in this passage obviously!)

Conditional Branching (cycles, etc)

Since Botscripten does not maintain a concept of state, nor have a way to script items such as cycling or conditional links, you should present all possible branches using the [[link]] syntax. This will allow you to view all permutations in Botscripten when testing conversations locally.

Conditional branching can then be implemented as a Directive. This gives you control outside of the Twine environment as to which link is followed under what conditions. We're partial to a ###@next ... ### directive, but feel free to create your own!

Scripting Directives in Botscripten

If you absolutely want to handle Directives in Botscripten, you can do so by selecting Edit Story JavaScript in Twine, and registering a handler for your directive. For example, this logs all @log directives' content to the developer tools console.

story.directive("@log", function (info, rendered, passage, story) {
  console.log("LOG data from " + passage.id);
  console.log("Directive contained: " + info);
  return rendered; // return the original (or altered) output
});

Directives are evaluated after the Passage is parsed, but before any tag behaviors are applied.

📖 Node Module Documentation

Most individuals are interested in writing for the Botscripten format, not consuming it. If you are looking to read Botscripten's Twine HTML files, and are also in a node.js environment, you can install Botscripten over npm/yarn and access the parser. Parsing a valid Botscripten HTML file will yield the following:

import botscripten from "@aibex/botscripten";
import fs from "fs";

const story = botscripten(fs.readFileSync("your/file.html").toString());

story = {
  name: "", // story name
  start: null, // name ID of starting story node
  startId: null, // numeric ID of starting story node
  creator: "", // creator of story file
  creatorVersion: "", // version of creator used
  ifid: "", // IFID - Interactive Fiction ID
  zoom: "", // Twine Zoom Level
  format: "", // Story Format (Botscripten)
  formatVersion: "", // Version of Botscripten used
  options: "", // Twine options
  tags: [
    {
      // A collection of tags in the following format...
      name: "", // Tag name
      color: "", // Tag color in Twine
    },
    // ...
  ],
  passages: {
    // A collection of passages in the following format...
    // pid is the passage's numeric ID
    [pid]: {
      pid: null, // The passage's numeric ID
      name: "", // The passage name
      tags: [], // An array of tags for this passage
      directives: [
        {
          // An array of Botscripten directives in the following format...
          name: "", // The directive name
          content: "", // The content in the directive, minus the name
        },
        // ...
      ],
      links: [
        {
          // Links discovered in the passage in the following format...
          display: "", // The display text for a given link
          target: "", // The destination Passage's name
        },
        // ...
      ],
      position: "", // The Twine position of this passage
      size: "", // The Twine size of this passage
      content: "", // The passage content minus links, comments, and directives
    },
    // ...
  },
  passageIndex: {
    [name]: id, // A lookup index of [Passage Name]: passageNumericId
    //...
  },
};

⚠️ Why would you use Botscripten over (Insert Twine Format)?

First off, every Twine format I've worked with is amazing and super thougtful. If your goal is to create interactive fiction, self-contained tutorials, etc, you should just use Trialogue, Harlowe, or Sugarcube. However, if you're using Twine as a conversation editor (and you are more interested in the tw-passagedata blocks and the data structure behind Twine) Botscripten may be for you.

  • Zero story.* Calls To be as portable as possible, No template tags may be used. That means your code cannot contain the <% ... %> blocks seen in Trialogue/Paloma. These tags are incredibly difficult to parse/lex, because they assume a JavaScript environmemt at runtime. And since you don't know where your Twine file is going to run, you must decouple the programming from the data.
  • Tags drive behavior Because of that first restriction, we need a way to perform actions within Botscripten. Thankfully, Twine's Tag system is up to the task. We strive to keep the tag count low to minimize the number of reserved tags in the system.
  • Dev Experience Iterating on Twine templates is hard. A lot of time was spent to make the dev experience as simple as (1) put tweego in your executable path, and (2) type npm run dev.
  • Multiple Formats Botscripten provides two syncrhonized formats from the same repository. Features in the proofing / html5-min version will also show up simultaneously in the Interactive one.

Developing on Botscripten

Local Development

  1. Acquire tweego and place it in your development path.
  2. Check out this repository
  3. run npm install to install your dependencies
  4. run npm run dev to start developing using the twee files in the examples folder
  • Examples are available under http://localhost:3000
  • TEST_Botscripten can be installed in Twine from http://localhost:3001/Botscripten
  • When you are done developing/testing, be sure to remove the TEST_Botscripten format. If you forget, just restart the dev server so Twine doesn't complain every time you start it up

For local testing convienence, we have a npm run tweego command. It ensures that Botscripten is in the tweego path before performing a build.

As an example, the sample document was converted from Twine to Twee using the command npm run tweego -- -d ./stories/sample.html -o ./examples/sample.twee. (You may need to manually edit the html file to set the format to "Botscripten")

Acknowledgements

Botscripten would not be possible without the amazing work of Philo van Kemenade for imagining Twine as a conversational tool, M. C. DeMarco who reimagined the original "Jonah" format for Twine 2, and Chris Klimas creator and current maintainer of Twine.

Botscripten is sponsored by Aibex. Love your career.