Fictional Adventure
Fictional Adventure is a Twine story format that allows publication to Archive Of Our Own, or any other site that allows HTML and CSS but not JavaScript.
How To Use
Add the story format to Twine
Fictional Adventure is a Twine "story format", basically a plugin that controls how the story will appear. You'll only need to do this once.
- Open Twine's editor, either installed on your computer or directly in your web browser.
-
From the menubar, click "Twine" and then "Story Formats".

-
In the Story Formats window, click "+ Add".
- In the dialogue box that appears, paste the following URL:
https://fictional.tools/adventure/dist/format.js
-
Click the green "+ Add" button. This will add Fictional Adventure to Twine.

Create a new story using Fictional Adventure
- Click "+ New" from the menubar to create a new story.
-
Click "Story" from the menubar, and then "Details".

-
A dialogue box will open. From the "Story Format" dropdown, select "Fictional Adventure".

-
Create the story. You can check out Twine's reference guide for full instructions, but in short:
- Double-click on a passage to open it in a window
- Type in contents of each passage as normal. You can use Markdown for formatting like italics, bolds, etc.
- Create links to other passages by surrounding text in square brackets. For example,
[[Part Two]]will link to a passage named "Part Two" and create it if it doesn't already exist. -
To make big, finger-friendly buttons, put your links on their own lines starting with an asterisk:
* [[Go to Part Two]] * [[Or to Part Three]] -
You can test out your story by clicking "Build" from the menubar and then clicking "Play". This will format your story with Fictional Adventure. Check out the "Preview" section to see your story in action.

-
Once you're ready to publish to AO3 or elsewhere, play your story like above.
- Create a work skin on AO3 and paste in the contents of Fictional Adventure's "CSS" box.
- Create your fic on AO3 and paste in the contents of the "HTML" box as your chapter contents.
- Select your created work skin as the skin for your fic, then save.
- Your Twine story is now published to AO3!
If you publish a work using Fictional Adventure, consider adding a link in your end notes:
Created using <a href="https://twinery.org/">Twine</a> and <a href="https://fictional.tools/adventure?utm-source=user-share">Fictional Adventure</a>.
Advanced Features
Customizing Your Work Skin
If you want to customize how your fic appears, you can add custom CSS directly in Twine from the Story > Stylesheet menu. Just enter (or paste in) CSS and it'll be automatically get appended to Fictional Adventure's CSS output.
For example, you can alter the color of the link buttons like this:
li a {
color: white;
background-color: #593196;
}
Using Story Flags
If you want to add more complex logic to your story, you can use story flags. Story flags allow for simple "if this then that" sections to be added to your code to track things the player has done, such as picking up items. (In programming terms, story flags are boolean variables.)
Story flags can be either "set" or "unset". They are always "unset" to start with. They can be set by putting the following in a passage of your story:
You pick up the key.
{{set has-key}}
In other passages, you can check whether the flag has been set:
{{#if has-key}}
You have the key!
{{else}}
You don't have the key.
{{/if}}
Story flags can also be unset:
You drop the key.
{{unset has-key}}
Or toggled:
{{toggle has-key}}
set, unset, or toggle command in your passage. The command will always be processed when the passage is opened, even if the command was inside an if block that wouldn't otherwise be run.Limitations
It's important to note that story flags can greatly increase the word count of the HTML that Fictional Adventure outputs. Since Archive Of Our Own can't run actual scripts, Fictional Adventure will instead generate a copy of each passage in your story for every combination of flags. So if you use one flag, you'll have two copies of each passage. Two flags will have four copies, three flags will have eight copies, and so on.
Four or five flags (16 or 32 copies of each passage) is likely the practical limit in most cases, though it depends on the length and number of passages in the story.
Fictional Adventure will automatically trim any unreachable passage states, so you can cut down on the total number of copies by unsetting flags as soon as your story no longer needs them.
Helpers
"Helpers" are tools that can do things like counting or comparing flags. There are several helpers built in to Fictional Adventure.
Boolean Logic
You can use complex boolean logic using the and, or, and not helpers. (These use Polish notation, with the logical operator first and the operands after.)
{{#if (and first-key second-key)}}
This will appear if both first-key and second-key are set.
{{/if}}
{{#if (or first-key second-key)}}
This will appear if either first-key or second-key are set.
{{/if}}
{{#if (not (and first-key second-key))}}
This will appear if neither first-key nor second-key are set.
{{/if}}
Counting
You can count flags using the count helper. This will give the number of listed flags that are currently set.
You have {{count first-key second-key third-key}} keys.
Comparisons
Numbers can be compared using gt (greater than), gte (greater than or equal to), lt (lesser than), lte (lesser than or equal to), or eq (equal) helpers.
{{#if (eq 3 (count first-key second-key third-key))}}
You have all three keys!
{{else}}
{{#if (gte (count first-key second-key third-key) 1)}}
You have at least one key.
{{else}}
You have no keys.
{{/if}}
{{/if}}
If you want a flag to be counted multiple times, just repeat it: {{count first-key second-key keyring keyring keyring}} will make keyring count as three keys.
Ranges
Sometimes it can be helpful to generate a range of numbers, like repeating some text a certain number of times. The range helper will list the range of numbers between the specified start and end, including the start and excluding the end. {{range 1 5}} will give 1,2,3,4.
range can be combined with the built-in #each to loop over the numbers.
{{#each (range 1 10)}}Copy {{this}}, {{/each}}
This will output Copy 1, Copy 2, ... and so on through Copy 9.
Arithmetic
The add, sub, mul, and div helpers will add, subtract, multiply, or divide respectively.
Hint: story flags are internally equal to 1 when set and 0 when unset. {{mul 5 keyring}} would give 5 if keyring is set and 0 if keyring is not set, since 5 x 0 = 0.
Flag Lists
Sometimes it can be helpful to have a shorthand to refer to multiple flags. You can create a flag list like this:
{{list first-key second-key third-key}}
Once defined, this list will be available in every passage. You can use it anywhere that multiple story flags can be used:
{{#if (and keys)}}
You have all the keys!
{{/if}}
Advanced usage: Partials
A "partial" is a passage that can be included from inside of other passages. This can be help avoid copy/pasting a section multiple times.
To make a partial, just create a story passage like normal and give it a name starting with Partial:. The name can't include spaces.
For this example, we'll create a new passage named "Partial: key-counter".
You currently have {{count keys}} key{{#unless (eq 1 (count keys))}}s{{/unless}}.
(The unless section will leave off the trailing "s" if there's exactly one key. This prevents the incorrect pluralization "1 keys" from being displayed.)
Elsewhere in the story, the partial can be included like this:
You look in your pocket. {{> key-counter}}
If the player has two keys currently, this would result in: "You look in your pocket. You currently have 2 keys."
Advanced usage: Handlebars
Internally, Fictional Adventure's story flags feature uses the Handlebars template engine. You can optionally use advanced Handlebars features like whitespace control.
You can also register helpers and partials in JavaScript by using your Twine story's JavaScript section, under the Story menu. The helper and partial functions are aliases of Handlebars' registerHelper and registerPartial:
helper('plural', (list, options) =>
list.filter(i => !!i).length === 1
? null
: options.fn(this));
Full Example
Passage "Start":
There is a locked door here. You {{#unless has-key}}don't{{/unless~}} have the key.
There is a box here. It is {{#if box-open}}open{{else}}closed{{/if}}.
{{#if has-key}}
* [[Unlock the door|Unlock]]
{{/if~}}
{{#if box-open}}
* [[Pick up the key|Get Key]]
* [[Close the box|Toggle Box]]
{{else}}
* [[Open the box|Toggle Box]]
{{/if}}
Passage "Toggle Box":
{{toggle box-open~}}
You {{#if box-open}}open{{else}}close{{/if~}} the box.
* [[Continue|Start]]
Passage "Get Key":
{{set has-key~}}
You pick up the key.
* [[Continue|Start]]
Passage "Unlock":
{{unset has-key~}}
{{unset box-open~}}
You unlock the door. You win!
* [[Play Again?|Start]]