QuestBook

Contents


About the QuestBook system

QuestBook is a system that allows you to make your own solo adventure, much like those solo adventure books. Ever played one of those? No? Well, it works kind of like this: On the first few pages of the book, there are some instructions on how to play and what items and skills the main character of the book starts out with. By reading on, you reach the actual adventure, which gives you a number of choices at different stages of the adventure. It could look something like the paragraph below.

42

You are standing in a dark tunnel. Behind you is the cave opening from whence you entered the tunnel. Taking a few steps, you almost fall over a small chest. Before you have time to evaluate the amount of riches that may be concealed inside it, you hear a muffled shuffling that seems to come from further down the tunnel.

You could draw your trusty sword and venture into the tunnel and take whatever monster that lives here by surprise. Go to section 151.

Maybe a wiser choice would be to open the chest now before whatever lives in the tunnel discovers you. Go to section 22.

It might be best to just double back and get some help. Go to section 89.

Since the authors of the adventures are either a bit lazy or want a long adventure rather than one with lots of parallel story lines, many of the choices lead to certain death. In the example above, the first choice could lead to death by nasty ambush, the second choice could reveal that the chest has some kind of poison trap and the third could – oh I don't know – cause an earthquake or something.

Bitterness aside, in the QuestBook system you can write an automated solo adventure. QuestBook can work as kind of a rudimentary game master that keeps track of the lead character's inventory, any skills s/he might have, whether or not the dragon has been slain, that sort of stuff. Not like those pesky paper books where the player had to keep track of all that, and therefore might *gasp!* cheat.


Basic syntax

Let's just jump head first into the QuestBook mark-up language, or as I don't like to call it, QBML. The "choose your own adventure" section above would be represented as follows.

<area>
    <id>42</id>
    <title>42</title>

    <text>
        You are standing in a dark tunnel. Behind you is the cave
        opening from whence you entered the tunnel. Taking a few
        steps, you almost fall over a small chest. Before you have
        time to evaluate the amount of riches that may be concealed
        inside it, you hear a muffled shuffling that seems to come
        from further down the tunnel.
    </text>

    <option>
        <targetid>151</targetid>

        <text>
            You could draw your trusty sword and venture into
            the tunnel and take whatever monster that lives
            here by surprise.
        </text>
    </option>

    <option>
        <targetid>22</targetid>

        <text>
            Maybe a wiser choice would be to open the chest now
            before whatever lives in the tunnel discovers you.
        </text>
    </option>

    <option>
        <targetid>89</targetid>

        <text>
            It might be best to just double back and get some help.
        </text>
    </option>
</area>

Although it doesn't look like it in the example above, QBML also has those fancy in-tag parameters that you'll find in other mark-up languages like HTML (e.g. the HREF parameter of the A tag). That's because it can work in two ways. QBML uses what I sometimes call an entity-parameter hierarchy. Every tag is an entity, and everything enclosed by the tag is its parameters. The contents either consist of good clean data or more tags, which are parameters to the enclosing tag. In the example above, the AREA tag has an ID parameter, a TEXT parameter and three OPTION parameters. However, you don't have to use the entity-parameter style if you think it's too verbose; you can use in-tag parameter lists instead of tags-within-tags. (The examples in the rest of this document will try to mix both styles so you can choose for yourself.) In that style, the example above could look something like the following.

<area id=42 title=42>
    <text>
        You are standing in a dark tunnel. Behind you is the cave
        opening from whence you entered the tunnel. Taking a few
        steps, you almost fall over a small chest. Before you have
        time to evaluate the amount of riches that may be concealed
        inside it, you hear a muffled shuffling that seems to come
        from further down the tunnel.
    </text>

    <option targetid=151>
        You could draw your trusty sword and venture into
        the tunnel and take whatever monster that lives
        here by surprise.
    </option>

    <option targetid=22>
        Maybe a wiser choice would be to open the chest now
        before whatever lives in the tunnel discovers you.
    </option>

    <option targetid=89>
        It might be best to just double back and get some help.
    </option>
</area>

This style is much shorter, and possibly more readable, depending on your personal preferences. As exemplified above, the OPTION tag assumes that any untagged text within it is a short form of the TEXT parameter, which makes it behave very much like the A (anchor) tag in HTML.

A QuestBook adventure is a collection of AREAs. Each AREA has to have an ID; the rest is optional. If you want the AREA to be described, give it a TEXT parameter. You can also give the area a title by simply supplying a TITLE parameter. The OPTIONs indicate what AREAs the lead character can reach from this one. It doesn't have to be an area in the physical sense, just another paragraph in the adventure, like a fight with a troll, a train of thought, a journey through the forbidden forest or whatever. Regardless, each OPTION needs a TARGETID parameter that tells QuestBook what section it should jump to if the player selects that option. Also, it needs a TEXT parameter if it's not supposed to be invisible. (See below for examples of invisible OPTIONs.)


Inventory and variables

The most basic adventure is a set of sections with links between them. Just make a bunch of AREAs with some OPTIONs that link them. Do it right and you'll get a cool story with twists and turns in the plot, keeping the player on the edge of his/her seat. However, how will you keep track of inventory or stuff like whether or not the main character knows karate or how many health points the nasty orc has? We use the CODE tag, which is another optional parameter to AREAs. It contains instructions that is to be followed when the lead character reaches the AREA.

<area id=init>
    <code>
        <set>
            <item>sword</item>
            <value>1</value>
        </set>

        <set>
            <var>karate</var>
            <value>yes</value>
        </set>

        <set var="orc hp" value=20/>
    </code>

    <option targetid=1>
        Start the adventure.
    </option>
</area>

Let's go through this example piece by piece, from the inside out. The most basic part is the VALUE tag. It represents a simple value; a number, a letter, a string, what have you. The contents of the tag states what value we're actually talking about. Thusly, <value>1</value> quite naturally means the numerical value 1.

Next we have the VAR tag that represents variables; a space in which we can store a value such as whether the main character knows karate. In this case, the contents specify the name of the variable. For example, <var>karate</var> is a variable named "karate". Similarly, the ITEM tag represents items in the inventory. Items work a lot like variables in that we can set items to certain values. The values specify how many of that item the main character is carrying. In the example above, the main character is assigned one sword. This will show up in his inventory list.

That brings us to the SET tag. It takes two parameters. The first parameter has to be an ITEM or VAR tag, and the second has to evaluate to a value. The most obvious choice is a VALUE tag, but you can also use ITEM or VAR tags since they contain values. When SET has these two parameters, it simply stores the value in the second parameter in the storage space specified by the first parameter. In the example above, we're setting the variable orc hp to 20. (Yes, variable and item names can have spaces in them.)

That takes care of setting variables to different values. We'll also need a way to print out the results. For example, the player might want to know how many health points the main character of our adventure has.

<text>
    <var>hp</var> HP
</text>

Yes, it's that easy. All of the tags in a TEXT tag are evaluated, and the result is printed as if it were part of the text. (NB: This is a "lazy" example; you'll have to imagine the surrounding AREA tag and all that. Most of the following examples will be lazy as well.)

To reiterate, the CODE tag takes SET parameters that can change the number of ITEMs in the inventory or the VALUE or a VARiable. The CODE tag also takes the parameter tags INC and DEC which increment and decrement the value of a variable by one. Let's say, for example, that an hour has passed and we want our variable hour to reflect that.

<inc>
    <var>hour</var>
</inc>

DEC works in the same way, in that it takes either a VAR tag or an ITEM tag for adding to or subtracting from the inventory. Of course, you shouldn't have to use a whole lot of INCs if the main character receives, say, 20 pieces of gold. We can use an operator instead.


Operators and constants

Our first example operator is ADD, a tag that simply adds its two parameters.

<set>
    <item>gold</item>
    <add>
        <item>gold</item>
        <value>20</value>
    </add>
</set>

Below is the same code in the short style.

<set item=gold>
    <add item=gold value=20/>
</set>

Operators evaluate to values and can therefore replace VALUE parameters anywhere. In this example we've used the ADD operator instead of a VALUE in the SET tag. Now note how the ADD tag above has a VALUE parameter. We can put an operator in there instead. Although this is totally unnecessary in this case, it might serve as a good example. We'll use the MUL tag, which multiplies its two parameters.

<set item=gold>
    <add item=gold>
        <mul value=2 value=10/>
    </add>
</set>

There are of course other operators than ADD and MUL. Here's the complete list.

Operators in QBML
Tag name Description
Numerical ADD Adds its two parameters.
SUB Subtracts the second parameter from the first parameter.
MUL Multiplies its two parameters.
DIV Divides the second parameter by the first parameter.
Logical EQ Evaluates to TRUE if and only if the parameters are equal.
GT Evaluates to TRUE if and only if the first parameter is greater than the second.
LT Evaluates to TRUE if and only if the first parameter is less than the second.
AND Evaluates to TRUE if and only if both parameters are TRUE.
OR Evaluates to TRUE if and only if one or both of the parameters are TRUE.
NOT Evaluates to TRUE if and only if the single parameter is FALSE.

Don't mix the numerical (ADD, SUB, MUL, DIV) and the logical (EQ, GT, LT, AND, OR, NOT) operators. The result is undefined; sometimes FALSE evaluates to an empty string, and in other cases it's equal to zero.

Apart from the operators, there are also three contants that work similarly to operators in that they evaluate to certain values. For example, there's the TRUE tag. We can use this to indicate that our main character knows karate.

<set>
    <var>karate</var>
    <true/>
</set>

Note that in QBML (as in XML), <true/> is the equivalent of <true></true>. It quickly gets tedious to write the explicit start and end of a tag that doesn't contain any other tags.

The usage of the boolean values TRUE and FALSE has a great advantage versus using strings such as "yes" and "no"; we can easily perform logical operations.

<code>
    <set>
        <var>karate</var>
        <true/>
    </set>

    <set var=judo>
        <false/>
    </set>

    <set var=martial artist>
        <or var=karate var=judo/>
    </set>
</code>

That last SET would be more complex if we'd used "yes" and "no" strings.

<code>
    <set>
        <var>karate</var>
        <value>yes</value>
    </set>

    <set var=judo value=no/>

    <set var=martial artist>
        <or>
            <eq var=karate value=yes/>
            <eq var=judo value=yes/>
        </or>
    </set>
</code>

Here's the complete list of constants.

Contants in QBML
Tag name Description
TRUE Evaluates to TRUE.
FALSE Evaluates to FALSE.
SP Evaluates to a single space.
BR Evaluates to a line break.

Numerical and logical expressions

It's getting a bit hard to see what all this code does. Expressions that are more complex than just setting a value don't really lend themselves to the XML format. For that reason, there's an EVAL tag that can evaluate numerical and logical expressions. The gold example above that adds 2*10 to the gold variable can be translated into a single EVAL tag, as follows.

<eval>
    #gold := #gold + 2*10
</eval>

The hash (#) indicates that gold is an item class in the player's inventory. Similarly, a dollar sign ($) would specify that we're talking about a variable.

<eval>
    $hp := 20
</eval>

The EVAL tag supports parentheses in all kinds of situations, and are always used to associate several terms and bypass the precedence order, just like parentheses should. For example, attentive readers might have noticed that in our martial artist example, there was a variable with a space in it; martial artist. This is perfectly acceptable, but a bit of a problem in the EVAL tag if we're not careful and use parentheses to specify just what the name of the variable is.

<eval>
    $(martial artist) := <true/>
</eval>

(Note that constants are tags in these expressions too, just like in the previous examples.) Had we omitted the parentheses, although perfectly acceptable in this case, the code could easily become a string of nonsense in more complex expressions; a variable here, an assignment there, and a stray word in the middle that doesn't mean anything. Of course, parentheses can also be used in the conventional manner, to override operator precedence.

<eval>
    $hp := $hp - 0.1 * ($damage + 10)
</eval>

Below is the last CODE example from the previous section, using numerical/logical expressions. Note that CODE and EVAL can take several expressions separated by semi-colons. Also note that strings are not enclosed by quotation marks; they're handled just like numerical values.

<code>
    $karate := yes;
    $judo := no;
    $(martial artist) := ($karate == yes) || ($judo == yes)
</code>

Dice

What role-playing game doesn't have dice? What with solo adventures being solo role-playing games and QuestBook being a solo adventure engine, QuestBook should also have dice, right?

<set>
    <var>strength</var>
    <dice>3d6</dice>
</set>

This example rolls three six-sided dice and puts the result in a variable called "strength". Rather straightforward. However, what if we want to roll a certain amount of dice, and that amount is stored in some variable? Say that the main character is a ninja, and that she throws all of her shuriken at someone, and now we want to know how much damage they do, given that each shuriken does a four-sided die worth of damage.

<code>
    <set>
        <var>damage</var>
        <dice><item>shuriken</item>d4</dice>
    </set>
</code>

Just like in the TEXT tag, every tag in the DICE tag is evaluated. On a slightly related note, you can use DICE in expressions.

<code>
    $damage := <dice><item>shuriken</item>d4</dice>
</code>

Options

Variables and inventory won't do us any good if they can't affect which options the player can choose. If the main character doesn't have a sword, the player shouldn't be able to pick "draw your trusty sword"; we should be able to hide certain options.

<option targetid=151>
    <text>
        You could draw your trusty sword and venture into
        the tunnel and take whatever monster that lives
        here by surprise.
    </text>

    <hide>
        <eq item=sword value=0/>
    </hide>
</option>

An OPTION with a HIDE tag is hidden if the contents of the HIDE tag evaluates to TRUE. In the example above, the option is hidden if the main character's amount of swords is equal to zero. Similarly, we should be able to force the player into certain options, e.g. if the main character has slain the dragon, the king should thank her.

<option targetid="thankful king">
    <text>
        The king, chortling in his joy, approaches you.
    </text>

    <hide>
        !$(dragon slain)
    </hide>

    <choose>
        <var>dragon slain</var>
    </choose>
</option>

This option is hidden if the variable "dragon slain" is FALSE (note that HIDE and CHOOSE can parse expressions) and is chosen automatically if the same variable is TRUE. As a side note, the bulky <choose><true/></choose> is equivalent to <choose/>, an empty CHOOSE tag. The same holds for the HIDE tag. This can be useful for separating the initialisation of variables and inventory from the actual adventure.

<area id=init>
    <code>
        <set>
            <item>sword</item>
            <value>1</value>
        </set>

        <set item=gold value=53/>

        $strength := <dice>3d6</dice>;
        $agility := <dice>3d6</dice>;
        $wisdom := <dice>3d6</dice>
    </code>

    <option targetid=1>
        <choose/>
    </option>
</area>

Just place an AREA like this at the beginning of the file, and you're all set (provided that you want to initialise the game to this kind of values, of course).

That's about everything you need to know about OPTIONs. There are two other nice features though. The first is that they can have more than one TEXT parameter, where each one becomes a separate paragraph. As it happens, the same is true for AREA tags. The other is that the TARGETID parameter, when written as its own tag, has that auto-evaluation feature that TEXT and DICE has, so you can use variables, items or even DICE in it. Might come in handy.

<area id="path through woods">
    <title>Dark path</title>

    <code>
        $(return area) := (path through woods)                <!-- Remember which area we're in. -->
    </code>

    <option choose>
        <targetid>encounter<dice>1d10</dice></targetid>       <!-- Choose a random encounter. -->

        <text>
            These woods are treacherous. Who knows
            what you might encounter?
        </text>
    </option>
</area>

<area id=encounter1>
    <title>A goblin</title>

    <!-- add some description and fighting code and stuff here -->

    <option>
        <targetid><var>return area</var></targetid>           <!-- Return to the calling area. -->

        <text>You are victorious!</text>

        <choose>
            $(goblin hp) <= 0
        </choose>

        <hide>
            $(goblin hp) > 0
        </hide>
    </option>
</area>

<!-- add some more random encounters here -->

Just another small thing to note: The short version of the empty CHOOSE tag is simply an in-tag CHOOSE parameter without an assigned value, as in the encounter OPTION of the AREA "path through woods" above. The same goes for HIDE. This is very much akin to the CHECKED parameter of radio buttons in HTML.


Editing QBML files

You can use the edit page to make your own adventures. First pick a filename for your adventure; anything without slashes is fine. Don't fill in a password, that's for later. Press "submit". If you get "Wrong password", someone else has already picked that filename. Choose another one.

When you've reached the page with an edit box, you can just start typing. Depending on your browser's support for TEXTAREAs, you might prefer to use a text editor and then just paste the QBML into the edit box.

The META tag

Now, you might not want someone else to edit your adventure, so you should add a PASSWORD tag. The PASSWORD tag specifies the password that you should enter at the first screen of the edit page to be able to edit your adventure. This tag only exists within the special META tag, which contains all sorts of information about your adventure.

Since all the tags within META are rather self-explanatory, here's an example that you can copy and alter to suit your needs.

<meta>
    <title>The cool adventure</title>
    <author>John Smith</author>
    <year>2004</year>
    <info>Journey across the tundra and claim the gold!</info>
    <css>http://www.example.com/ice.css</css>
    <password>54321</password>
</meta>

Bear in mind that I can and probably will read your QBML code, so don't go using your HoTMaiL password or your cash card code or something.

A note about the CSS tag: The contents of this tag, be it a reference to a CSS-file or actual in-line CSS code, is applied to the presentation of your adventure. For now, you can view the HTML source of the adventure as you play to figure out how to write CSS for it. I might specify what SPANs and DIVs and whatnot there are in the HTML later on.


Try out some adventures

First, a quick note. QuestBook uses cookies to store variables, inventory and the current area for each adventure you play. Clearing the cookies on your computer will erase that information, and then you'll have to start the adventures all over again.

Here's a list of adventures:


Well, that's it

Any questions?


Copyright © 2002-2004 Joaquim Gândara