Crowbook User Guide 0.15.0

« 6. Proofreading with Crowbook

Chapter 7
Interactive fiction

Version v0.12.0 added experimental support for writing interactive fiction.

Since this support is experimental, it means it can change at anytime, and there is no guarentee that the interactive fiction you write for the current version of crowbook will work with the next release, even if it isn’t a major release.

If you want to have a non-linear story, you can simply use Markdown links just as you would for any other link:

* [Open the treasure chest](
* [It might be trapped, stay away from it](

All crowbook renderers should render this correctly, allowing the reader to “choose her adventure”. Note, however, that you still need to include all these Markdown files in you book configuration files.

While the above allows you to generate correct EPUB and PDF files, it will still display all the content if the reader chooses to read your book linearly. While this may not be a problem, you might want to only display the part of the book that the reader is actually exploring.

In order to do so, you can use the interactive fiction html renderer:

output.html.if: my_book.html

This output is similar to the standalone HTML output, except the option to display only a chapter at a time is always true, and there is no way to display the table of contents.

While the above allows the reader to choose his own path, its interactivity is quite limited. With the interactive fiction renderer, it is possible to include Javascript code in your Markdown files, using a code block element:

You open the chest, and you find a shiny sword. Yay!

    user_has_sword = true;

This Javascript code can return a string value, which will be displayed inside the document according to the reader’s previous choices:

You encounter a goblin, armed with a knife!

    if (user_has_sword) {
	    return "You kill him with your sword, congratulations!";
	} else {
	    return "You don't have any weapon, you die :(";

Note that only the interactive fiction renderer supports this way of embedding Javascript code. If you try to render a document containing such code blocks to EPUB, PDF, or the “normal” HTML renderer, they will be displayed as regular code blocks.

If you want to include Markdown formatting in the Javascript code (to display a passage or another without having to write HTML code), you can use the @"..."@ syntax:

    @"You face a troll!"@
    if (user_has_sword) {
	    @"* [Attack him with your sword]("@
	} else {
        @"* [Better run away]("@

Note that in this case you don’t need to return a value, this is done behind your back. Similarly, @"..."@ blocks don’t require semicolons.

If you need to access the value of a Javascript variable inside this Markdown code, you can use the {{...}} syntax:

    var name = prompt("Enter your name", "world");
	@"Hello, {{name}}"@

Sometimes, you want some text (or Javascript code) to only be displayed (or run) when the reader reads this passage the first time, or alternatively when she goes back to it. While it is trivial to add some code to check that, it is a common enough pattern to justify its own variant: you’ll juste have to insert a named code block with the number:

@"Only displayed at first passage"@

@"Only displayed at second passage"@

@"Displayed at passage 3, 4 and so on.

As other renderers, there are options specific to the interactive fiction.

html.if.new_game allows you to specify the path to a Javascript that will be run at the beginning of the game. Since this code is not embedded in a function and is at the root (and the beginning) of the document, it is a good place to declare all the functions and the global variables you might need for your interactive fiction mechanics.


html.if.new_game: some_file.js

html.if.new_turn and html.if.end_turn allow you to specify some Javascript code that will be executed at the beginning and the end of each segment. Unlike html.if.new_game, the (usually shorter) code is specified inline, and can return a string value that will be displayed at the beginning and the end of each segment. This is exactly like including code blocks at the beginning or the end of each of your Markdown file. E.g.:

html.if.new_turn: "nb_turns += 1;"
html.end_turn: "return 'Turn: ' + nb_turns;"

html.if.script allows you to specify the name of a Javascript file to override the default script.

8. Tips and tricks »