Interactive stories are fun! In principle, there is a starting point, a finish point when you reach the end of the
story, and various points (or nodes
) inbetween reached by following different choices as the story progresses,
which can lead you through the story many different ways so that it changes each time you read it.
Writing an interactive story is tricky, though. You’ll need to plan it carefully so that all the various routes through the story work correctly, so that the story is consistent depending on the various routes taken to reach a certain node, and that it is possible to reach all nodes you have written and of course to reach the end! That takes much more time and effort than writing a normal story, and you may want to consider collaborating on a complex project with another author. To upload them, the stories must also be in a very specific format, and will not work otherwise.
Our support for interactive stories on this site has now been substantially upgraded with some simple programming elements that can control flow and offer new options. You can now keep scores, track and achieve multiple interdependent goals in a non-linear way and carry items (and drop them, or use them up) throughout a story, more like a text-based adventure game. This expanded guide will show how to add these new elements into your stories, even into older ones as the basic format is unchanged.
Some understanding of HTML may help with debugging as the text portions will be converted to correct HTML format, but otherwise the syntax is quite straightforward. The upload page will do very careful checking of the node syntax and will give you specific error messages locating any problems. You may upload stories that are not in HTML format as long as the rest of the node structure described here is correct and separated by at least one newline, or you may include specific HTML markup as shown in the first example below.
We STRONGLY advise that you read our HTML reference guide for MMSA for more information about using HTML directly in story submissions here. All the other extra features we offer through pseudo-tags, like in-site links to other stories and series and language changes, are available normally within your story nodes. You can also place a CSS style block at the very top of your story before any comment lines.
Here is a short example of what some typical nodes might look like at the start of a story:
First, note that the story is split logically into different nodes. Each node is identified by a number enclosed in vertical bars, always on its own line. The vertical bar symbol is usually found at the lower left of your keyboard (often appearing dashed). Beginning on the line after the node number is the text you want to display for this node. It can be plain text with paragraphs and line breaks shown correctly or HTML-formatted as above, with paragraph tags. In fact, you can have any HTML text you want, with the usual restrictions on tags for this site.
The only symbols you may NOT use in this text block (and not in the following link legends either) are the curly brace symbols { and }, as these are used to delimit the link legends, and the vertical bar character | as this is used to delimit the entire node. If you need any of these, you can insert their HTML entities instead:
Symbol | HTML entity |
---|---|
{ | { |
| | | |
} | } |
Using any of these prohibited characters in the text portions of your nodes will cause errors when the syntax is checked on uploading. If you are getting upload errors that are proving hard to debug, check for these characters carefully. The syntax checker should inform you if it finds them in unexpected places.
After the node text, each on their own line, comes a number of links corresponding to different choices at this point in the story. Each link has a legend (the text shown for that choice to the reader), which must be enclosed in curly braces, followed by a node number to jump to if that choice is made, which must be enclosed in brackets. There must be at least one link given and any text is permissible in the links except braces and vertical bars. It can be HTML-tagged but will appear on the page in bold anyway.
In the example above, because there is only one possible route forward from node 3, so no choice that needs to be made by the reader, the final Continue link will not actually be shown and any link legend will be completely ignored. (We advise you to use the text continue for debugging clarity). Instead the story text will continue directly with the contents of node 2, which is the only destination node there. This allows these continuity nodes without decisions to join story situations coming from different branches without duplicating the following common node text. The reader will not notice the join as the nodes are shown together.
You can specify two or more nodes as the target of a link by separating the numbers with a comma, like so:
In this case, the node actually jumped to will be selected at random from the multiple choices. Each choice has an equal chance of being taken, so to weight choices more heavily you simply repeat them as in the second line above. This allows even more variation in the gameplay and keeps your readers guessing!
Finally, there are four things required in the file you upload to enable the system to recognise it as an interactive story: there must be a descriptive entry node (node 0), a start node, a finish node, and a final end marker that MUST appear after every other node. The actual nodes may appear in any order you like, though – they do not have to be in strict numerical order. The start node is always 1, the finish node must be 9999. The finish node must link back to the start (node 1) to allow the reader to play again.
An absolutely minimal complete story would therefore appear like so (this example is shown without HTML; note the use of line-spacing to indicate paragraph breaks):
That’s only three nodes: a short description, then the start node proper, then the last linking back to the first, with a final end marker. You just need to add some nodes of your own into the middle to begin your own story. It’s that simple!
To add scoring, collecting and carrying/using items into stories, you can now set simple named variables that can be checked to determine the story flow and updated depending on the choices made. These can be either counters (integers from 0 to 999) or Booleans, representing true/false, yes/no, or have/have not. There can be any number. Any variable can also be set as a carrying item. For instance, you could be carrying an apple (true/false) or any number of apples (from 0 to 999, rational physics aside).
Each variable must have a UNIQUE alphabetic name that is used in the syntax to identify it when you test or change it, a starting value, and short descriptive legends that might be shown in the story text, typically in a list of any items you are carrying. You can also insert counter information automatically into your story to show a current score, amount of things collected etc..
All variables are defined right at the start of your story before the first node. They can actually be combined with comments or any other information you want to add, but only lines that are recognised as variable definitions from the first character on the line will be parsed, everything else will be skipped and ignored and will not be shown to the reader.
A variable definition line starts with either a dollar sign $ or a hash symbol #. This shows whether it is a general variable (like a score, an achievement reached or a current state) or something that will be carried – variables defined with the # symbol are carry items. Immediately following this is the variable name, which can ONLY be alphabetic characters, NO numbers or symbols, and the starting value following an equals sign. That must then be followed by a semicolon, which ends the definition. This will look quite familiar to anyone who has programmed in C-type languages like Javascript and PHP. Starting values are either numbers, for counters, from 0 to 999 maximum, positive integers only, or TRUE/FALSE for Booleans.
Here is an example of how to set up a few variables at the start of a story:
Note that the first/third lines are comments that will be ignored: they do not start with a dollar or hash symbol. Then there is a general variable cane which is a counter, starting at zero, and a Boolean variable shot that will indicate a story state achieved (whether you succesfully shot something or someone with the catapult). Although the definitions can be in any order at all, following that is a list of carry items that might be encountered in the story and collected, or maybe used. Two are single items that you either have or don’t have, so they are defined as Boolean variables, but the sweet variable is set as a counter, as you might collect any number. The catapult has been initialised with a value of TRUE, so you start the story carrying that, but no sweets or the apple.
After the variable initialisation, following the semicolon, comes the short decription(s) that will be displayed for these variables. The name of the variable will never be shown. Only carry items MUST have this descriptive text. You can leave them out for general variables, which will then only display numbers if you use them to insert scores or track progress in the story text. Non-carry Booleans are never inserted this way, so don't need a legend.
For a Boolean variable carry item there is only one legend, but for counters there are two you must give, for the singular and plural forms (when you have just one of an item, or none/many). Singular/plural legends must be separated by a colon. If you do not provide the correct number of legends for a variable, you will get an error.
Note that the legends for Booleans require an article in front (a, an or the) to display correctly when inserted into the line telling the reader what they are carrying. Legends for counters do not, as they will appear with the number giving the current counter value in front. As the above example shows for the variable cane, you can be as creative with the legends as you like, they do not have to be identical in single/plural form.
There is another important line shown above, which is actually optional. If you do not set a CARRYTEXT definition like this, then the story will be shown with English defaults of:
You are carrying item1, item2, and item3.
[OR] You are carrying nothing.
Since the story POV may not be first person, and the story language may not be English, you are encouraged strongly to set your own three legend fragments this way. Be as creative as you like as long as they follow the meaning of these defaults, just make sure you separate them with colons. You do not need a closing fullstop. For obvious reasons you may not use CARRYTEXT as a variable name.
When you write your story, you may change your mind about whether a variable should be a counter or a Boolean. Perhaps, using this example, you decide later that instead of either having or not having an apple, there may be more than one you might pick up in your story. It is critical that you are consistent, and to help you debug any problems you will receive an error on uploading if you try to set a counter with a Boolean value or vice versa.
The syntax of these upgraded stories had to be backwards-compatible with the old version, so tests and settings have been incorporated simply into the links following each node. To test, you add an IF bracket into the legend for the link, and to change a variable due to following a link you set it in the destination bracket. Link lines may now take the following general form:
In this example the counter cane is tested for being equal to 4, and the Boolean catapult is tested for being TRUE (the plus symbol following it, or a minus symbol would be a test for FALSE). If the link to node 8 is followed, any settings following the colon after the destination are applied. In this case, 2 is added to the total for cane – presumably adding some more strokes for the unfortunate subject of the story – and catapult is set to FALSE, perhaps because it has been confiscated.
There are two very important things to note about this example. The first is that this a logical AND test, meaning that BOTH tests must be true for the whole test to succeed. To make a logical OR test, where merely ANY of the things tested must be true (not necessarily all) then the IF test should be enclosed in normal round brackets, not square ones. You can test as many variables as you need at once this way. For testing a single variable there is no practical difference between the two and you can use either round or square brackets.
The second important thing is that the result of the IF test decides whether the entire link line is shown or not. If (at the time you reach this node) you still have the catapult and you have exactly 4 cane strokes, then you will see any choice presented by this link (if it is not the only one) or the branch to node 8 will be taken straight away if it is the only possible one. If you do not have the catapult, then you will not have the option or ability to reach node 8 from this node. Perhaps you may from another point in this story, or you may be able to come back to this node later if you obtain the catapult again.
This does mean you will have to be VERY careful to make sure that you do not set up link tests so that it is possible for ALL the tests after a node to fail, leaving no possible destination forward. Basically, if you make a test in one node link, at the very least you also need a link that does the exact opposite test on the same variable(s), so that one of the pair is always valid and allows the story to go forward, or you should have a default choice that does not contain a test at all.
Here is a list of all the ways you can test and set variables, showing the exact operator syntax:
Using tests and variables in your stories can simplify the writing process, as you won’t need to write every possible node and construct complex webs of links for every possible outcome. You can make far more use of joined continuity nodes that add information based on various possible story states before linking straight on to a generic description that can work for all states.
Adding to this, you can also insert the values and legends of your counter variables automatically into your nodes with a simple text marker, perhaps so you can inform the reader of their current score or what they have achieved so far. The marker is the variable name enclosed in square brackets, which will be replaced by the current value of the variable when the story is displayed, or by adding a modifier the value with the singular/plural legend following it can also be shown.
You should probably use this sparingly, or it may become tedious for the reader. Remember that they will always get a list at the bottom of every node (except the very last) of what they are carrying anyway. Note also that these marker substitutions will only work for counter variables, not Booleans.
Here is a short but complete example demonstrating all the new variable features. There is actually only one proper reader decision in it – all the other tests in the links control the flow of the story between various continuity nodes to build up a composite outcome. Two nodes (4 and 7) appear in both the main story threads. While much of this could have been better combined into a single specially-written node for each of the three outcomes, it wouldn’t have been much of an example!
Note there are two uses of the random features, one to change the story flow (alternate destination nodes) and one in setting a variable outcome. The counter variables sweet and cane are also substituted into the conclusion nodes as a sort of score confirmation. Note too the use of pairs of opposing tests to ensure that there is always a route forward in the story. Only one of the pair will be valid at any time.
If you try uploading this story fragment (but please NOT submitting it!) you’ll be able to see how the upload preview page shows you the changing values of your variables at every node, along with all the link tests, settings and substitutions being applied. Seeing which links are hidden for not passing your tests should also help with proper debugging.
For clarity this example has been written in plain text, not HTML.
Short interactive story example.
Remember: any lines at the start that do NOT set up variables are ignored.
First set a counter variable:
$cane=0; stinging stripe:throbbing stripes
Then the items to be carried:
#apple=TRUE; an apple
#catapult=TRUE; a catapult
#sweet=0; sherbet lemon:sherbet lemons
#CARRYTEXT; In your pockets you have:and:Your pockets are empty
|0|
You're an incorrigible urchin with a knack for getting into trouble. Can you negotiate an unfortunate encounter with your headmaster without ending up with a very sore bottom?
|1|
You run round the corner in the school corridor and bump straight into the headmaster. As usual he's carrying a cane. It's one you recognise all too clearly and your most recent experience of it is still a vivid memory – you're rather a regular visitor to his office.
Running in school is an offence and the new catapult you smuggled in today is a rather obvious lump in your blazer pocket. He's looking at you very crossly. Should you try to distract him?
{give headmaster apple} (2 : apple-)
{don't give headmaster apple} (3)
|2|
Before he can start to lecture you, you offer him the apple left over from your tuck.
The headmaster says Thank you,
and to your surprise he gives you some sweets in
return. He's a nice old stick really.
{continue} (4,10 : sweet?5)
|3|
You apologise profusely, hoping he doesn't spot the catapult. He harrumphs a bit and allows you to go. Phew! You got away with it!
{continue} (4)
|4|
But as you turn away, the headmaster asks: What's that in your pocket?
{IF(apple-) continue} (5)
{IF(apple+) continue} (6)
|5|
Perhaps he will be lenient with you since you were so generous...
{continue} (7 : catapult-)
|6|
Oops! He's not smiling and the cane is flexed ominously in your face. You know from painful experience that your shorts will offer little protection – the head is a formidable thrasher of naughty boys.
{continue} (7 : cane+4 catapult-)
|7|
The catapult is confiscated. After a short harangue about the dangers of offensive weapons, you sigh and touch your toes as ordered. You feel your shorts pulled tight and the cane tapping its target eagerly. Then... OUCH!
{IF[cane=4] continue} (8 : cane+2)
{IF[cane<4] continue} (9 : cane+1)
|8|
You get four blistering strokes. As you struggle to absorb the agony in your rear, you hear
the head swish his cane briskly and say: Now, about your running in school...
He demonstrates his disapproval very effectively indeed, with a couple of absolute corkers
low down that bring tears to your eyes.
A minute later you are heading for the bogs. You have [cane+] across your bottom and nothing to show for it, and you've been warned that the next time will be trousers down. It's no idle threat, Smith got it bare last week!
Maybe you should have tried to win over the old boy earlier.
{continue} (9999)
|9|
You are in luck! He's in such a good mood he gives you only a single stinger, and even lets you off the running too with just a warning to be more careful next time.
It's a shame about the catapult, but you have just [cane+] across your bottom and [sweet+] in your pocket. Buttering the old boy up certainly worked a treat!
{continue} (9999)
|10|
You leave smiling with [sweet+] in your pocket. He even forgot you were running! What a good thing he didn't notice the catapult...
{continue} (9999)
|9999|
You have completed the story!
{Start again and try a different choice} (1)
|End|