If you haven’t installed Fractive yet, click here
Create a new story project:
fractive create path/to/my/story
Launch your favorite code editor – I particularly like VS Code – and open the default story text file, source/text.md.
You’ll see the following:
{{Start}}
Your story begins here.
{{Start}} marks the beginning of a new section, called “Start”. Your story will contain many sections, each of which must be named uniquely. The “Start” section is the one your story will start on when it’s
first launched.
Add a second section:
{{Elsewhere}}
This is a different section.
Now add a link to the second section from the first section. Story text is written in Markdown , so you can use Markdown link syntax:
{{Start}}
Your story begins here.
[Go elsewhere]({@Elsewhere})
The link URL {@Elsewhere} is a macro pointing to the section called “Elsewhere”. Macros are enclosed in {} and have a leading metacharacter indicating the macro’s type. In this
case we used @ which indicates a section macro; clicking this link will take the player to the named section.
Build the story project:
fractive compile path/to/my/story
Navigate to path/to/my/story/build and open up the index.html in a web browser to run your story!
You now know enough to create interactive fiction stories both simple and complex. However, Fractive is capable of much more than this! You can browse the built-in examples to see other features by doing:
fractive examples
Each folder in examples is its own Fractive project, which you’ll learn about in the next section.
Fractive is built on Node.js , so you’ll need to install that if you don’t already have it. (Fractive currently targets version 8.9.0 LTS.)
Once Node.js is installed, open a command line and install Fractive:
npm install -g fractive
Fractive is now globally available on the command line. Type fractive to see usage instructions.
Story text is written in Markdown (.md) files, and game logic is written in Javascript (.js) files. These files, plus any additional assets (images, etc.) are kept together in a Fractive project. You can create a new project like this:
fractive create path/to/my/story
In the new project folder you’ll see this default structure:
story
|- assets/
|- source/
|- fractive.json
|- template.html
The source folder contains all your Markdown (.md) and Javascript (.js) files.
The assets folder contains images, video clips, and other miscellaneous assets. Not all projects will require these.
The template.html is a formatting template for how your published story will look in the browser. See Templates for details.
Finally, the fractive.json is your project file. It contains all your project settings, like rules for where to find source files and where builds should go. If you take a peek inside, you’ll see the default
rules:
markdown: [ "source/**/*.md" ],
javascript: [ "source/**/*.js" ],
assets: [ "assets/**" ],
ignore: [],
template: "template.html",
output: "build",
This page lists all the configuration options available in the fractive.json project file.
Aside from the title, none of the project metadata is currently used, but in the future it will be displayed to the player (e.g. on a standardized title page, in an online database of Fractive stories, etc.)
"title": "My Project Title"
Specifies the name of your story. This will be shown to the player, so it should be your actual story title, not a project code name or internal name. This will also appear as the title in any OpenGraph card when this game is linked to
on social media. The page title will also be set to this if the <!--{title}--> mark is present in your template; see Templates for details.
"author": "Your Name"
Specifies who wrote the story. This could be your real name, an online nickname, a social media handle, or even a company name.
"description": "About your story"
Give a brief (one or two sentences) description of your story. This will also appear as the description in any OpenGraph card when this game is linked to on social media.
"website": "Your website"
Give an online address where players can learn more about you, find more of your stories, etc. This could be your website URL, a social media handle, or even an email address. You can also just leave it blank if you prefer.
"twitter": "@yourname"
If you specify your Twitter handle here, it will be linked in OpenGraph cards when this game is linked to on Twitter.
These options specify where in your project folder Fractive should look for different kinds of files, what should be included in a build, and what should be ignored.
These are generally globs or lists of globs.
Paths are relative to the fractive.json project file.
"markdown": [
"source/**/*.md"
]
List of globs indicating where story text (Markdown) files should be found. All files sourced by this list will be compiled as story text when you build the project.
"javascript": [
"source/**/*.js"
]
List of globs indicating where Javascript files should be found. All files sourced by this list will be combined and embedded in the output index.html when you build the project.
"assets": [
"assets/**"
]
List of globs indicating where asset files should be found. All files sourced by this list will be copied to the output location, preserving their directory structure.
"ignore": [
"assets/.DS_Store"
]
List of globs indicating files to ignore. All files sourced by this list will be ignored; they will NOT be compiled, embedded, copied, or otherwise processed.
What kinds of files should I ignore?
"template": "template.html"
Specifies the HTML template file to use for formatting the story. (To use one of Fractive’s built-in example templates, you can write the path like {examples}/basic.html.)
"output": "build"
Specifies a directory name where the final index.html and asset files will be placed when the project is built.
These options affect how source text is interpreted and rendered into the final HTML.
"aliases": [
{ "alias": "name", "replaceWith": "text", "end": "text" }
]
List of alias definitions. See Aliases for details. Note that the end property is optional and may be omitted for aliases that don’t need to use it.
"outputFormat": "prettify"
Specifies how the final HTML should be written:
prettify: Write human-readable HTML with line breaks and whitespace. This is easier to debug but takes up more disk space and bandwidth. Good for development.minify: Compact the final HTML by removing all unnecessary whitespace and symbols. This is difficult to read and debug, but is much smaller. Good for final release.This option doesn’t change how your story is displayed to the player at all, it just determines what the HTML source code looks like.
"linkTooltips": false
Specifies whether links should show a tooltip on mouseover which indicates their target location.
"linkTags": {
"external": { "html": "someCode", "prepend": false },
"inline": { "html": "someCode", "prepend": false },
"section": { "html": "someCode", "prepend": false },
"function": { "html": "someCode", "prepend": false }
}
Link tags are custom HTML snippets which can be automatically appended (or prepended) to links based on their type. The available link types are:
external links target a web URL outside of the current storyinline links expand in-place without navigating to another section using the :inline macro modifier, e.g. {$SomeVariable:inline}section links navigate to another section within the current story, e.g. {@SomeSection}function links call a Javascript function when clicked, e.g. {\#SomeFunction}Whatever HTML you specify for html will be added immediately after the end of the link, unless prepend is true, in which case it’ll be added immediately before the beginning of the link.
"includeBackButton": true
If true, the value of backButtonHTML will be inserted into the final story HTML. Where it gets inserted is determined by the location of the <!--{backButton}--> macro in the template file. If
the macro is not found, the backButtonHTML will be ignored.
"backButtonHTML": "Back"
If includeBackButton is true, this is the HTML snippet that will be inserted into the final story HTML in place of the <!--{backButton}--> macro in the template file.
"hardLineBreaks": true
If true, single line breaks in Markdown source will be replaced with <br/> in the rendered HTML source. If false, they’ll be replaced with \n, unless the line is suffixed by two or more spaces (see the
official Markdown spec for details).
"smartPunctuation": true
If true, replace straight quotes with smart quotes, – with en-dash, — with em-dash, and … with ellipsis.
If you’re not familiar with glob syntax, here are the basics:
source/text.md targets just that one filesource/*.md targets all .md files in the directory “source”source/**/*.md targets all .md files in all subdirectories of “source”, including “source” itselfsource/* targets all files of any type in “source”source/** targets all files of any type in all subdirectories of “source”, including “source” itselfFor most stories these will probably be multimedia files like images and video clips, but technically assets can be anything, even Markdown and Javascript files. Markdown files included by assets will NOT be compiled as story
text, and Javascript files included by assets will NOT be embedded in the output index.html.
Ignores are most useful when you have an assets wildcard like assets/** but then there are a few files or file types within it that you don’t want, like .DS_Store files and similar.
Another use case might be for game art. If you made your art with Photoshop and saved PSDs into an assets folder and then exported PNGs alongside them, you might want to include assets/** and then ignore assets/**/*.psd.
That way when you build the project it’ll only copy over the PNGs and leave the PSDs behind.
Link tooltips can be useful for debugging, as the tooltip will show the actual macro a link is targeting. For example, if you have a link like this:
[Go somewhere]({@SomeSection})
…then setting linkTooltips to true will allow a tooltip on that link which looks like this:
{@SomeSection}
Example projects can be found in the examples folder in your Fractive install location.
When you’re ready to share or test your story, you need to build it:
fractive compile path/to/my/story
Fractive will compile your project and spit out an index.html and assets (if any) in the output location specified in the project’s fractive.json. Simply open that index.html in a browser
to test, or upload the entire output directory to your web server to publish it to the world.
If you specify a story directory, Fractive will look for a fractive.json at that location, and use the settings it finds there to build the story. If you specify a path to a .json file, Fractive will use that as the project
file instead.
You can add logic to your Fractive stories using Javascript .
By default, new projects contain a source/script.js which you can put your custom scripting in, but you can also add new .js files and link them into your story using the scripts property in fractive.json (see Configuration for details).
Typically, you’ll create Javascript variables to remember the game state, and Javascript functions to change the game state. In your story text you can use Macros to retrieve those variables and call those functions.
Function macros are denoted by the # metacharacter and they refer to Javascript functions. For example, the macro {#Foo} refers to the Javascript function Foo(). Function macros never pass any arguments,
but in some circumstances can accept a string return value (see below).
If you put a function macro directly in the story text, the function will be called on entry into the section, and any text it returns will be inserted into the section in place of the macro.
First, create a Javascript function in any .js file that’s included in your project:
function MyFunction()
{
return "Hello, world!";
}
In your Markdown story text, include a function macro referencing this function:
{{Start}}
Here is a message from Javascript: {#MyFunction}
When the player starts this story they’ll see:
Here is a message from Javascript: Hello, world!
The text that gets displayed is the return value of MyFunction() converted to a string by MyFunction().toString().
If you put a function macro as a link destination, the function will be called when the player clicks the link.
First, create a Javascript function in any .js file that’s included in your project:
function MyFunction()
{
alert("Hello, world!");
}
In your Markdown story text, link to this function using a function macro:
{{Start}}
[Say hello]({#MyFunction})
When the player clicks the “Say hello” link, a window will pop up with the text “Hello, world!”
If you put a function macro as a link destination and add the :inline specifier, the function will be called when the player clicks the link, and the link will be replaced with any text the function returns.
First, create a Javascript function in any .js file that’s included in your project:
function MyFunction()
{
return "Hello, world!";
}
In your Markdown story text, link to this function using a function macro with the :inline specifier:
{{Start}}
Javascript says: [???]({#MyFunction:inline})
When the player starts the story, they’ll see:
Javascript says: ???
…and when they click the link “???” it’ll be replaced inline, so they’ll now see:
Javascript says: Hello, World!
The text that gets displayed is the return value of MyFunction() converted to a string by MyFunction().toString().
Variable macros are denoted by the $ metacharacter and refer to Javascript variables. For example, the macro {$Foo} refers to the Javascript variable Foo.
Variable macros placed directly into story text are expanded to their string value when the section is entered. For example, if a .js file declares a variable like this:
var Foo = "Hello, world!";
…and the story text contains a variable macro like this:
{{Start}}
Javascript says: {$Foo}
…then when the player starts the story, they’ll see:
Javascript says: Hello, world!
The text that gets displayed is the value of Foo converted to a string by Foo.toString().
Variable macros cannot currently be used as link destinations, and the compiler will spit out an error at build time if you attempt to do so.
Variable macros can be set as link destinations with the :inline specifier, in which case the link will be replaced with the value of the variable when clicked. For example, if a .js file declares a variable like this:
var Foo = "Hello, world!";
…and the story text contains a variable macro like this:
{{Start}}
[Javascript says...]({$Foo:inline})
…then when the player starts the story, they’ll see:
Javascript says...
…and when they click the “Javascript says…” link, it’ll be replaced with:
Hello, world!
The text that gets displayed is the value of Foo converted to a string by Foo.toString().
Fractive exposes some useful Javascript functions to your story scripts.
Core.BeginStory()
Begins (or restarts) the story. You don’t need to call this to start the story initially; that happens automatically. But you might call this if you wanted to implement your own “Restart Story” link.
The difference between calling this vs. calling Core.GotoSection("Start") is that this function also calls any registered OnBeginStory event handlers.
Core.GetSection("SectionName")
Gets a copy of the given section, expands its macros, registers its links, and returns an Element instance which is fully activated and ready to be displayed to the user, without actually navigating to that section. This function
is for advanced/unusual circumstances; for example, this documentation uses it to populate the table of contents in the sidebar. Normally you should just use Core.GotoSection("SectionName") instead.
Core.GotoPrevousSection()
Travel to the section we just came from. You can hook this up to a “Back” link if you want players to be able to undo their choices.
Core.GotoSection("SectionName")
Advances the story to the named section. This is exactly the same thing that happens when the player clicks a link to a section macro. The advantage to calling this in Javascript is you could retrieve the target section name from a variable, or build it dynamically (use with care!)
Core.RefreshCurrentSection()
Reloads the current section without creating a new history entry. Not commonly used.
Fractive exposes events you can subscribe to, for when you want some code to be notified that something happened. To assign an event, declare a Javascript function in your story script and pass it to Core.AddEventListener.
Core.AddEventListener("OnBeginStory", function()
{
// Handle the event here
});
Subscribe to this event and it’ll be called immediately before the story begins. This is a good place to do any script initialization you might need.
Core.AddEventListener("OnGotoSection", function(id, element, tags, reason)
{
// Handle the event here
});
Subscribe to this event and it’ll be called whenever the current section changes. You’ll receive the ID (section name) of the target section, the HTML Element representing it (this will be the new state of the __currentSection div), an array of tags (strings), and a reason enum.
Tags are not currently used, but in the future you’ll be able to assign them to sections and then do whatever you want with them.
The reason enum provides context for why we’re going to this section now. It’s a value from Core.EGotoSectionReason as follows:
Core.RefreshCurrentSection().Since Fractive games allow unrestricted Javascript, you have the ability to extend your game beyond the “normal” hypertext fiction structure in potentially surprising ways. For example, you might choose to integrate your own or third-party libraries to add things like interactive graphical gameplay sequences or network multiplayer.
These kinds of extensions may add lots of additional Javascript – much more than you’d be using for your “normal” game logic – and that Javascript may need to be deployed in certain directory structures, utilize lazy loading, etc. These
are all things that would likely break if all those scripts were embedded directly into your story’s index.html.
In these situations you may benefit from placing those scripts in your assets list instead of your source list (see Project configuration).
That way, they’ll simply be copied to your final build location instead of being embedded in the index.html. You can then edit your template with <script> tags to source those scripts however you need.
You can also import Fractive as an npm dependency into another project, e.g. if you wanted to embed Fractive into a larger game or application. If your host project is an NPM project (which is strongly recommended) then you can add Fractive as a local dependency like this:
npm install --save-dev fractive
Then import it in your script file(s):
import * as fractive from "fractive";
And invoke exported API functions like this:
fractive.Core.GotoSection("SomeSectionName");
This installs Fractive as a local dependency to your project. If this is your only Fractive install (i.e. you never do npm install -g fractive) then you won’t have fractive on your PATH, which means commands like
fractive compile path/to/my/story won’t work. Local installs place the fractive executable in your project’s node_modules/.bin directory, so you’ll need to invoke it like this:
cd path/to/my/story
./node_modules/.bin/fractive compile .
Since this is a little awkward, it’s recommended to wrap this with an npm build script in your package.json:
"scripts": {
"build": "./node_modules/.bin/fractive compile .",
}
Then you can just do npm run build to compile your story. In this use case, though, you’ll probably have some kind of build script already set up for all the rest of your non-Fractive code, so you may just want to integrate
this command into that script however is most appropriate for your dev environment.
Fractive is a hypertext authoring tool, primarily intended for the creation of interactive fiction.
Stories are written in Markdown , and (optional) game logic is added with Javascript . The results are kind of like Twine , but the authoring process is very different.
Fractive has three core goals:
Throughout this documentation you’ll see some links with symbols next to them:
indicates a link to something outside this guide. This will open in a new tab/window.
appears on links which expand in-place to reveal more detailed information about the topic.
Fractive is maintained on GitHub at https://github.com/invicticide/fractive
Bug reports and feature requests can be filed here (you will need a GitHub account). Please do a quick search for your issue before filing, to prevent duplicates.
Fractive is licensed under AGPL-3.0+ .
Story text is written in Markdown , which is pretty close to plain text but with a few special formatting marks. Here’s a cheat sheet that should get you up to speed in just a few minutes.
You’ll write your story text in sections, each preceded by a special macro that looks like this: {{SectionName}}. Each section name (the part inside the double curly braces) must be unique within the story,
and section names may not contain whitespace or punctuation: only letters and numbers. A simple section would look like this:
{{Start}}
You are in a maze of twisty little passages, all alike.
Your story must contain one section called {{Start}} which is where the story begins.
You can create a link that takes the player to another section by creating a regular Markdown link and setting the URL to a macro that looks like this: {@DestinationName}:
{{Start}}
You are in a maze of twisty little passages, all alike.
[Look around]({@LookAround})
In this example, clicking the “Look around” link would transition the player to the section called LookAround.
Sections can be optionally be given tags, which are just a list of identifiers you can use for any purpose in your custom scripts.
To assign tags, declare a section like this:
{{Start: Tag1, Tag2}}
Everything after the : is a tag, and the list is comma-separated. In this example, the Start section is tagged with both Tag1 and Tag2.
In your scripts you can get the list of tags assigned to the current section:
var tags = Core.GetCurrentSectionTags();
for(var tag in tags) { ... }
Or you can get the tags assigned to any given section:
var tags = Core.GetSectionTags("Start");
for(var tag in tags) { ... }
Or you can get a list of all the sections that have the given tag assigned:
var sections = Core.GetSectionsWithTag("Tag1");
for(var section in sections) { ... }
Macros are always enclosed in {}. There are several types, each denoted by a leading metacharacter:
@ denotes a section macro# denotes a function macro$ denotes a variable macroIn story text, they look like this:
{{Start}}
This is a section macro: {@SomeSection}
This is a function macro: {#SomeFunction}
This is a variable macro: {$SomeVariable}
When used directly in the story text, macros behave like so:
@ section macros are replaced with the contents of the named section# function macros call the named Javascript function and then replace themselves with the text returned by that function (see Scripting: Function macros for details)$ variable macros are replaced with the value of the named Javascript variable (see Scripting: Variable macros for details)For example, writing this:
{{Start}}
You have {$NumApples} apples.
…would replace the {$NumApples} macro with the value of the NumApples variable, for a result like this:
You have 42 apples.
Macros are re-evaluated each time a section is entered, which means if you returned to this section again later in the story (after the value of the NumApples variable had changed) you would get a different result:
You have 10 apples.
When used as a link destination, macros behave like so:
@ section macros navigate to the named section# function macros call the named Javascript function (see Scripting: Function macros for details)$ variable macros are not valid as link destinations and will throw an error if used in this contextFor example, writing this:
{{Start}}
Let's go [elsewhere]({@Elsewhere}).
…would create a link out of the word “elsewhere” which, when clicked, would navigate to the section called Elsewhere.
Link macros can also be extended with the optional keyword :inline which creates a link that expands to some other text in-place when clicked (the links in this documentation
are an example of :inline behavior).
For example, you could write this:
{{Start}}
You are in [a maze]({$ExamineMaze:inline}) of twisty little passages, all alike.
…then define the variable in a .js file:
var ExamineMaze = "the Maze of Doom, where few adventurers dare tread. It consists";
Now when the player clicks on the a maze link, the link will be replaced with the value of the ExamineMaze variable, so they’ll see instead:
You are in the Maze of Doom, where few adventurers dare tread. It consist of twisty little passages, all alike.
Note that sections are block-level elements and will include paragraph breaks, so if you want to do an inline link in the middle of sentence, you’ll probably want to use a function or variable macro instead.
You can add multimedia elements, like images or videos, to your Fractive stories. In most cases you’ll just put those files in assets and then source them in your Markdown file. For example, you can place images like this:

Anything in assets gets copied over to your build output location when you publish your story, and the directory structure is preserved. (When writing asset paths in Markdown or Javascript, they should be relative to the project
root, not the Markdown/Javascript file itself.)
Markdown also allows raw HTML, so you could embed e.g. a YouTube video using its normal embed code. A section with a video might look like this:
{{VideoSection}}
Here's a video!
<iframe width="854" height="480" src="https://www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" gesture="media" allowfullscreen></iframe>
Since Markdown also accepts HTML, you could style some text like this:
In this story, some things are <span style="color:red">displayed in red</span>!
While functional, this looks ugly and makes your story text harder to read. It’s also a lot to type out, and if you’re going to be styling things consistently, you have to copy the same HTML snippet over and over again, which creates an opportunity for bugs to arise.
To solve this problem (and others like it) you can define custom macros, called aliases, which expand to other text or markup at compile-time. In your fractive.json simply add some rules to the aliases field, like this:
"aliases": [
{
"alias": "red",
"replaceWith": "<span style='color:red'>",
"end": "</span>"
},
{
"alias": "blue",
"replaceWith": "<span style='color:blue'>",
"end": "</span>"
}
],
Then refer to the alias in your story text like this:
In this story, some things are {red}displayed in red{/red}!
When you build your story, all instances of {red} will be replaced with <span style='color:red'> and all instances of {/red} will be replaced with </span>. If later you wanted
to change all your red text to a more specific shade of red (for example) you could simply edit your alias like this, then rebuild your story and all existing usages of the {red} alias would be automatically updated:
"aliases": [
{
"alias": "red",
"replaceWith": "<span style='color:#ff8888'>",
"end": "</span>"
},
{
"alias": "blue",
"replaceWith": "<span style='color:#8888ff'>",
"end": "</span>"
}
],
The end property of an alias is optional. Aliases are replaced with the replaceWith parameter, unless they contain a leading /, in which case they’re replaced with their end parameter
instead.
Alias replacement happens before any other build steps take place, and is a (nearly) pure text replacement. That means you can replace aliases with macro definitions, and those macros will then be expanded normally. In other words, you could do something like this:
"aliases": [
{
"alias": "Home",
"replaceWith": "{{Start}}"
}
],
And then in your story text do this:
{Home}
This is the beginning of my story, but I'm obstinate and don't want to use the normal \{{Start}} macro as my default section header.
When you build this story, {Home} will get replaced with {{Start}} and then voila, you have a valid starting section by a different name! (This is a contrived example, but you get the idea.)
Finally, did you notice the \{{Start}} in the example text above? When a macro is preceded by a \ character it is escaped, which means it’s not treated like a macro and is instead just rendered
as-is. Escaping applies to aliases as well, so {red} will be replaced, but \{red} will not. You should only need to use this in the rare case that you have text that contains a macro (or just a { character) that needs to actually be shown to the player. (This documentation is one such example!)
You can control the visual layout and style of your story by providing a custom HTML template. When you create a new project, a basic template.html is created in your project root. You can edit or replace this at your leisure.
A template is a regular HTML file with a few special marks:
<!--{script}-->
Indicates where story scripts should be inserted. Generally you should put this inside your <head>. You don’t need to include <script> tags; they’ll be added automatically by the compiler.
<!--{story}-->
Indicates where story text should be inserted. Generally you should put this inside your <body>. It doesn’t really matter where, because this will all be hidden at startup anyway.
<!--{backButton}-->
Indicates where the backButtonHTML defined in your fractive.json should be inserted, if includeBackButton is set to true. See Configuration for details.
<!--{title}-->
Optional mark which should appear in your <title> tag and will be replaced with the title field from your fractive.json. See Configuration for details.
You also need to define:
<div id="__currentSection"></div>
…which should be empty. This is where the active section’s story text will be displayed on the page.
Optionally, you can also include:
<div id="__history"></div>
…which should also be empty. This is where past sections will be displayed when history is enabled.
You can also style your game with custom CSS; just embed it in <style></style> tags at the top of your HTML template (or link to an external CSS file if you prefer). Fractive uses a few core CSS selectors you’ll
want to override:
#__currentSection
Covers the entire current section div, where active gameplay takes place.
#__history
Covers the entire history div, where previous sections are displayed for reference.
.__inlineMacro
Covers the expanded text that appears when the player clicks an :inline macro. The expanded text is wrapped in a span with this class.
.__disabledLink
Covers <a> tags in sections that have been moved to the history. Those <a> tags are replaced with <span> with this class assigned.
start of the tutorial
dev environment, tools, setup
create a project
write first couple sections and link them
build the project
test the project
add images, video
write a js function that affects game state
create a function macro to call your function
add a variable macro to reveal the dynamic game state
add detail with inline links
do some work in an event listener
use aliases for inline styling
customize the html template
publish the project, what to upload