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.
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 AREA
s. 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 OPTION
s
indicate what AREA
s 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 OPTION
s.)
The most basic adventure is a set of sections with links between them. Just make
a bunch of AREA
s with some OPTION
s 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 AREA
s. 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 ITEM
s in the inventory or the VALUE
or a VAR
iable. 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 INC
s if the main
character receives, say, 20 pieces of gold. We can use an operator instead.
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.
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.
Tag name | Description |
---|---|
TRUE |
Evaluates to TRUE. |
FALSE |
Evaluates to FALSE. |
SP |
Evaluates to a single space. |
BR |
Evaluates to a line break. |
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>
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>
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 OPTION
s. 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.
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 TEXTAREA
s, you might prefer to use a text
editor and then just paste the QBML into the edit box.
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.
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:
Copyright © 2002-2004 Joaquim Gândara