@austinheller/choicelab
v3.4.4
Published
Create your own interactive stories
Downloads
84
Readme
Choicelab
This repo manages the source files for the Choicelab engine. If you actually want to create a Choicelab project, use the Choicelab starter.
Engine source reference
actions.js
Provides a hook for registering new actions in the engine.
assets/assets.js
Loads any assets used in a scene -- e.g. non-HTML media like images, audio, or video.
Note that this file doesn't figure out what files need to be loaded, or how to load them. It's on the actions to do that. This file just says, Go through this scene. Anything with a load function, run it. And when everything in the scene says it's done loading, tell the scene it can play.
assets/preload.js
Determines whether Choicelab should preload scene assets in advance. By default, Choicelab preloads everything, like buffering a video on a conventional web page. But the preloader can be set to only load a certain number of scenes in advance of the current one.
events.js
Establishes a number of events used by the engine to fire functions at specific points. The complete list is in the file, but a few include:
- Scenes are parsed, but scene preloaders haven't finished
- The engine has parsed all scenes, the scene preloader is finished, and the story is ready to play
- A scene is paused
- A new scene starts
- The current scene ends
- Inputs are submitted
files.js
Loads the start.path
file stored in the project's /scenes
folder, and any other .path
files referenced in goto
properties.
html/components.js
Provides pre-built controls that would be kind of annoying for a project creator to manage, including:
- Play/pause button
- Reset button
- Closed caption button and text box
html/elements.js
This file does two things:
- Takes the text in a scene and passes it to
getContentNodeList
to convert it into a collection of HTML nodes. - Provides hooks for rendering and removing all scene content in the DOM. Consistently provides appear and clear classes for elements, and marks actions as complete so the playback engine can keep moving forward.
html/text.js
Takes a block of text, and converts it into a collection of HTML nodes.
The tricky thing that this file does is convert emphasis marks in text (bold, italics, and spans) into nested HTML that can be safely inserted into an element. Frankly, it's kind of a mess, but it does its job effectively and quickly, and it shouldn't be too hard to expand it to include other single-line elements in the future.
init.js
Creates two objects: Choicelab
(the engine), and choicelab
(the user's variables). With the former, initializes a bunch of properties that the engine will fill in later.
logging.js
Mostly a wrapper for console
with a twist: it also can spit out the logs on the front-end, so writers don't have to open dev tools (or know what that is).
media/audio.js
A low-level library for loading, playing, and pausing audio. Used by the audio
and response
actions.
media/video.js
A low-level library for loading, playing, and pausing video. Used by the video
action.
parser.js
Parses the contents of a .path
file.
This one is pretty ugly, but it basically works like this:
- Demarcate all scenes.
- Within a scene, differentiate any Choicelab actions from blobs of plain text.
- If there are timing flags, assign the corresponding timing values to each action or blob.
- If there are any inputs, collect them into an object for use by an input action later.
- If there are any actions, create action calls out of them.
- Add this newly processed group of scenes to the global scenes object (
Choicelab.scenes
).
playback.js
Chooses what scene to start from when a user presses start (based on whether they're new or returning), and the order of future scenes (based on the current file and the last scene played). This file also evaluates rules attached to a scene to figure out if it should play or be skipped.
rules.js
Parses a set of rules, written in plain text in a scene's header.
This file is a holdover from an early version of the engine that was entirely reliant on rules for determining logic. As such, it's somewhat more rigorous than the explanation in the sample project — it can do a lot of evaluations on strings, numbers, and even arrays — but the heavy-duty stuff hasn't been tested in a while. This parser is probably the engine component that would most benefit from automated testing, if we ever get to that point.
scene.js
Loads a scene into the DOM, firing actions and HTML content at the specific times defined in the scene.
For the most part, the work of knowing what to do with, say, an audio action comes down to the action code, not this file. But it does handle two very important things:
- Making actions and HTML content appear at specific times is basically a matter of using JavaScript's
setTimeout
function. But because scenes can be paused, the scene player resets the timers on every action when a scene pauses and resumes. - Choicelab doesn't require scene authors to explicitly set a length for each scene. It just knows when to end one scene and move on to the next once all actions have played. This file is responsible for doing that heavy lifting.
scene/scene.end.js
Ends the scene by clearing all actions from screen, and telling Choicelab to look for the next scene. Only fires when all actions in the scene announce that they are done.
scene/scene.utils.js
Various functions used by the scene player. The big one is setting audio timing: Choicelab can either play audio files simultaneously, or one after another, and time onscreen elements based on which approach.
session.js
A session is an instance of a Choicelab story. What this file does, in approximate order:
- Create a variable registry for any scene variables.
- Parse all of the .path files in the
/scenes
folder. - Establish that we need to save the variable registry and current file and scene in local storage.
- Load an existing variable registry and last-viewed file/scene, if local storage has it.
- Identify what file and scene we should start from. (The first scene in
start.path
if we're new; the last-viewed file and scene if we're returning.) - Preload project media, if there is any.
This file loads from index.js
, which is Choicelab's entry point. If you follow along from there:
- Choicelab checks if the HTML page wants to use it at all. It does this by querying for an element with a
data-stage
attribute. - Assuming the page does, Choicelab creates a new session.
utils.js
A grab-bag of functions that don't correlate to any particular component but are used throughout the engine. That includes stuff like parsing timing values (e.g. "0.3s"
becomes 300ms
), setting the state (if a story is loading, playing, or paused), or getting a particular scene from Choicelab.scenes
.