M.A.C. : Mystery Adventure Creator

v. 2.3

Author: Paolo Lucchesi
email: plucchesi@tin.it
Author's homepage: http://www.paololucchesi.it
M.A.C. home page: http://mac.paololucchesi.it

To my wife Benedetta
and Becky and Raffa.


0: Synopsis

1: Brief description of text adventures and glossary

2: Using M.A.C.

2.1: Program options

3: Playing with M.A.C.

4: Programming language (or something similar)

4.1: [System], Adventure generic data

4.2: [Sysmsg], System Messages

4.3: [Directions], Movement

4.4: [Locations], Game Locations and Rooms

4.5: [Verbs] e [Nouns], Game vocabolary

4.6: [Objects], Items and Objects

4.7: [Messages], Messages

4.8: [Shows], Graphic Messages

4.9: [Vars], Variables and Flags

4.10: [Events] e [Actions], Game engine

5. Graphics

6. Credits

7. Licence and warranty

0: Synopsis

M.A.C. is a simple scripting language used to create text adventures (now called "Interactive Fictions") with the spirit of the ones running on the old 8bit computers (like ZX Spectrum and Commodore64). I was inspired in this work by the Brian Howart's "Mysterious Adventures" serie and an adventure creator named "The Quill". Maybe M.A.C. mey be seen as a remake of "The Quill".

Compared to other similar products, as T.A.D.S. or Inform, M.A.C. is surely much less advanced. The programming language is extremely simple and in no way object oriented, and consequently the game itself cannot have the flexibility of other systems; command are in the verb-noun form, it's not possibile to have more than one character, and so on... On the other hand, M.A.C. can use graphic images correlated to the various game location.

I've done M.A.C. for three reason: first, a simple programming language is, in my opinion, more suitable to recreate the spirit of the old days; second, no other products was really suitable for the remaking of old adventure games; third, I enjoyed programming it.

1: Brief description of text adventures and glossary

If you're interested in M.A.C., probably you know what a text adventure is. Anyway I'll do a brief description, to have a common glossary.

A text adventure is a game; in a text adventure the player control a virtual character in a virtual world; the computer gives a description of the situation and of the events that happens, and the player decides what the charater does (or tries to do) giving natural language commands, as "pick un the apple" or "enter the building". The complexity of the commands usable is very variable from game to game; in some cases are permitted long and complex sentences, in other cases (and in our case) we are limited to simple senteces formed by a verb and one or more nouns. M.A.C. can handle up to three differen nouns, but in many case commands are in a simple verb-noun form.

The game is played in a group of locations, virtual ambients the character can move from and to, going in the cardinal direction (North, South, East, West and, less frequently, North-East, South-East, North-West and South-West), up, or down.

The Character can interact with various objects that are in the locations; some of these can be carried, some can be worn, some can be used in various ways, alone or with other obejcts. The collection of objects carried by the character is called inventory.

The game can be ended in three ways. The player can decide in any moment that he has had enought and exit the program (maybe saving the situation, so he don't have to restart from the beginning), or the character can fulfill the task of the game (find an amount of treasure or a given object, leave a dangerous place, or anything you can think), or the character cannon in any way finish succesfully the game (mostly becouse he's dead, or something similar).

2: Using M.A.C.

M.A.C. runs under a 32bit dos-like system (like the dos prompt under Windows 9x) or under Windows 9x/NT/2000/ME/XP. There are four different M.A.C. versions:
MACSTD.EXE is the simplest version, and it's text only. It's only purpouse is to be ported easily under other systems.
MACTXT.EXE is a text-only version that use the DOS console. Its main purpouse is the debug of the adventures you write.
MAC.EXE is the complete graphic version. Every version has exacly the same option set, so we'll refer to this version only. This version is a 32bit dos application, runs full screen, and is not guaranteed to work under Windows NT/2000/XP.
WINMAC.EXE is a native Windows version. This version is a beta release (mainly for the graphic library). It works in windowed mode (if possible) and need a resolution of at lease 800x600. It's virtually identical to the 32bit dos graphic version.

M.A.C. also works under Linux; in this case there are just two versions: mac (graphic version, runs under x11) and macstd (standard text only version, runs in console).

The adventure file can be in two format: the first has a .adv extension, and is a text file that can be edited (even from scratch) with any text editor (as Edit or Notepad) following the guidelines of chapter 4. The second has a .mac extension, and is a binary (compressed) file; you can obtain a .mac file from a (correct) .adv file using the -c option of M.A.C.

You can start the program with the command mac <filename>, where nomefile.mac or nomefile.adv is the name of the file containing the adventure. If non filename is given, the program search a file called as itself (with the proper extension); so mac.exe look for a mac.mac or mac.adv file, but you can rename it. If you rename mac.exe in myadv.exe, and run it with the command myadv, it

When you run the program, it reads the file and, if no errors are found, starts the game. Every error is displayed but if only lesser errors (warnings) are found, the game starts anyway.

Always pay attention to the filenames: under linux character case is fundamental (readme.txt and ReadMe.txt are different files). So to ensue portability and functionality, use lowercase filenames only (you can use number, but should avoid uppercase letters and spaces).

2.1: Program options

As said earlier, M.A.C. can convert a text file .adv in a binary file .mac, with the following advantages: first of all the .mac file is compressed (less space occupied), and it isn't possible to look the informations keeped in the file (this is done very easily with .adv files). To convert files, use the option --compile (or -c); for example, the command mac -c filename convert the text file filename.adv into the binary file filename.mac. If M.A.C. is invoked with the -c option, it only converts files, and doesn't start the game

Usually M.A.C. looks first for a text file (extension .adv) and then for a binary file (extension .mac); pay attention: before release 2.4 M.A.C. adopted the opposite behavior. The --text (or -t) option force M.A.C. to look only for a text (.adv) file, and the --binary (or -b) option force M.A.C. to look only for a binary (.mac) file.

The --debug (or -d) option runs M.A.C. in debug mode. Debug mode is disabled if the adventure file is in binary format (.mac). While in debug mode, you can type (while playing, at the command request) the % character followed by a number n to look the position of the n-th object and the value of the n-th variable; you can also type just the % character, to look the curren location and the number of carried items.

Finally the --help (or -h) option shows a brief help message and exits, and the --version (or -v) option shows the version number and exits.

3: Playing with M.A.C.

There are various standard command that are necessary when you play a text adventure. These commands (as defined in the ital.adh file) are:

The commands NORTH, SOUTH, EAST, WEST, UP and DOWN (or, in short notation, N, S, E, W, U and D) make the character move from one location to another one. The command INVENTORY (or I) shows the objects the character owns. The command REDESCRIBE (or R) shows again the location description (useful only while using the text-only version macstd.exe).

The command EXAMINE (or LOOK, or SEARCH, or EXAM), used with an object name, gives, if possible, a detailed description of the object. The commands GET (or PICK), DROP (or LEAVE), WEAR and REMOVE, used with an object name, make the character interact with that object piking it up, dropping it, wearing it or removing it. The command WAIT make the time passes (if you're waiting some events.

The commands SAVE and RESTORE (or LOAD) save and restore the situation in a file. Both are followed by the request of a number between 1 and 9 that identify the save file. The save file is called like the game, with an extension between .sv1 and .sv9. Finally, the command QUIT makes the game end (the program ask if you're sure, then ask if you want to save the situation, and at last ask if you want to restart the game).

In the graphical version and in the console text version, the player can recall the list of the last commands using the ud and down arrow.

4: Programming language (or something similar)

I admit that the term "language programming" is a bix exaggerated. The file that describe the adventure is no more than a set of definition. There are no procedure, nor objects, nor flow control. But let's take a look to the general concepts.

The file that describe the adventure is a normal standard ASCII text file, done with any text editor (for example edit or notepad). The file is divided in various section, each beginning with its name between square brakets. The sections can be in any order, and even interlaced (i.e. you can type part of a section, then another section, and then return to the first section).

Almost every element of the various sections (exception: the variables) begins with the # character followed by an unique (in that section) number, and after that the fields that specify the element, separated by commas. Only the first line of an element is divided in fileds. In the following lines (if existent) you can use commas freely.

Keywords may be in upper case, lower case or any combination of upper and lower case; i.e. the keywords "LOCATIONS", "locations", "Locations" and "lOCatiONs" are equivalent.

The | character means end-of-line; i.e. nothing after the first | is read. You don't have to put a | at the end of every line, but you can add a remark after the | character. A line that begin with the | character is a remark line. The | character has another purpose: if you have to add some spaces at the end of line, you have to put a | after the spaces.

The \ character is used in long description of objects and locations, and in messages. It means carriage-return.

If you need to use che % character in messages or description, you have to type it twice (%%). We'll explain this when we'll discuss flags and variables.

You can include another file in your adventure file. You only havo to write a line containing the @ character followed by the name of the included file. For example, if you want to include a file named mydef.adh in a file named myadv.adv, you have to put the line "@mydef.adh" in the latter file. It's even possibile to recursively include a file in an included file; this has little utility, and it's not a good pratice.

Usually the file inclusion is used to insert in an adventure file a set of standard common definitions, like the system messages, or some verbs. Along with M.A.C., four standard definition files are distribuited: eng.adh contains the standard definition in English, ital.adhcontains the standard definition in Italian, myst.adh contains the standard definition in "Mysterious Adventures" style (in English) and myst_it.adh contains the italian transtlation of the latter.

Let's remember, to ensue portability, to avoid uppercase character and spaces in filenames.

4.1: [System], Adventure generic data

The [System] section contains a set of constants of general use. Each line has the format <ElementName>=<value>. These constants are:

StartLocation is the number of the location where the character is when the game starts (for example StartLocation=5). Default value is 1.

Boolean is a pair of character the player use to answer to yes/no questions, as "Do you really want to quit playing (y/n)?". The two characters follows the = sign, the positive answer comes first; for example Boolean=yn. Default is yn.

MaxItems is the maximum number of items the character can carry (for example MaxItems=7. Default is 5.

Prompt is the string that preceed the command line in the game. For example Prompt=What Now?. Default is just the %gt; character.

ImagePath is the subdirectory where the graphics images used in the game are stored (for example ImagePath=advimg). The maximum size is 32 character. If no ImagePath is specified, M.A.C. looks for the images in its own directory.

ShowExits can be followed by the y or n character(example ShowExits=n) and, if equal to y, means that the location description shoul include a list of the available exit directions. Default is y.

BgColor and FgColor are the background color and the foreground color used in the graphic version. They can assume values between 0 and 15 (for example BgColor=7), referring to the standard VGA palette:

0 = black4 = dark red8 = dark grey12 = red
1 = dark blue5 = purple9 = blue13 = magenta
2 = dark green6 = brown10 = green14 = yellow
3 = teal7 = grey11 = cyan15 = white

Title is the title shown on the window upper bar (Windows version only).

StatusLine is a message (long no more than 64 characters) that will be shown continously and that (as we will see later) can contain variables. Mostly this feature is used to show the numbers of turns passed and the score achieved. These feature is not present in the standard text version MACSTD.EXE.

CharSet is a flag that means if the adventure file use an ascii table different from dos standard, and if a conversion of any kind should be applied (example CharSet=w). The only value accepted is w, that means that the adventure file use a windows standard ascii table; conversion is limited to vowels with accents (not used in English) and other characters on an italian keyboard.

4.2: [Sysmsg], System Messages.

The [Sysmsg] section contains the generic system messages, common to several games. These message aren't specific to a single game, so their natural collocation is in a standar definition file.

Every message is defined in a single line that contains the message id number (beginning with the # character) and the message text. For example #4,you're carrying too much. The system message are:

1: Syntax error, or command unknown (for example "I don't understand what you mean")
2: Object not found (for example "You don't see it")
3: The requested command cannot be accomplished (for example "You can't")
4: Full inventory (for example "You're carring too much")
5: Movement toward unavailable direction (for example "You can't go there")
6: Object non present in inventory (for example "You don't have it")
7: Generic description of an object (for example "You see nothing special")
8: The command cannot be accomplished in that situation (for example "You can't do that yet")
9: Waiting message (for example "Time passess...")
10: Successful action message (for example "Ok!")
11: Prefix to the objects present in location list (for example "You see:")
12: Inventory prefix (for example "You have:")
13: Worn objects suffix (for example "(worn)")
14: Empty inventory list message (for example "nothing at all")
19: Prefix to the possible directions list (for example "Exits:")
21: Save position number question (for example "Save in position (1-9)?")
22: Load position number question (for example "Restore from position (1-9)?")
23: Restore game at start question (for example "Restore a saved game (y/n)?")
24: Quit confirm question (for example "Are you sure you want to quit (y/n)?")
25: Save game on exit question (for example "Save current game (y/n)")
26: Restart game question (for example "Restart game? (y/n)")
29: File error message (for example "File error")

These messages are properly defined in the standars definition files ital.adh, eng.adh and myst.adh.

4.3: [Directions] Movement

The [Directions] section contains the names of each direction the character can move to. Pay attention: these are just tha names that are showed along with the locarion description, these aren't the command the player must input to make the caracter move from one location to another. The commands are defined in the [Verbs] section.

Each line contains the direction id number (between 1 and 10, beginning with the # character) and the direction name. For example: #2,South.

Obviously the direction names are usually common to all games, and their natural collocation is in a standard definition file. The ital.adh, eng.adh and myst.adh files contain the definition of North, South, East, West, Up and Down (numbered from 1 to 6).

4.4: [Locations] Game Locations and Rooms

The [Locations] section contains the full description of the locations of the game; if you use the graphic version of M.A.C. you can associate an imagte to any location. You can define up to 32767 locations.

The first line of every location contains the location id number (from 1 to 32767, beginning with #), a short description (actually unused), the filename of the graphic image (v. chap. 5), a type id and the list of the locations the player can reach moving in each direction (0 means that the player cannot move in that direcrion). The following lines contains the long description of the location. The type id has value 0 for a normal location, and 1 for a "dark" location (where the character cannot see if he doesn't have a source of light).

For example:

You are in the entrance hall of the Rudolph manor. There are dusty
pictures and suit of arms to the walls. A wooden ladder leads up.

Here the location described is not "dark", and along with its description the graphic version of M.A.C. will show the image in the entrance.png file; fron this location the character can get to location 3 going north, to locarion 2 going east and to location 4 going up (assuming we're using standard directions).

The location number 0 is reserved. It contains the description and the image showed when the character is in a "dark" location (without any source of light). Type and movement directions of location 0 are unused. Here an example of location 0:

It's dark. You cannot see a thing.

In the [Events] and [Actions] sections, we'll see that the movement directions from any location, and the light in any location can be altered in the game.

4.5: [Verbs] e [Nouns] Game Vocabolary

The [Verbs] section contains verbs used to give orders to the character. Every line contains the verb id number (from 1 to 32767, beginning with the # character) and some words that will be treated as synonimous. For example:


Some verbs are "reserved". The verbs from 1 to 10 are used for the movemente directions, as defined in the [Directions] and [Locations] section. The other reserved verbs are:

11: to show the inventory (INVENTORY, I)
12: to repeat the location's description (REDESCRIBE, R)
13: to examine an object (EXAMINE, LOOK, SEARCH)
14: to pick up an object (PICK, GET, TAKE)
15: to drop an object (DROP, LEAVE)
16: to wear an object (WEAR)
17: to remove a worn object (REMOVE)
18: to wait (WAIT)
21: to save the current game (SAVE)
22: to restore a saved game (RESTORE, LOAD)
23: to quit the game (QUIT)

These verbs are properly defined in the standar definition file eng.adh, ital.adh and myst.adh.

The [Nouns[ sections contains the nouns used with verb to compose the commands to guide the character. Again, every line contains the noun id number (from 1 to 512, beginning with the # character) and a list of words that will be treated as synonimous. For exampe:


Usually if a noun is related to an object, it has the same number (see [Objects] section). For this reason, is better to separate (using suitably high id numbers) the objects that aren't related to any object. A nounm can be related to more than an object. In the [Objects] we'll see how to handel this.

4.6: [Objects] Items and Objects

The [Objects] section contains the description of the objects the charcater can interact with (or even objects that are just decorations) and that can be found while playing.

The first line of every object contains the object id number (from 1 to 32767, beginning with the # character), the short description (the one mostly used), the location where the object is at the beginning of the game, a type id and the noun related to this object (optional, see [Nouns] section). The following lines are optional and contain the long description of the objects, the one used whe the character "examines" the objects.

The start location may be the id number of any location, or a special value: 0 means that the object doesn't exist when the game begins (for example an open door that will be created when the charater opens a closed door), -1 means that the object is in the inventory, and -2 means that the object is worn by the character.

The type id is calculated adding some values: 1 means that the object is carriable, 2 means that the object can be worn, and 4 means that the object is a source of light. A type 0 object is not carriable nor can be worn, and cast no light (like a big rock), a type 3 object can be carried and worn (like a jacket), and a type 5 object is a carriable source of light (like a torch); an object that can be worn, obviously, should also be carried (so don't define type 2 objects).

The noun related to the object, if not dedined, has the same id number of the object. Usually it's defined when two objects have the same noun (a closed door and an open door, for example, are related to the noun DOOR). The noun related to the object can be specified with his id number or, if the noun has been previously defined in the [Nouns] section, even with the explicit noun.

If no long description is given, when the character examines the object, the system message 7 ("You don't see nothing special") is shown.

Some examples:

#1,A gun,-1,1
Your trustworth Magnum 44.
#2,A wooden table,2,0
#3,A torch,2,1
#4,A light torch,0,5,TORCH
#5,A cloak,2,3
An old grey cloak.

We have defined 5 objects; only two (the gun and the cloak) have an accurate description. When the game begins, the gun is owned by the character, the light torch (source of light) doesn't exist and the other objects are in the location 2. All the objects, except the table, can be carried, and the cloak can be worn. The light torch has the same noun of the unlight torch.

4.7: [Messages] Messages

In the game usually are shown messages that describe the result of the actions of the characters, or some events. These messages are described in the [Messages] section.

Every message description contains the id number (from 1 to 32767, beginning with the # character), followed by the message text. The message text can span on more than a single line. For example:

#1,You move the heavy barrels revealing
a secre passage.
#2,You hear a faint laughter in the distance.
#3,As you try to move the library, it crushes
to the floor, killing you.

4.8: [Shows] Graphic Messages

The [Shows] section contains messages, just like the [Messages] section; the only difference is that if you're using the graphic version of M.A.C., you can associate a graphic image to every message in this section. These messages can be used, for example, as intro messages when the adventure begins (see section [Events], condition begin), or at the end, or when something peculiar happens. You can define up to 32767 messages, but the overuse of this messages is not good pratice (more than two or three intro messages can be obnoxius for the player). After every message in this section, M.A.C. should halt and wait for a keypress or for a little time (see section [Events], statement pause), or the location image could override the message image.

The first line of every graphic message contains the message id number (from 1 to 15, beginning with the # character) and, eventually, tha filename of the graphic image (v. chap. 5). The following lines contain the text of the message. For example:

As you walk over the heavy double doors of the Rudolph Manor, your
voyage toward the unknows begins. In the darkness that hides traps
and danger you will walk. Will you find the Moonruby and leave this
doomed palace?

4.9: [Vars] Variables and Flags

In the [Vars] section you can define some variables (or flags) that can be freely used in the [Events] and [Actions] sections. The use of the variables is needed to realize an adventure more than trivial. You can define up to 32767 different variables, and every variable can assume values from 0 to 32767. When the game starts, all variables have value 0.

Every line of the [Vars] section contains the name of one or more variables, separed by commas. For example:


So I have defined four variables (upstair,drinked,counter and mar) which I will use in the [Actions] and [Events] sections.

Note that variables must have distinct names and that variables are identified only by the first 8 characters of the name (so this 8 character should differ from variable to variable). For example precipitated and precipitation are the same variable. Finally, the [Vars] section must preceed the [Events] and [Actions] sections, because you cannot use a variable that you haven't yet defined.

You can also use variables in messages and in descriptions. Just put in the message/description the variable name encosed by two % characters (this is the reason for the double % typing if you want a single %). Let's make an example:

After %turns% game turns you have solved the %score% %% of the adventure.

If turns variable has value 123 and score variable has value 42, when the message is displayed you'll see:

After 123 game turns you have solved the 42 % of the adventure.

Obviously you can use variables in the StatusLine message. Note that, unlike for event and actions, in messages and descriptions you can use variables still not defined.

4.10: [Events] and [Actions] Game engine

We have seen that M.A.C. handles automatically the most common actions that the character can do, like move in the fundamental directions, get and drop objects, show the inventory, and so on. Obviously the character's possibility are not so limited; the character should be able to do other actions, like pulling a lever, open a door or a chest, move a library. Also, it's possible that, depending on the situation but not on a specific action of the character, some events will happen, like the dawning or the crush of a filght of stairs.

This is handles in the [Events] and [Actions] sections; these sections are very similar, so we'll describe now both of them. The main difference between these section is this: events are elaborated before the command input (and obviously don't depend from the command) and usually all events are elaborated; actions are elaborated after the command input (and depend from the command), and usually just a single action (the first succesful action) is executed; also the "standard" actions (like pick up an object or move) are handled by M.A.C. only if no succesful ection is executed. Anyway, as we'll see, there's more than a way to avoid the "all the events and a single action" rule.

The [Events] and [Actions] sections are composed by condition lines (lines formed by a serie of conditions) and statement lines (lines formed by a serie of operations). Condition lines begin with the if, or or and keyword, while statemend lines begin with the then keyward (which is optional, but suggested), or the do keyword.

Condition lines beginning with the if statement are valid if and only if all the conditions forming it are true. Condition lines beginning with the and keyword are valid if all the conditions forming it are true and the previous condition lines are valid. Condition lines beginning with the or keyword are valid if all the conditions forming it are true, or if the previous condition lines are valid.

Statement lines are executed only if the previous condition lines are valid, or it the statement line doesn't follow a condition line (i.e. it's the first line in the section, or it follow another statemen line). Condition lines influence only the immediatly following statement line (or block, as we'll see later).

Pay attention: in a former M.A.C. version, the keywords 'if' and 'or' were synonimous (and there was no 'and' keyword), so one could write (deprecated habit) a serie of condition lines beginning with if and M.A.C. treated them as a single condition line begininning with if and a serie of condition lines beginning with or. This is'nt true anymore; statement lines following a series of if-beginning condition lines are executed only if the last line is valid. To obtain the desired result, the author have to write an if-beginning condition lines followed (if needed) by one or more or-beginning condition lines.

You can also use a condition line beginning with the while keyword (eventually followed by some and or or condition lines). In this case the following statement line (or the following block, as we'll see later) will be executed continously until the conditions following the while became false; we suggest that the statement line following the while should begin with the do keyword, instead ot the then keyword. The use of the while keyword is dangerous; it's behaviour is not easily predictable and it can lead to infinite loop that will halt completly the program. So use the while condition line only if strictly necessary.

Conditions and statements can be followed by one or two parameters (integer number, verbs, nouns or variable names); missing parameters are assumed to be 0. In every line there can be up to 8 conditions or statements. Both [Events] and [Actions] sections can contain up to a maximum of 32767 lines (conditions or statements) each.

The conditions are the following (stating when they're true):

beginThe condition is true only at the beginning of the game. This condition can't be used in the [Actions] section, and it's very useful to initialize variables and to show intro messages.
verb xThe x verb (x can be the verb id number or the verb itself) is part of the last command given by the player; obviously this condition has no meaning in the [Events] section, and every action should have a verb condition and, usually, a noun condition..
noun xThe x noun (x can be the noun id number or the noun itself) is the main (first) noun encountered in the parsing of the last command given by the player; again this condition has no meaning in the [Events] section.
noun2 xThe x noun (x can be the noun id number or the noun itself) is the second noun encountered in the parsing of the last command given by the player. Don't abuse of this condition; this condition has no meaning in the [Events] section.
noun3 xThe x noun (x can be the noun id number or the noun itself) is the third noun encountered in the parsing of the last command given by the player. The use of this condition should be very rare; again this condition has no meaning in the [Events] section.
anynoun xThe x noun (x can be the noun id number or the noun itself) is a noun encountered in the parsing of the last command given by the player (in any position). Be careful using this condition; again this condition has no meaning in the [Events] section.
move xThe command given by the player is a movement (in a fundamental direction) command. If x has value 1, the condition is true only if the movement is really possible. If x has value 2, the condition is true only if the movement is impossible. If x has value 0 (or any other value), the condition is true with possible and impossible movement. Even this condition depends from command input, and shouldn't be used in the [Events] section.
at xThe character is in the x location.
exist xThe x object is existent (is in some location, or in the inventory).
isin x yThe x object is in the y location.
carried xThe x object is in the inventory, but it isn't worn.
worn xThe x object is worn by the character.
owned xThe x object is in the inventory (carried or worn).
here xThe x object is in the current location (but not in the inventory.
present xThe x object is in the current location or in the inventory (carried or worn).
dark xThe x location (is x has value 0 or is missing, the current location) is dark and there aren't source of lights there.
eq x yThe x variable (x is a variable name) has value y.
gt x yThe x variable (x is a variable name) has value greater than y.
lt x yThe x variable (x is a variable name) has value lesser than y.
freeThe number of object in the inventory is lesser than the maximum number of object carriable (i.e. the character can carry at least one object more).
random x yThis condition is true randomly, with a probability of x/y (x possibility out of y). Obviously x must be lesser than y (or the condition will be always true) and greater than 0. If y has value 0 (or is missing) it will be considered 100.

If you put the keyword not before a single condition, you invert the meaning of the condition; i.e. the condition is true only if what stated above is false.

Furthermore a condition may be a single variable name (eventually after a not keyword). If this is the case, the condition is true if and only if the variable has a value greater than 0 (immediatly after a not keyword, obviously, the condition is true only if the variable has value 0).

This is a list of the statements:

create xThe x object is put in the current location.
destroy xThe x object is done "not existent" and removed from the game.
get xThe x object is put in the inventory (if the inventory isn't full, see condition free))
wear xThe x object is put in the inventory (if the inventory isn't full) and worn by the character.
put x yThe x object is put in the y location.
moveall x yAll objects that are in location x are moved to location y. If x is zero, the objects in current location are moved. If y is zero, the objects in location x are destroyed.
swap x yThe position of objects x and y is swapped; obviously, if one object doesn't exist, is created where the other is, and the other is destroyed.
go xCharacter is moved to x location.
at xThis is a special statement: it means that the next statement (only the next statement) will be evaluated considering x as the current location.
exit x yIf y is not equal to 0, this statement create in the current location an exit (in fundamental direction x) leading to the y location. If y is 0, then this statement remove the exit in fundamental direction x. The x parameter is a number that identify the direction as stated in the [Directions] section.
subst x yAll exits leading to the x location are changed in exits toward the y locazion. Is x is zero, exits leading to the current location are changed. If y is zero, all exits leading to x location are removed. This command can be used, along with the moveall command, to substitute a location for another.
light x yIf y is not equal to 0, then the x location is enlightened, even if it was defined as dark in the [Locations] section. If y is 0, then the location is dark. If x is 0, then the statement act on the current location.
message xThe x message is shown (see [Messages] section).
sysmsg xThe x system message is shown (see [Sysmsg] section).
show xThe x graphic message is shown (see [Shows] section).
mchoiche x yThe program ask the player for a numeric value between 1 and y (y can be between 2 and 9), and the result is assigned to the x variable (x is a variable name). If the player presses the esc key, the result is 0. If y is less than zero, obviously, the choiche is between 1 and -y, and furthermore the esc key is ignored.
bchoiche xThe program ask the player and yes/no question (see [System] section, boolean). Is the player answers yes, the x variable (x is a variable name) assumes value 1, else it assumes value 0.
pause xThe game pauses for x milliseconds or until a key is pressed. If x is less than zero, the pause lasts for -x milliseconds and key pressure has no effects. If x is zero, the pause lasts until a key is pressed. The behavior of this statement may vary depending on operative system and implementation.
quitThe game quits immediatly. It's used usually on character's death or at the end of the adventure.
set x yThe x variable (x is a variable name) assumes value y. If there isn't an y parameter, the x variable assumes value 1.
reset xThe x variable (x is a variable name) assumes value 0.
add x yThe value of the x variable (x is a variable name) is increased by y.
sub x yThe value of the x variable (x is a variable name) is decreased by y.
redescThe current location description is repeated.
clsClears the message area on screen.
haltQuits the elaboration of the following items in the section. In this way, M.A.C. doesn't consider the following events. This statement has no effect in the [Actions] section.
continueContinue to elaborate the following items. In this way the following actions (and the standar action handlad automatically by M.A.C.) are elaborated anyway and the next succesful action (only one, if it doesn't comprehend a continue statement) is executed. This statement has no effect in the [Events] section.
breakQuits the elaboration of the current block (see later), skipping to its end. If used in a nested block, only the innermost block is skipped.

The block is an important feature of the [Actions] and [Events] section. The block is a sequence of condition and statement lines which are considered as a single statement line. Using this feature, several statement lines could be influenced by a single condition line, and, most of all, the [Actions] and [Events] section can be structured in a more complex and complete way.

A block begins with a line containing just the begin keyword or, better, the { character (open brace), and ends with a line containing just the end keyword or, better, the } character (close brace); optionally a then or a do keyword can be placad befor the begin or the {. All statements and conditions included between these lines are considered like they are a single statement line. Furthermore, in the [Actions] section, a block is alwaye elaborated entirely (except for the halt and quit statements). If in a block is executed an action, the remaining of the block is evaluated and eventually executed, and the elaboration is halted only when the end of the block is reached (unless a continue statement is executed, or no statement lines are executed in block evaluation).

You can nest a block inside another block, up to 15 blocks nested. For this reason, you can put, at the beginning of any line, a free sequence of blacks and tabs. In this way you can put or augment the blank space at the beginning of the line when a block begins, and reduce it when a block ends, and have a visual idea of what is the block tha contain a certain statement. This pratice is called "indentation", and, although it's not obligatory, it's really raccomended.

There are two particular block types: If the block begins with the fbegin keyword or with the {/ characters, the actions elaboration will be stopped at the end of the block, even if no statement line was really executed. If the block begins with the sbegin keyword or with the {+ characters, the block execution (in [Actions] section) stops when a statement line is executed (but continues if non statement is executed in the block). These blocks ends with end keyword or } character.

Pay attention: in M.A.C. versions before 2.3 the actions elaboration was stopped after a block, even if no statement lines was executed (like the actual 'fbegin' or '{/' blocks). This is no longer true. If no statement lines is executed in a block, the actions elaboration continues. The .mac binary files made with former M.A.C. versions still works.

Some examples:

if at 4 present 1
then message 7 destroy 1

If in any moment the character is in location no. 4, and the object no. 1 is in that location or in the inventory, then message no. 7 is shown and the object is removed from the game.

if verb open noun door present 14
or verb push noun button present 16 present 14
then swap 14 15 message 5 exit 3 7
if verb close noun door present 15
then swap 14 15 sysmsg 10 exit 3 0

We assume that the verbs "open", "close" and "push" are defined. Object no. 14 is a closed door, object no. 15 is an open door, object no. 16 is a button. Noun no. 14 ("door") is related to both object no. 14 and 15, while noun no. 16 ("button") is related to object no. 16. The first action is triggered if the command is "open the door" and the door is closed, or if the command is "push the button" and both the button and the closed door are present; if one of this conditions is true, the closed door is replaced with the open door, message no. 5 ("the door opens") is shown, and an object toward east, leading to location no. 7, is created. The second action is triggered is the command is "close the door" when the closed door is present; in this case, the closed door is replaced with the open door, the system message no. 10 ("ok") is shown, and the exit toward east is removed.

if move dark
then message 7 continue
if move dark random 1 8
then message 6 quit

The first action is triggered when a movement command (N,S,E,O...) is given, and the character is in a dark location (without any source of light); in this situation the message no. 7 ("it's dangerous to move in the dark...") and M.A.C. continue to elaborate the actions. The following action is triggered when the characters tries to move in the dark, with a probability of 1 out of 8 (12.5%); when the action is triggered, message no. 8 ("you fall and break your neck...") is shown, and the game quits. If this action is not triggered, M.A.C. proceed to resolve automatically the movement command.

if not at 5
then set salcnt 0
if at 5
then add salcnt 1
if at 5 eq salcnt 2
then message 5
if at 5 eq salcnt 3
then message 6 quit

The salcnt variable (defined in the [Vars] section) is set to zero whenever the character isn't in the location no. 5. If the character is in the location no. 5, salcnt in increased by 1 every turn, and, when it reach the value 2, the message no. 5 (a warning message) is shown; when salcnt reach the value 3 (i.e. the next turn) the message no. 6 (that says that the character is dead horribly) and the game quits.

if verb wait noun 0
then { set count 5 while gt count 0 do sysmsg 9 pause 500 sub count 1 }

If the command "wait" (or similar) is given, the standard wait message is shown for 5 times, pausing each time. This is done putting the count variable to 5, and repeating (while) the 'show message - pause - decrement count by 1' sequence until the variable is zero.

if verb talk noun policeman present 8

message 11 mchoiche rsp 3
if eq rsp 1
then message 12
if eq rsp 2
message 13 mchoiche rsp 2
if eq rsp 1
then message 14
if eq rsp 2
then message 15 create 9
reset rsp
if eq rsp 3
then message 16
reset rsp
if verb talk noun policeman
then message 17

If the command "talk to the policeman" (or something similar) is given while a policeman (object no. 8) is presend, a block elaboration begins. First the message no. 11 (which contains three dialog options) is shown, and the player is requested to choose one option (mchoiche statement, the player can avoid the choiche hitting the esc key); the rsp variable assumes a value corresponding to the option choosen (1 to 3). If the player choose the first or the third option (i.e. if rsp has value 1 or 3), the program displays the message no. 12 or the message no. 16, without any other effects. If the second option is choosen (i.e. if rsp has value 2), begins the elaboration of a nested block. In this inner block, in a similar way, the program displays the message no. 13 (which contains two different dialog options), and the player is asked to choose (and the esc key is disabled); rsp is used again to contain the result value. If the player choose the first option, the message no. 14 is shown, while if the player choose the second option, the message no. 15 is displayed and the object no. 9 (a module, for example) is created. At the end of both blocks the rsp variable is resetted to 0, not to interere with the following commands. At the end of the outer block, the [Action] section elaboriation is ended (as usual, like if an action is succesfully executed); at the end ot the inner block, the elaboration is not ended, because the outer block elaboration should be completed. The last two lines are used when the "talk to the policeman" command is given when the policeman isn't present.

We have ended the description of the "programming language" used to write adventures. You can find more complete examples in the games distribuited with M.A.C.

5. Graphics

We have seen how [Shows] section messages and location can have a graphic image. The graphic version of M.A.C. has a "windows" for showing this images.

Every image must be in a separate file and an image can be used in more than one istance; we have seen how the image files can be specified in the [Shows] and [Locations] sections. The files that contains the images must be placed in the direcotory we launch M.A.C. from, or, even better, in a subdirectory specified with the ImagePath entry in the [System[ section.

M.A.C. images must have a very specific format: they must have a dimension of 384x256 pixel, in RGB (24 bit per pixel) or colortable up to 256 colors (8 bit per pixel); of these 256 colors the last 2 (254 and255) are system colors and shouldn't be used..

M.A.C. handles only png (portable network graphics) files with some semplification: only images with indexed color table (up to 256 colors), grayscale (up to 256 levels) or RGB (true color, 16 millons colors), always without trasparency (alpha) channel are admitted. Interlaced images are not handled. All optional information (i.e. the ancillary chunks) are ignored.

If you want you can also encode the images, so that a normal graphic program cannot read them, and distribute encoded images along with your games. The pngsrmb program (downloadable from M.A.C. home page) is made for this. The syntax is: pngsrmb imagename.png; if applyed on an encoded images, the program decode it. M.A.C., obvioulsy, handle encoded images.

A brief example: let's suppose you want to associate an image to a location (say, a library). You can draw the image with any graphic program, paying attention to the image size (384x256) and using a 256 color image palette (don't use truecolor images), and then save the image in your adventure directory with name library.png, specify this name in the [Location] section, in the entry of the proper location, and you're ready.

Finally let's remember, to ensue portability, to avoid uppercase character and spaces in images filenames.

6. Credits

M.A.C. was written in c using the Gnu GCC compiler
The compiler is subject to the GNU GENERAL PUBLIC LICENSE. You can find the theresaid license in the file gpl.txt

The 32bit dos versions are compiled using the DJGPP release, © 1995,1996 DJ Delorie.
The compiler, along with its sources and toolkit, can be downloaded from the DJGPP official Home Page: http://www.delorie.com/djgpp.

The native Windows versions are compiled using the MinGW (Minimal Gnu for Windows) release
The compiler, along with its sources and toolkit, can be downloaded from the MinGW official Home Page: http://www.mingw.org.

The graphic version of M.A.C was implemented using the GRX graphic Library, (c) Csaba Bielg.
The Library is subject to the GNU LIBRARY GENERAL PUBLIC LICENSE. You can find the theresaid license in the file lgpl.txt.
The library GRX v2.2, along with ist sources, can be downloaded from

The file management use the ZLIB compression library, (c) 1995-1998 Jean-loup Gailly and Mark Adler.
The ZLIB library can be downloaded from http://www.cdrom.com/pub/infozip/zlib.

Thanks to RikTik for his unvaluable debugging.

7. Licenze and Warranty

M.A.C. is released under the terms of the GNU General Public License (see gpl.txt file for details).

Every user can copy, use and distribute the software. He only has to grant the same rights to everyone that receives the software.

Every user can modify freely the software. In this case he only has to grant the same rights, and the rights to copy, use and distribute, to everyone that receives the modified software.

Every M.A.C. package must contain the following files: README.TXT, COPYING.TXT, CREDITS.TXT, gpl.txt and lgpl.txt, without any variation, except for the adding of a translation in another language.

This software is distribuited with NO WARRANTY. The author it's not responsible for any damage derived from the use of the software.