MuCho is a multiple choise adventure engine, or choose your adventure engine, or gamebook engine, for the ZX Spectrum.
This document describes the story definition language.
In MuCho, every "room" consists of the room description and one or more options for the player to pick from. Each option then sends the player to another "room".
The syntax for the basic structure is as follows:
# The lines starting with # are comments # and will be ignored when compiling. $Q roomname Room description taking as many lines as is deemed necessary. The engine will automatically remove any whitespace and word-wrap the text. If a line break is desired, an empty line is needed in the source. $A nextroom Text for the first option $A anotherroom Text for the second option $A yetanotherroom Text for the third option |
Lines starting with a $ are "statement" lines. Currently, there are four different statement lines.
$Q roomname |
The $Q statement begins a room description. Its first parameter is the room's identifier, which must be unique among rooms, and must not contain spaces or colons (the ':' character). The identifier is only used while compiling, and will turn into a number inside the compiled data.
$A roomname |
The $A statement begins a player option description. Its first parameter is the room identifier the option sends the player to. Think of this as "if you want to go west, turn to page 347".
$I sunset.scr |
The $I statement includes a picture in the story where it is placed. To be used inside the page description, not in answer description. The first parameter is the source image name.
$O flag |
The $O statement starts an optional paragraph, that will be shown if the flags match the current state.
The $I statement can be used to include images in the story. If the same image is used several times, its data will still only be stored once. Any empty space on the bottom of the image is trimmed. The maximum height of an image is 14*8=112 pixels. If more is needed, just draw several images. Images are always full width, but empty space compresses well if a smaller square image is desired.
In addition to the first parameters mentioned earlier, the statements also take additional, optional parameters that manipulate and query the state of flags. These commands are split into two categories, predicates and executives. Predicates are used to figure out whether something should happen, and executives alter the game's state in some way.
The engine can handle up to 2048 flags, which should be enough for even the most crazy things you can fit in the zx spectrum.
Currently, there are three predicate commands.
$O roomname |
The simplest predicate checks if some flag is on. Whenever a room is entered, the room name flag is turned on, so to check if player has been to some place and then print out some text if they have, you could do the following:
$O cave This place reminds me of the cave you were in recently. |
If you wish, you can also write the flag-checking command as has:flagname.
Alternatively, you can check if some flag is not on by prefixing the flag with !.
$O !roomname |
The alternate form of flag-not-set check is not:flagname.
The third predicate is random:
$O rnd:127 |
The range is 1..255, so a value of 128 gives about 50% chance, 64 gives 25%, 32 gives 12.5%, etc.
Use random with care, as it may lead to undue frustration.
The predicates can be used to hide optional text blocks with $O, images with $I, and player options with $A. You can have a maximum of about 80 commands on one line, which means you can create rather complicated behaviors if need be.
Most of the executive commands alter the state of the flags.
$O set:flagname |
The set command sets a flag. Remember that entering a room sets the flag for the room name automatically.
$O clear:flagname |
The clear command clears a flag. It can also clear the flag that is automatically set when entering a room.
$O toggle:flagname |
The toggle command toggles the state of a flag. If it's on, it's turned off, and vice versa.
$O attr:7 |
The attr command changes the color attribute to be used for text from now on.
To set the color of the whole screen, in the $Q statement set attr and then use ext command to clear the screen, like:
$Q dark_room attr:7 ext:9 |
Here's a table of colors for your convenience:
Color | Ink | Paper |
Black | 0 | 0 |
Blue | 1 | 8 |
Red | 2 | 16 |
Magenta | 3 | 24 |
Green | 4 | 32 |
Cyan | 5 | 40 |
Yellow | 6 | 48 |
White | 7 | 56 |
So, for red on yellow background, you'd have 2+48=50, or attr:50. For bright, add 64, and for blinking, add 128.
$O iattr:7 dattr:7 |
The iattr and dattr commands change the attributes for the interface (iattr) and the divider (dattr). The attributes change the next time the interface is cleared.
$O ext:0 |
The ext command is meant for miscellaneous things that don't require a 8 bit parameter.
The sound effects are basically most of BeepFX v1.11 demo sounds, not including the sampled sound effects which take quite bit of memory.
Id | Sound | Id | Sound | |
100 | Shot 1 | 128 | Item 1 | |
101 | Shot 2 | 129 | Item 2 | |
102 | Jump 1 | 130 | Item 3 | |
103 | Jump 2 | 131 | Item 4 | |
104 | Pick | 132 | Item 5 | |
105 | Drop 1 | 133 | Item 6 | |
106 | Drop 2 | 134 | Switch 1 | |
107 | Grab 1 | 135 | Switch 2 | |
108 | Grab 2 | 136 | Power off | |
109 | Fat beep 1 | 137 | Score | |
110 | Fat beep 2 | 138 | Clang | |
111 | Fat beep 3 | 139 | Water tap | |
112 | Harsh beep 1 | 140 | Select 1 | |
113 | Harsh beep 2 | 141 | Select 2 | |
114 | Harsh beep 3 | 142 | Select 3 | |
115 | Hit 1 | 143 | Select 4 | |
116 | Hit 2 | 144 | Select 5 | |
117 | Hit 3 | 145 | Select 6 | |
118 | Hit 4 | 146 | Select 7 | |
119 | Jet burst | 147 | Alarm 1 | |
120 | Boom 1 | 148 | Alarm 2 | |
121 | Boom 2 | 149 | Alarm 3 | |
122 | Boom 3 | 150 | Eat | |
123 | Boom 4 | 151 | Gulp | |
124 | Boom 5 | 152 | Roboblip | |
125 | Boom 6 | 153 | Nope | |
126 | Boom 7 | 154 | Uh-huh? | |
127 | Boom 8 | 155 | Old computer |
The executive commands are only executed if the predicates succeed. Other than that, commands are executed in order they appear.
$O set:flaggy flaggy clear:flaggy toggle:flaggy |
In the convoluted example above, the engine first runs through the commands checking the predicate commands, and if they fail, the rest of the commands is NOT executed. If the flag "flaggy" was on, the commands are executed in order. First the flag is set, then it's cleared, and then toggled, setting it back on.
$Q room $O !light Light is off $O light Light is on $A room toggle:light Toggle light |
This example has a single room with a light that can be on or off. The player's option always points back to the same room, and the optional text blocks show whether the light is on or off.
$Q start Go to cave or forest? $A cave Go to cave $A forest Go to forest $Q cave Well, go on.. $A end Exit cave $Q forest Well, go on.. $A end Exit forest $Q end $O cave clr:cave As you exit the cave, you find... $O forest clr:forest As you exit the forest, you find... $O ...the end of the example. $A start Restart |
This example shows two different routes to a room, and the room's description reacts to where you came from.
$Q room You're in a room with a door. # If the 'key' flag is not on, tell player there's a key here. $O !key There is a key here. # If the 'open' flag is on, tell player the foor is open. $O open The door is open. # If the 'key' flag is not on, let player pick the key, # and if they do, set the key flag. $A room !key set:key Get key # If the player has key, and the door is not unlocked, # let player unlock the door, setting the flag. $A room key !unlocked set:unlocked Unlock door # If the door is not open and not unlocked, show an option # to open the door which sends player to the "locked" room, # below. $A locked !unlocked !open Open door # If the door is not open, but it's unlocked, let player # open it, setting the open flag on. $A room unlocked !open set:open Open door # If the door is open, let player exit. $A end open Exit # This little "room" is here just to tell player their # door-opening attempt failed. $Q locked The door is locked. $A room Dang it! # This is the end screen. There are no options; the game ends. $Q end You went through the door. |
A compiled room must not take more than 4096 bytes. The MuCho compiler will tell you when you cross the limit.
Images may be up to 112 pixels high. If more is needed, split images in pieces.
Maximum of 2048 flags.
Maximum of 16 active options at the same time.