CYOA Choose your own adventure - ThePix/QuestJS GitHub Wiki

This is currently under development. What is written here is unlikely to change, but the system is still untested except in its most basic form.

Why Use QuestJS CYOA?

A CYOA, or "Choose your own adventure" is composed of a series of text passages that the user navigates by clicking either a link in the text itself or a list of options after the text. Each passage might have between one and four options to choose from, making the process interactive - the user can choose the course of the story.

CYOA games can be thought of as navigating time. Games are composed of a branching series of events, and the player experiences those events over time.

Parser games, on the other hand, can be thought of as navigating space. Games are composed for a series of locations, and the player explores the geography of the game.

There are a lot of options for authors wanting to write a CYOA-style game, such as Squiffy and Twine, and if you want a simple time-based game, these are great; I would not recommend QuestJS, you are better served by using a simpler system.

But what if you want to create a CYOA game with a world model? That is, the user makes a selection from a list, and moves to the next event, in a flow of time, but at the same time there is a world geography with items that have specific and persistent locations. This is where QuestJS CYOA excels. While you can do this with other systems, as far as I know QuestJS CYOA is the only one to have it built-in.

By the way, if you want to have no text input, but still want the side panes, with the compass rose and item interactions, you are better off creating a parser game, but with the command line disabled. See here for details.

Setting up

By default, the CYOA library is not included in a Quest 6 game (though the file is present). The first step, then, is to tell Quest to include this library. To do that, add this line to your settings.js file (and indeed all options that start "settings" should go in that file):

settings.libraries.push('cyoa')

Creating Choices

Here is a very quick game to illustrate how to use QuestJS in this way. As we have a world model, we have a player object that moves around within it. The "loc" attribute should be set to the first choice.

"use strict"

createItem("me", PLAYER(), {
  loc:"lounge",
})

Here is our first choice. Use the "createChoice" function to create your choices (behind the scenes it uses "createRoom"). The "desc" attribute is the text the player will see.

createChoice("lounge", {
  desc:"The lounge is boring, you wonder where to go.",
  c1:new Option("Go to dining room"),
  c2:new Option("kitchen", {alias:'Go the other way'}),
  c3:new Option("Just leave"),
})

The "c1", "c2" and "c3" attributes are the options that will be presented (behind the scenes, these are actually Exit objects). There will be presented to the player in numerical order, whatever order you put them in here. You are limited to nine (and frankly more than five choices is probably too many for the user).

In "c2" you can see that an "alias" attribute is set; the name will be set to "kitchen". For "c1", the alias will be set to "Go to dining room", while the name will be derived from that by stripping out all non-alphanumeric characters (and that includes accented characters), and turning into lower case, so in the case "gotodiningroom". Every name must be unique, so you cannot have another room called "Goto Dining Room" as that would have the same name attribute.

You can also add options using the "options" array. They will be assigned "c1", "c2", etc in order.

createChoice("Go to dining room", {
  desc:"You walk into the dining room. Much better!",
  options:[
    new Option("kitchen", {alias:'Go the other way'}),
    new Option("Just leave"),
  ]
})

Links in the text

You can also embed options in the text itself. This version of the lounge has the "c3" option flags as not to be listed. It is, however, referenced in the description, using the "option" text processor directive.

createChoice("lounge", {
  desc:"The lounge is boring, you wonder where to go. How about {option:c3:just leaving the house}.",
  c1:new Option("Go to dining room"),
  c2:new Option("kitchen", {alias:'Go the other way'}),
  c3:new Option("Just leave", {doNotList:true}),
})

It you are intending to have all your options in the text, rather than listed, across the entire game you can just set settings.includeChoices = false in settings.js; you then can omit the "doNotList".

createChoice("lounge", {
  desc:"The lounge is boring, you wonder where to go. The {option:c2} or the {option:c1:dining room} perhaps?. How about {option:c3:just leaving the house}.",
  c1:new Option("Go to dining room"),
  c2:new Option("kitchen", {alias:'Go the other way'}),
  c3:new Option("Just leave"),
})

Note that the first "option" directive has no text; it will just use the alias for the Option object

Basic options

Most of the styling options discussed elsewhere - particular those using CSS - still apply.

Name Type Default Comment
clearScreenOnRoomEnter Boolean false Set to true to clear the screen each time the player makes a choice
includeChoices Boolean true Set to false to stop having the options listed after the passage is displayed
includeHeadings Boolean false Set to true to have the alias of the passage shown as a title
includeObjects Boolean false Set to true to have a list of items at the current location displayed