Alan
Adventure Language
Tutorial
Table of Contents
ii - Introducing the Alan System
ii.1 - Use any wordprocessor to write an adventurer1 - Tutor's Ramble 1 - About Source Code Layout
r1.1 - Why worry about layout ?VISITS
StatementLOOK
StatementINCLUDE
Statementlisting
' Option OBJECT
with Defined Syntax VerbsIF
and CHECK
Statements in VerbsIF
and CHECK
CHECK
s and 'take all'CHECK
s in ExitsTutor's Ramble 2 - Conclusion - What's still to do?
r2.1 - Beta TestingAppendix 1 - Sources of Further Information
a1.1 - The Alan Language manualWhen we talk about 'Adventure Games' in the context of the Alan Adventure Language we are talking about text adventure games or 'interactive fiction.' In text adventure games, descriptions of places and events are displayed on the player's computer screen. The player types commands to instruct the computer what should happen next. The computer then responds with a new description.
A well written text adventure game can be a lot of fun to play. It can be even more fun to create a text adventure game. A text adventure game can be written using almost any computer programming language. However, using a general purpose programming language (such as Pascal or C) to write an adventure game is a major undertaking. Fortunately there are people who think that writing adventure game programming languages is even more fun than writing adventure games.
There is a range of good adventure game programming languages available. Some are easy to use but have limited power while others are very flexible and powerful but difficult to learn. The subject of this tutorial is the Alan Adventure Language. Alan is powerful but easier to use than other modern text adventure programming languages. It is therefore an excellent choice for someone who wants to write good text adventure games but is daunted by the complexity of other languages.
The Alan programming language comes with a complete manual which contains all you need to know to use Alan. This tutorial is a supplement to that manual and is intended as an introduction to Alan for people who are new to the language. It takes the reader step-by-step through the creation of a small adventure game. Copies of the Alan programming code referred to in each lesson are included with the tutorial.
The reader of the tutorial should study the example code for each lesson and compile it after reading each lesson. I recommend that the reader also write their own example game as they work through the tutorial using the principles covered in each lesson.
This tutorial is only an introduction to the features of Alan. Once the reader has completed the tutorial, the reader should refer to the Alan Language Manual for comprehensive information about the language.
To use this tutorial the reader should have already obtained the Alan programming language and its manual. If you don't have Alan, see 'Appendix 1 - Sources' for information on obtaining the Alan Adventure Language.
Copy the example files for this tutorial into the directory (or 'folder') where you have put the Alan programming language files.
This tutorial is intended to be used with the versions of Alan that are current at the time of writing.- versions 2.7 and 2.8. Some of the information may not be accurate or some of the example files may not work correctly with other versions of Alan.
There are three components in the Alan Adventure Language system - the Alan manual, the 'Alan' compiler program and the 'Arun' game-player program.
The Alan programming language lets you write a text adventure by describing a collection of locations, objects and other items and by specifying a collection of commands the 'reader' or 'player' of your adventure can use to manipulate and move around the environment you have described.
This description can be written in any text editor or wordprocessor that can save files as plain or 'ascii' text such as Windows Notepad or DOS Edit on MSDOS PCs, vi on Unix machines or SimpleText on Apple McIntosh.
The document you create in your wordprocessor is called the 'source code' for the adventure. The text adventure's source code must of course conform to the Alan language specification or 'syntax' which is described in detail in the Alan manual. This tutorial doesn't provide the full syntax of the Alan language. The examples given illustrate just some of the features of Alan.
The file containing the source code needs to be 'compiled' by the Alan program. This creates a pair of 'game files' which can then be played using the Arun program. Of course you could never write the complete source code for an adventure then compile it once and be completely satisfied with the way the game plays with Arun. You will need to write and re-write the source code over and over as you fix problems and add enhancements to your game.
The source code you write with your text editor or wordprocessor is still just a text file. To turn it into an Alan adventure game the file needs to be 'compiled.' The compile process checks that the text is written in correct Alan syntax and then converts the human-readable text file into two Alan binary code game files.
This tutorial comes with a source code file called intro.ala
which you can compile now to test that you have got the Alan system set up properly. Compiling the intro.ala
source file will create two game files called intro.dat
and intro.acd
.
The DOS Alan compile program is called alan.exe
. For other computer systems the
filename may be slightly different - probably just ' alan
'.) The easiest way to
use alan.exe
is to put a copy of it in the same directory as your source files. (Note that
if you're using MS-DOS but not MS Windows you'll also need a file cwsdpmi.exe - see Appendix 1.2.)
Then, if you're not already there, go to your operating system's command prompt. (For example, on a
MSDOS PC, if your Alan program and source files are in a directory called "AlanPrgm" on your c: disk drive go to a DOS prompt, then enter c:
and then cd\alanprgm
)
Then to run a source file through the Alan compiler, enter
alan source
where source is the name of the source file without the 'file extension' part of the name. Alan assumes the source file name ends in .ala
(or .alan
on systems that use longer filenames than MS-DOS.) In our example the file is called intro.ala
so the command is
alan intro
That command should display some information on the screen and create files called intro.dat
and intro.acd
. These are the Alan game files for our test adventure which you can now play using the Arun program.
Appendix D in the Alan manual explains the options available when you compile your source code with the Alan compiler. You can also get a summary of options by entering alan -help
at the command prompt.
One particularly useful option is the -listing
option. When your source file contains errors (which it no doubt will at some time) the messages scroll off the screen too fast to study. Entering
alan source -listing
will produce a file called source.lis
(or source.list
) containing all the error messages which you can view to isolate where the problems are.
The trick is to fix the first error that the Alan compiler lists and then try compiling again.
Frequently one error has a cascade effect so that once the compiler encounters an error it is unable to understand the following source code even though that code may be perfectly correct.
Also, the cause of an error may be in an earlier line than the line of code that Alan reports as having a problem.
For example, if you leave out the end of one section of code, Alan will report an error at the start of the next section saying something like "um, sorry, you can't start a section here." So, to find the cause of a problem, always look at previous lines of code as well as the line reported to contain the error.
Having compiled a game successfully we can play it using the Arun program. The Arun program reads the .dat
and .acd
files created by the Alan compiler. To play the test adventure, intro, make sure you are at a command prompt and in the same directory as intro.dat
and intro.acd
, then enter
arun intro
at the command prompt. (Appendix D of the Alan manual explains the options available with Arun. Normally you don't need to use any of the options to play a game.)
So for other people to play your completed game, they need copies of the two game files (the .dat
and .acd
files) and also a copy of the version of arun.exe
that runs on their computer system.
A feature of the Alan language is that games can be played on a variety of operating systems. The .dat
and .acd
files created on one operating system can be played on any other system using the version of Arun for that other operating system. For example, if you create a game on an Apple MacIntosh, you could email the .dat
and .acd
files to a friend with a PC who would be able to play the game using the MS-DOS version of arun.exe
.
So normally when distributing a game you would send just the .acd
and dat
files along with instructions on where the player can get the appropriate version of Arun for their computer.
The absolutely most basic text adventure that can be written in Alan would name one location and specify that the adventure starts at that location. The Alan source code for such a basic adventure would look like this:
LOCATION ItsAPlace END LOCATION. START AT ItsAPlace.
This would be a very boring adventure game. No descriptive text would appear on screen. There would just be the word Itsaplace
displayed and a >
symbol on the next line prompting the player to enter a command. However there are no commands the player could use as none have been specified in the source code. There is not even a command to exit from the game. Pressing the Ctrl and C keys simultaneously will crash out of it on most versions of Alan. On the Apple MacIntosh version use Command-Q.
So lets elaborate the source code for our example text adventure a little before we look at how to compile and play Alan games.
Firstly we can add a second location so we can at least move between two places. We'll call it AnotherPlace
. (Note that the names for items in the Alan language cannot have spaces in them. You might want to use underscore characters in location names, eg: Another_Place
, to make them easier to read.)
LOCATION AnotherPlace END LOCATION.
We can decide that "AnotherPlace" will be to the north of our "ItsAPlace" location. To allow the player to move north from "ItsAPlace" to "AnotherPlace" we would add an EXIT
specification to the section of source code describing the "ItsAPlace" location:
LOCATION ItsAPlace EXIT north TO AnotherPlace. END LOCATION.
So the player can move back from "AnotherPlace" to "ItsAPlace" we could add an EXIT south
specification to the source code for "AnotherPlace"
LOCATION AnotherPlace EXIT south TO ItsAPlace. END LOCATION.
Someone playing this game would now be able to type north when they are at "ItsAPlace" to go to "AnotherPlace" and then south to move back from "AnotherPlace." However the player would not know this. The game needs to provide some information to the player about where they are. This is done by writing some descriptive text in a location DESCRIPTION
section such as this:
LOCATION ItsAPlace DESCRIPTION "You are at one particular place. From here you can go north to another place." EXIT north TO AnotherPlace. END LOCATION.
The text within double-quotes will be displayed on screen when the player moves to the location. A similar DESCRIPTION
section can be added in the code for "AnotherPlace:"
LOCATION AnotherPlace DESCRIPTION "You are now at another place. From here you can go south to the first place." EXIT south TO ItsaPlace. END LOCATION.
Try compiling this game with Alan. The source code is included with this tutorial in the file lesson1.ala
- so the command to compile it is
alan lesson1
You can then try playing it with Arun though remember you'll need to use ctrl-c to exit from the game. The command to play the compiled game is
arun lesson1
You could also write your own little two-location game with north and south 'exits' to go between the locations. You can write the game in any text editor or wordprocessor program. A wordprocessor is not the best as you must remember to save the file in plain text format and automatic word wrapping may mess up the layout of your source code.
If your game doesn't compile look for missing full-stops ('periods'). Just like sentences, all blocks of Alan code need a full-stop to mark the end. So EXIT
statements need to finish with a full-stop and the END LOCATION
lines need full-stops as well.
Now we have a nice little game but we had better add a command to exit from the game.
Commands the player can use are called "verbs" in Alan. The description of a verb in Alan source code looks like this
VERB verbname DOES these Alan instructions END VERB.
The Alan instruction (or 'statement') to stop Arun running a game and return to the computer operating system is QUIT
. So if we want the player to be able to enter the command finish when they want to stop playing a game, we would enter the following verb description in our source code file
VERB finish DOES QUIT. END VERB.
The stop-playing-the-game verb isn't the simplest first example of an Alan verb. It is mentioned first for two reasons. Firstly, it is a necessary command to finish playing a Alan game. Secondly, it provides an opportunity to introduce Alan's very useful SYNTAX
statement.
The problem with our 'finish' verb is that the definition of single-word commands in Alan is more complicated than what I've described so far. (If you've rushed ahead and tried compiling that command already you will have found that Alan produced a warning message when it compiled the source code.)
This is because most verbs in adventure games do something to an object. Examples would be "eat cake" or "get the cloak." So Alan, by default, expects verbs to be followed by another word which is the name of an object. (Don't worry if you don't know about objects - we don't talk about them for another few lessons.)
If we played our example game as it is now and entered the command finish Arun would reply "I don't understand" because Arun would be expecting another word after finish. This is because Alan would have compiled the game assuming that finish would always be followed by the name of an object - that's what the 'warning' message would've said. So we need to tell Alan that the verb finish makes sense as a single word command. This is done with a syntax statement which would simply look like this:
SYNTAX finish = finish.
This means the player will invoke the verb named on the left of the equals sign by typing the word, or words, on the right of the equals sign. For a single word verb like finish the syntax statement looks a little trivial. The syntax statement is, however, a powerful feature of Alan which is also used to tell Alan games how to interpret complicated phrases like 'pour the water from the bucket onto the campfire.'
So the complete definition of our stop-playing-the-game verb would look like this
SYNTAX finish = finish. VERB finish DOES QUIT. END VERB.
In adventure games the verb to finish playing a game is traditionally called quit. Most other types of software would use exit but this word could be used during an adventure game to, for example, leave a room so exit is not normally used to end a game. You could call your finish-playing-the-game verb anything you like but we will stick with tradition and use quit.
To make a command called quit available to the player we need to create a verb statement in our source code like this:
VERB 'quit' DOES QUIT. END VERB.
This means that when the player types quit the Arun program will execute the Alan statement QUIT. Coincidentally, the verb-name and the statement happen to both be 'quit'
Note that word quit has single-quote marks around it when used as a verb-name. This is because if the word was written without quotes as we did with the definition of our finish verb, Alan would assume the word was the Alan statement QUIT and putting an Alan statement next to the VERB statement makes no sense to the Alan compiler.
Similarly we need to use quotes in the syntax statement for the quit verb.
SYNTAX 'quit' = 'quit'.
Note that text within single-quote marks should always be entered in lower-case. (The reason for this is explained in the "Tutor's Ramble" below.)
Well that's it. We have now written the source code for a playable Alan text adventure game with two locations the player can move between and a command to quit the game.
Compile the example source code for lesson two and add a "quit" command to your own example game.
Before we go on to learn more about Alan, a few hints about the layout of source code files might be useful.
The aim of laying out source code in a tidy way is to make it easier for humans to read. The simple clear syntax of the Alan language leads naturally to more readable source code than many other languages but it still pays to write neat and tidy Alan source code.
The most important element of readable source code is to add comments to the source code to perhaps describe why things are done a certain way and so on. Even if you wrote it yourself, source code can look very unusual even a few days let alone years after you first wrote it. Remarks in Alan are lines of text starting with two hyphen symbols. The Alan compiler ignores any text on a line after two hyphen characters and doesn't attempt to compile it. For example the compiler would ignore these lines of source code:
-- T1.ala -- First Example of an 'Alan' Adventure -- Feb 96
The spacing between lines of code and between words is insignificant to the Alan compiler. Alan uses a full stop (or 'period') character to denote the end of all statements. You can, therefore, lay out the source code any way you like as long as you remember the full stop characters and that there is atleast one space between words.
It is a good idea to separate sections of code with blank lines so it is easy to see what code relates, say, to one location.
This piece of source code ....
SYNTAX 'quit'='quit'.VERB 'quit' DOES QUIT. END VERB. START AT ItsAPlace.
and this piece ....
-------Definition of Quit Verb ------ SYNTAX 'quit'='quit'. VERB 'quit' DOES QUIT. END VERB. ---------- Start Section ----------- START AT ItsAPlace.
are exactly the same to the Alan compiler but the second layout is much easier for human readers!
I've used a convention in the examples with this tutorial of typing Alan 'keywords' like location, syntax, end and verb in uppercase letters. It looks a little ugly but distinguishes the components of the Alan language from the writer's own item names and descriptive text. In the following example 'exit' and 'to' are Alan keywords:
EXIT south TO ItsAPlace.
Note that the case of letters is of no significance to the Alan compiler - EXIT and exit mean the same thing; ItsAPlace and itsaplace are the same location. The capitilisation is solely for the benefit of readability.
On the other hand, note that capitilisation is significant in text placed in single-quotes - for example in the syntax for the 'quit' command.
You should always write syntax in lower case because of the combined effect of two facts. Firstly, text in quote-marks is stored by the Alan compiler exactly as the game author typed it with the captilisation retained. Secondly, the Arun game-player program converts all player input to lower case before it analyses the input to figure out what the player means.
Remember that the text on the right of the equals sign in a SYNTAX
statement specifies what a player can input. If we had specified the quit syntax to be, for example,
SYNTAX 'quit' = 'Quit'
the user would be unable to enter the command as we would have specified that the player must type Quit with an upper-case Q and there is no way for the player, no matter what case they type their input on the keyboard, to actually enter an upper-case Q into Arun.
It is a good idea to indent the lines of code between the first and last lines of a section to visually separate that section. Indentation is particularly helpful when reading more complicated blocks of source code than we have looked at so far. A good example would be if-then-else statements which are described in a later lesson.
Our sample game will be a bit more interesting if we change the locations to something a bit more realistic than a vague "APlace" and "AnotherPlace". We can change the first location to a city street by renaming the location and changing the text in the DESCRIPTION
section.
LOCATION Street DESCRIPTION "Either side of the street is full of shops. The shops are a typical mixture of old houses converted into trendy boutiques and a few new glass-fronted shopping arcades. The exception is one house, to the north of you, which looks like a deserted house." EXIT north TO Porch. END LOCATION.
We can give the location a more descriptive name so that instead of 'street' being displayed we could have 'A City Street.' by adding a NAME
clause after the LOCATION
statement.
LOCATION Street NAME A City Street
If you want to use any Alan keywords in the NAME
then you need to enclose them in single quote marks.
LOCATION Street NAME A motorway 'exit' ramp
Arun
would display that as 'A Motorway Exit Ramp.'
Remember that if you want the player to be able to refer to the location by name the quoted text must be all in lower case. The player is not likely to use a location name in their commands but this is something to remember when naming objects and actors - which we'll discuss in a later lesson.
Normally, Alan will display any text in a nice tidy block with single spaces between words no matter how it appears in the source code. Sometimes however you may want to have the text formatted a specific way on screen.
This can be done by inserting special control strings in the text. Particularly useful are $n
to start a new line, $p
for a new paragraph (puts a blank line between paragraphs) and $t
to tab (or 'indent') text by four characters.
We could add the following to our "A City Street" DESCRIPTION
:
A sign on the front door says $p$tPrivate $n$tThis is my home$n$tDon't Annoy Me!"
When the game is played this would be formatted on screen like this:
A sign on the front door says Private This is my home Don't Annoy Me!
So far in this tutorial we've seen location DESCRIPTION
sections containing just a piece of text within double-quotes. Text within double-quotes are actually 'print-this-text-on-the-screen' Alan statements - think of them as PRINT
statements with the word PRINT
left out.
The DESCRIPTION
section of a location definition can also contain other types of Alan statements as well as double-quoted text. For example awarding points to the player for arriving at a location is specified in the source code with a statement added to the DESCRIPTION
section for the location.
Providing the player with points when they achieve certain goals in the game such as reaching a certain location or rescuing a distressed damsel adds to the interest in the game and provides the player with a measure of how well they are progressing through the game.
Points are allocated to a player with a SCORE
statement. For example if SCORE 5
is added to a location description, the player will be awarded 5 points the first time they visit that location.
LOCATION Porch NAME Front Porch DESCRIPTION "The unpainted wood of the porch is rotting and feels like it could crack under your weight at any moment. The front door of the house, however, seems newly installed and very strong." SCORE 5. EXIT south TO Street. END LOCATION.
(If that SCORE 5
statement is executed again, perhaps because the player visits the same location again, then nothing happens. The 5 points is only added to the score once.)
To display the current score use the SCORE
statement alone with no number after it. So we could display the score with our quit verb to let the player know how far through a game they are when they decide to finish playing.
VERB 'quit' DOES SCORE. QUIT. END VERB.
The player may also want to know the score while playing the game. So we can create a verb the player can use whenever they want to check their current score. Lets be predictable and call it the 'score' verb! The definition of this verb would then be something like this:
SYNTAX 'score'='score'. VERB 'score' DOES SCORE. END VERB.
Try compiling and playing lesson3.ala
- the lesson three example game. Try entering the score command and then move between locations and try the score command again.
One of the most important things an adventure game author can do to help someone enjoy his game is to allow multiple wordings for commands. This minimises the chance that the player must play a mini-game of 'guess the verb' to find the name the author has given to a command.
For example, if 'exit' is not used to leave a location somewhere in the game why not allow that word as an alternative to the 'quit' command? While hopefully players won't be leaving your game so often that they get tired writing 'quit', allowing the abbreviation 'q' is pretty traditional. Fortunately for the game author, you don't need to define extra commands called 'exit' and 'q' but simply list those words as alternatives for 'quit' in a 'synonyms' statement.
SYNONYMS q = 'quit'. 'exit' = 'quit'.
(Note that because exit is an Alan keyword - used to define exits from locations - it must be put in quotemarks when we define it as a player-enterable word. The letter q has no special meaning in the Alan language so quote-marks are not required.)
Synonyms can be defined for any word a player might type while playing a game. Defining abbreviations for direction commands are probably the most helpful because they will probably be the commands players most frequently type.
SYNONYMS n = north. s = south.
(Note that, as in the example above, you can list the synonyms for more than one command in one synonym statement. I prefer to define synonyms for each verb with its own separate synonym statement next to the verb's syntax statement. I find it easier to keep track of things that way.)
Its probably worth noting here that EXIT
names don't have to be compass directions. You could define exits called up, in, exit or shazam for example.
VISITS
Statement Like synonyms, another feature that often improves the playing experience is to not redisplay a location description when the player revisits a location.
By default, Arun always displays the location description. The game author can change this by using the VISITS
statement. If VISITS 99
(or any other big number) appears in the START
section of a game, after the initial visit, a location description won't be redisplayed until the player has revisited that location 99 times - effectively it will never be redisplayed.
START AT Street. VISITS 99.
LOOK
Statement At some point after the initial visit the player may want to see the location description again. The LOOK
statement prints the description of the current location so we can create a verb containing the LOOK
statement so the player can redisplay a location's description whenever they wish. Like the quit and score verbs, the look verb name and Alan statement the verb executes will be the same so we have to put single quote-marks around the verb name.
VERB 'look' DOES LOOK. END VERB.
Also, because it is a single-word verb we need a SYNTAX
statement to tell Alan that the verb makes sense on its own. And, as it will be a commonly used command players will appreciate it if we defining an abbreviation with a synonym statement.
SYNTAX 'look'='look'. SYNONYMS l='look'.
Players may not always want VISITS
set to 99. At times they may want the location description displayed every time they visit a location. This setting in a text adventure game is traditionally called 'verbose' mode. The opposite is known as 'brief' mode.
We can define brief and verbose verbs to let the player switch between the two modes as they wish. The verbs will execute a visits
0 and a visits
99 statement respectively.
VERB brief DOES VISITS 99. END VERB. VERB verbose DOES VISITS 0. END VERB.
Note that single-quote marks aren't required around the brief and verbose verb names because they are not Alan keywords.
Of course, syntax definitions are required for both the brief and verbose verbs because they are single-word commands. A few synonyms might also be appreciated by the player. So we need something like this in our source code:
SYNTAX verbose=verbose. SYNTAX brief=brief. SYNONYMS short=brief. full=verbose.
Verbs can display text as well as executing Alan statements. This is simply done by putting the required text (inside double-quote marks) in the DOES
section of the verb definition.
To display a brief or verbose mode confirmation when the player uses the brief and verbose verbs we could modify the verb definitions like this:
VERB brief DOES VISITS 99. "$pDescriptions will only be displayed the first time you visit a location$p" END VERB. VERB verbose DOES VISITS 0. "$pDescriptions will be displayed each time you visit a location$p" END VERB.
It can be a bit confusing when to use double or single quote-marks in your Alan source code.
The text that will be displayed on screen during the play of a game (such as location descriptions) should be written within double quote marks in the source code. Remember, double-quoted strings are actually 'print-this-text' Alan statements - PRINT
statements with the word PRINT
left out.
Single-quote marks around the names of locations and verbs etc are used in the source code to distinguish those names from Alan keywords that happen to be spelt the same.
$INCLUDE
Statement Our example game is getting a little big to be quickly read so we will now make use of a nice feature of Alan called 'include' files. Alan allows the author to split the source code into two or more text files but compile the multiple files as if they were a single big file by using $INCLUDE
statements. A $INCLUDE
statement can appear anywhere in the source code for a game and looks like this
$INCLUDE 'filename'
If Alan finds an $INCLUDE
statement in a source file while its compiling, the text in the second file is compiled into the game as well.
One of the main benefits of the $INCLUDE
statement is it allows game authors to split source code into more readable chunks. For example, we can save the verb definitions created in earlier lessons into a separate file so the example source code for this lesson doesn't become too cluttered.
The library1.ala
file contains the definitions for the look, brief, verbose, score and quit verbs. If we put the statement $INCLUDE 'library1.ala'
into the example source code for lesson five, all those commands will be compiled just as if they had been typed into the lesson5.ala
file.
The other main benefit of the $INCLUDE
statement is that chunks of useful source code like those basic commands can be used in any number of games. Such chunks of code are referred to as 'libraries.' You can write your own libraries or make use of code that other people have written to instantly add features to your own programs.
There are a couple of examples of libraries at the Interactive Fiction Archive which you may like to look at. (Look in the 'Sources' appendix to his tutorial for details.) The 'Etudes' contain a file called SHELL.ALA
which contains some features shared by all the Etude examples. There is also a file called STANDARD.ALA
which defines an extensive range of standard verbs and other features. This library won't compile without modification and most of the verb definitions don't actually do anything but it gives a good idea of what sort of things an author may need to program in a complicated game.
So far in this tutorial we've discussed the definition of locations and verbs. The third main component of an adventure game definition is 'objects' - things which the player can perhaps pick up and manipulate in some way during the course of the game.
The basic definition of an object called 'note' would look like this
OBJECT note END OBJECT.
An object's initial location in a game is specified with an AT
statement. The following example will place the note at the city street location
OBJECT note AT street END OBJECT.
Alan automatically adds a message to the location's description - "There is a 'objectname' here." The author can change this message to something else but we'll leave that until the next lesson.
The game author must specify some new verbs to enable the player to interact with objects. For example, the player will normally expect to be able to pick up and put down objects.
In adventure game terminology, when a player gathers objects it is said that a player is adding objects to the player's 'inventory.' For a player to pick up the note we have placed in our Street we need a verb that moves the note from the street to the inventory. So a command called 'take' to allow a player to pick up an object could be defined like this
VERB take DOES LOCATE OBJECT IN Inventory. END VERB.
The verbs we defined in earlier lessons required a syntax statement. The 'take' verb doesn't require a syntax definition because it conforms to the default Alan verb syntax of the 'verbname' being followed by an 'objectname.' By default, when a player types a verb name Alan expects it to be followed by the name of the object which the verb will be applied to. (For example: 'eat the cake' and 'shoot rabbit'.)
The word OBJECT
in the DOES
section of the verb definition is a reference to whatever object the player mentioned after he wrote the word 'take.' So if the player wrote "take note" then the DOES
clause will mean 'LOCATE note IN Inventory'
LOCATE
is an Alan statement that means place the object at the following location. In the case of the 'take' verb that location is 'Inventory.' Alan automatically defines an object called 'Inventory.' It is a 'container' that the player always has with them for holding objects they collect during an adventure game.
To allow the player to put things down again we can define a 'drop' verb
VERB drop DOES LOCATE OBJECT HERE. END VERB.
The DOES
part of this verb is very similar to that of the 'take' verb except instead of 'IN Inventory'
there is just the word 'HERE'
. HERE
is another Alan keyword. It means 'the location where the player currently is.' So this DOES
clause will remove the object the player mentioned from the 'Inventory' object and put it at the current location.
The player may find an 'inventory' command to list their collection of objects useful. Because there is already a container object called 'inventory' pre-defined in the game we can't name a verb called 'inventory.' It's not the same as using an Alan keyword as a verbname where quote marks around the name solves the confusion. In this case we would have two entities, one a container and one a verb, with the same name. That is a situation that Alan could not compile. So we'll simply name the inventory verb something else - for example 'list_inventory' - but define the syntax for it (ie: the command that the player types) as 'inventory'.
SYNTAX list_inventory= inventory.
The player will probably get tired writing 'inventory' all the time so defining an abbreviation, such as 'i', with a synonym statement would be a good idea.
The Alan statement 'LIST containername'
means list the names of the objects in the specified container. So the definition of the 'list_inventory' verb could be
VERB list_inventory DOES LIST Inventory. END VERB.
The Alan system doesn't dynamically create and destroy objects during the playing of a game.
Often, though, a game author will want the player to think objects are being created or destroyed - for example when the player waves a magic wand a white rabbit appears at the current location or when the player eats the chocolate bar the bar should no longer be in the player's inventory. However, like a magician, the game designer cannot really create and destroy things but only make them appear and disappear - in the game designer's case - with the LOCATE
command.
All the objects that will appear in a game need to be defined by the author. The Alan author can simulate the creation of an object by leaving its initial location undefined - by leaving out the 'AT'
clause in the object's definition, eg:
OBJECT rabbit END OBJECT.
Then a certain verb or event can place the object where the player can see it - hey presto!, an object appears to be 'created'
VERB shazam DOES LOCATE rabbit IN tophat. END VERB.
To destroy an object it must be moved out of the player's view, to a location inaccessible to the player. The author can define a location - called 'nowhere' for example - which he can move destroyed objects to. If there are no other locations with exits leading to that location, the player will never see the 'destroyed' objects again.
If we define a 'Nowhere' location, we can define an 'eat' verb which 'destroys' the object the player eats by moving it to 'Nowhere.'
LOCATION Nowhere END LOCATION. VERB eat DOES LOCATE OBJECT AT Nowhere. END VERB.
When the player types 'eat note' nothing much will happen. He simply gets the normal >
prompt asking for his next command. Only if the player does an 'inventory' will he see that the object is no longer in his possession. So we should add some descriptive text to the eat verb so the player knows what has happened.
VERB eat DOES LOCATE OBJECT AT Nowhere. "The note is surprisingly tasty. But, now that you think about it, eating it was rather pointless." END VERB.
That 'eat' verb definition is not quite right. If the player tries to eat some other object a message about the 'note' object will be displayed - something the player will find a bit puzzling.
Frequently, like the eat verb, the player may like to try actions that only make sense for certain objects or have unusual results if the player tries them on certain objects. The Alan language handles these object-specific actions by allowing the definition of verbs within object definitions.
So far in this tutorial we have always placed verb definitions in the main body of the source code. By entering a verb definition within an object definition, the game author can define verbs that apply only to specific objects.
You can also define a verb within a location definition so that it applies only when the player is at that particular location.
So we can define the eat verb within the note object definition like this
OBJECT note AT Street VERB eat DOES LOCATE Note AT Nowhere. "The note is surprisingly tasty. But, now that you think about it, eating it was rather pointless." END VERB. END OBJECT.
So now, if the player tries to 'eat the note', the verb's DOES
clause will be executed. If the player tries to eat some other object, a default Alan message - 'You can't do that' - will be displayed.
You can also give the player some points for performing an action by putting a SCORE
statement in the verb's definition.
VERB eat DOES LOCATE Note AT Nowhere. "The note is surprisingly tasty. But, now that you think about it, eating it was rather pointless." SCORE 5. END VERB.
This is a 'good' example of bad programming - the text says "rather pointless" and then we proceed to give five points to the player with the SCORE 5
statement. This sort of problem can easily sneek in when writing a game. Although it is perfectly good Alan code so it will compile just fine, its a 'bug' from the player's point of view. Hopefully the game author will notice it while they or someone else is testing the game. The author can then rectify it by removing the score statement or making the text more appropriate - perhaps like this:
VERB eat DOES LOCATE Note AT Nowhere. "The notepaper tastes awful. You only just succeed in swallowing it without choking but now you know that the message can not fall into enemy hands." SCORE 5. END VERB.
As well as creating and destroying objects, the game author can simulate changes in an object by replacing one object with another. In the following example if the player eats the apple he is carrying, the apple object is moved to 'nowhere' and the 'applecore' object appears in the Inventory instead.
OBJECT apple IN Inventory END OBJECT. OBJECT applecore END OBJECT. VERB eat DOES LOCATE apple AT Nowhere. LOCATE applecore IN Inventory. "You munch happily on the crisp apple until you're left holding nothing but the core." END VERB.
'-listing'
Option You may notice when you compile the sample game for lesson five that the Alan compiler reports that there were four informational messages.
"Well, where are these messages?" you might think.
The messages aren't displayed on screen because they're unimportant default messages that shouldn't cause you any concern. But you can see them by running the Alan compiler again with the '-infos'
option. You will probably then get too many messages to read before they scroll off the screen so you can also use the '-listing'
option to view all the messages generated by the compiler - you can abbreviate it to -l
like this
alan -l lesson5
The -listing
option, you may recall from the introduction, produces a text file containing the messages generated by the Alan compiler. If you open the file lesson5.lis
with your text editor you'll see that the 'informational messages' are telling you that the Alan compiler assumed that the object verbs we defined use the default Alan syntax and that the location 'Nowhere' has no exits. Interesting stuff but no cause for concern because that is what we intended.
Remember, though, that the '-listing'
option becomes very useful when your source code has so many errors that you can't see all the messages scrolling up the screen when Alan attempts to compile the code.
When the player enters a command you will want the game to check that the command is reasonable. The Alan system checks some obvious things automatically - for example if the player tries to pick up an object that isn't at the current location, Arun replies that the object can't be seen. The author may want to do other, more complicated checks - to see if objects are edible, readable or too heavy to lift for example. This can be done by defining object 'attributes'.
Lets place a couple more objects in the street:
OBJECT Tin AT Street CONTAINER IS NOT Takeable. END OBJECT. OBJECT Bomb AT Street IS NOT Takeable. DESCRIPTION "There is bomb securely bolted to a lamp post." END OBJECT.
You will notice that these object definitions both include a phrase IS NOT Takeable
and the rubbish tin definition includes the phrase CONTAINER.
These are example of object 'attributes.' The container attribute is a special built-in Alan attribute that we will discuss at the end of this lesson. 'Takeable' on the other hand is an object attribute that I have simply made up. Default object attributes are created by entering a section like this anywhere in the Alan source code:
OBJECT ATTRIBUTES Takeable.
After takeable
you could list any other attributes you might want to use in the game such as edible, eatable, sticky or whatever.
All objects in the game will have the attributes listed under OBJECT ATTRIBUTES
by default. So all objects - such as the 'note' - in our game will be 'takeable' by default. If an object should have other than the default state of an attribute the author can over-ride the default in the object definition. In our example game the player is not allowed to pick up the bomb or rubbish tin so they have IS NOT Takeable
in their definitions.
You can also use attributes that aren't relevant to all objects
by specifying them just in the objects that need them. For example
you might want one object, perhaps a glob of glue, to be 'sticky' until
it dries out. You can define a 'sticky' attribute for the glue object
just by adding the phrase IS Sticky.
to the definition
of your 'glob of glue' object:
OBJECT glob NAME glob 'of' glue AT Street IS NOT Takeable. IS Sticky. END OBJECT.
Because it isn't defined in the OBJECT ATTRIBUTES
section, the 'sticky' attribute is undefined for other objects. Therefore
you can't check the stickiness of objects in global verbs. Only verbs within
the definition 'glob of glue' object will be able to use the 'sticky'
attribute.
Attributes don't have to be either on or off - 'IS'
or 'IS NOT'
. You can also define attributes that
hold a value - either a number or a text string. For example:
OBJECT ATTRIBUTES Weight 1. Colour "blue". OBJECT glob NAME glob 'of' glue AT Street HAS Weight 0. HAS Colour "white". END OBJECT.
You can read more about attributes in section 3.3 of the Alan manual.
Object attributes become useful when we incorporate attribute 'checks' in our verb definitions. For example, to make use of a 'takeable' attribute we would check that an object was 'takeable' in the definition of the 'take' verb.
VERB take CHECK Object IS Takeable ELSE "You can't take that." DOES LOCATE OBJECT IN Inventory. "Taken." END VERB.
So when a player tries to take an object by typing 'take note' for example, the 'take' verb now checks to see if the object has the Takeable
attribute. If so, the DOES
part of the verb definition is executed. If not the ELSE
part of the CHECK
is executed and the rest of the verb definition is ignored.
You can string a variety of checks together in one verb with AND
between the checks. All the checks must be passed if the DOES
part of the verb is to be executed.
VERB take CHECK Object IS Takeable ELSE "You can't take that." AND OBJECT NOT IN Inventory ELSE "You already have it." DOES LOCATE OBJECT IN Inventory. "Taken." END VERB.
We haven't defined a syntax for 'take' in earlier lessons because the 'take' verb follows the default Alan syntax of 'verbname followed by an objectname'. For some purposes an author may want to define the syntax for a 'verb object' verb.
The standard syntax for a take verb, if it was required, would be something like this
SYNTAX take = take (obj).
We haven't seen a syntax with a word in brackets before. This means that the syntax for the 'take' verb is the word 'take' followed by any other word that the player types in and lets call that second word obj. The object names the player types when entering a command are called verb 'parameters.' We can use the 'obj' parameter in verb CHECK
s and so on where we previously had the keyword OBJECT
. Like OBJECT
, the 'obj' parameter refers to whatever game object the player named after the word 'take' in their command input.
VERB take CHECK Obj IS Takeable ELSE "You can't take that." AND Obj NOT IN Inventory ELSE "You already have it." DOES LOCATE Obj IN Inventory. "Taken." END VERB.
We can interchange the use of OBJECT
(which, by default, is the Alan parameter that refers to the first object mentioned in the player's input) and Obj
(or whatever else you define in your 'take' SYNTAX
statement). You may prefer to still use the keyword OBJECT
for simple verbs like 'take' so that the take verb looks similar to other verbs like 'read' or 'eat' which don't have a syntax defined and therefore use the default OBJECT
keyword. It would probably make your source code more readable though to use the parameter name you've defined if a verb does have a SYNTAX
statement.
You might be wondering why you might want to define the syntax for a verb that uses the default 'verb object' syntax. One reason is to allow the use of multiple objects with the verb.
For some verbs, such as take, the player may want to perform the verb on more than one object at a time. For example, the player may want to type "take the salt and the pepper" or "take all". If the player tried this in a game where the 'take' verb used the default syntax the game would reply "You can't refer to multiple objects with 'take'."
The author can allow the player to refer to multiple objects with a verb by adding an asterisk after the object parameter name in the SYNTAX
statement. For example, in the case of the 'take' verb, we would simply add an asterix to the end of the SYNTAX
definition.
SYNTAX take = take (obj)*.
As with locations, we can give objects more descriptive names by adding a NAME
clause after the OBJECT
statement.
OBJECT Tin NAME Big Rubbish Tin AT Street
The default description of this object will now be 'There is a big rubbish tin here' and the player can refer to the object with its full name - for example 'take big rubbish tin'. Arun assumes that the last word in the NAME
phrase is a noun and any words before it are adjectives. It allows the player to refer to the object by just the last word, the 'noun' - eg 'take tin' - or with any or all of the adjectives as well - eg: 'take big tin' or 'take rubbish tin' - and it even accepts the adjectives out of order - eg 'take rubbish big tin'
Remember that if a word in the NAME
clause is enclosed in single quote-marks (perhaps because the name contains an Alan keyword) the word has to be in lower case so the player can use it. For example
OBJECT Counter1 NAME 'check' 'in' counter AT Airport
You can add even more ways the player can refer to an object by defining synonyms for the object's name or for the words in the NAME
clause if the object has one. You define synonyms for object names or adjectives the same way we've defined them for verbs in earlier lessons. For example
SYNONYMS can = tin. garbage = rubbish.
The player can now refer to the tin as a 'can' or a 'garbage can' or a 'garbage tin' or a 'big garbage can', etc.
IF
and CHECK
Statements in Verbs As well as using CHECK
statements to check if using the verb makes sense in the current circumstances (and displaying some text if it doesn't), the game author can use another type of Alan statement, the IF
statement, within a verb's DOES
section to enable the verb to do different things depending on the circumstances.
Let's use the 'read' verb for the 'note' object to illustrate the difference between CHECK
and IF
statements.
The 'read' verb could contain a CHECK
statement to see if the player has the object.
VERB Read CHECK OBJECT IN Inventory ELSE "You don't have that." DOES "Its just someone's old shopping list scrawled on the notepaper." END VERB Read.
If the player doesn't have the object then the CHECK
would not be 'passed' and the "You don't have that." message would be displayed. The remainder of the verb definition, including the DOES
section, would not be executed.
You could be kinder to the player by defining an IF
statement within the DOES
section of the verb to automatically pick up the note if the player tries to read the note when they don't already have it.
VERB Read DOES IF Note NOT IN Inventory THEN LOCATE Note IN Inventory. "(You pick up the piece of notepaper.)$p" END IF. "Its just someone's old shopping list scrawled on the notepaper." END VERB Read.
With this verb definition, if the player tries to read the note when he's not already holding it, the following will be displayed
> read note (You pick up the notepaper.) Its just someone's old shopping list scrawled on the notepaper. >
IF
and CHECK
The difference between CHECK
and IF
statements is that CHECK
statements are used before the main DOES
section of a verb to verify that the circumstances are suitable for executing the rest of the verb while IF
statements are used within the DOES
section to allow the verb to do various things depending on various circumstances.
CHECK
statements don't offer as much programming flexibility as IF
statements because if a CHECK
is not passed then the remainder of the verb definition is not executed. On the other hand, if the result of an IF
statement is just going to be a 'you can't do that' type of message it would be better to use a CHECK
statement.
CHECK
s and 'take all' For example using CHECK
s rather than IF
statements in the 'take' verb makes the command 'take all' work better. Arun will perform the verb on all objects that are available at the current location, except the ones that don't pass the CHECK
s for the verb. So by using CHECK
s instead of IF
statements, the ALL mechanisms will be much more natural:
We defined the take verb like this using CHECK
s
VERB take CHECK OBJECT IS Takeable ELSE "You can't take that." AND OBJECT NOT IN Inventory ELSE "You already have it." DOES LOCATE OBJECT IN Inventory. "Taken." END VERB.
Instead we could've defined it like this using IF
s
VERB take DOES IF OBJECT IS NOT takeable then "You can't take that!" ELSIF OBJECT IN Inventory THEN "You already have it." ELSE LOCATE OBJECT IN inventory. "Taken." END IF. END VERB.
But if many 'not takeable' objects were at the current location that second definition of the verb could result in an untidy response like this to 'take all'
> take all (air) You can't take that! (sky) You can't take that! (ground) You can't take that! (shirt) You can't take that! (pants) You can't take that! (wicker basket) You can't take that! (old radio) You can't take that! (office chair) You can't take that! (snub nose gun) Taken.
Because when processing multiple objects, CHECK
messages aren't displayed, using our CHECK
s version you would get the following
> take all (snub nose gun) Taken.
So far we've defined verbs that involve no objects (eg: 'quit') or one object (eg: 'read') now we'll define a verb with two objects. Using a SYNTAX
statement we can define complicated phrases like 'put the fruit in the bowl' (A player always has the option of typing 'the' in front of an object name. Arun ignores such words so they don't have to be separately specified in the SYNTAX
statement.)
SYNTAX put = put (obj1) in (obj2)
A simple 'put' verb could then be defined like this
VERB put DOES LOCATE obj1 IN obj2. END VERB.
Note how we are now using the bracketed words in the SYNTAX
statement in the verb definition. The bracketed words or 'parameters' are the way to identify the objects the player mentioned in their command.
Of-course we should add some CHECK
statements to the verb to make sure the player is attempting something that is currently possible
VERB put CHECK Obj1 IN Inventory ELSE "You don't have the $1." AND Obj2 HERE ELSE "The $2 is not here." DOES LOCATE obj1 IN obj2. END VERB.
The second CHECK
in the example above - "AND Obj2 HERE"
- is not necessary as, by default, Alan only allows the player to refer to objects at the current location anyway.
I added that redundant check to help illustrate another Alan feature. You will notice the use of $1
and $2
in the quoted text in that example. These two phrases refer to the first and second parameters in the SYNTAX
statement - obj1
and obj2
respectively. For example, if the player typed 'put the note in the tin' and the player didn't currently have the note, the "Obj1 IN Inventory" CHECK
would not be passed and the text "You don't have the note" would be displayed by Arun.
The recommended alternative to using $1
and $2
in text is to use a SAY
statement. The statement SAY obj1
. would display the name of the first object referred to by the player. So an alternative way of defining the above 'put' verb would be
VERB put CHECK Obj1 IN Inventory ELSE "You don't have the" SAY obj1. "$$." --($$ means don't insert a space here) AND Obj2 HERE ELSE "The" SAY Obj2. "is not here." DOES LOCATE obj1 IN obj2. END VERB.
I find that a bit long-winded so, being a bit lazy, I stick to using $1
and $2
etc. One difference between using $1
etc and SAY
is that $1
echoes the text the player used to refer to an object but 'SAY Obj1'
etc uses the object's defined name. The author can choose which effect is more desirable in different circumstances and choose one or the other method.
For example, the player could type 'put message in the tin' as "message" is a synonym for "note". If the 'note' object wasn't at the player's location and the author had used SAY Obj1
the response would be "You don't have the note", if the author had used $1
the response would be "You don't have the message".
We can also add some checking to the SYNTAX
definition. 'Syntax checking' is done using a WHERE
statement. At the SYNTAX
definition level you can check that the player is using the right types of objects in the right order in the command. For example, the statement 'WHERE obj1 ISA Object'
checks that the player hasn't entered, for example, the name of a location when only the name of an object makes sense
SYNTAX put = put (obj1) in (obj2) WHERE obj1 ISA Object ELSE "You can't do that." AND obj2 ISA Container ELSE "You can't put things in there."
You could check some of those sorts of things using CHECK
s in the start of the verb definition or even IF
statements in the DOES
part of the verb but it is more logical to check that the right type of words are being used at the very beginning of the process of deciphering what the player is trying to say.
Furthermore, syntax checks are an important aid to avoiding 'run-time errors.' Run-time errors are problems, such as dividing a number by zero, that can occur when a program is executed even though the program's source code was valid and compilable.
Attempting to put one object into another object that isn't a container is an example of a run-time error that could occur in an Interactive FIction program. The Alan compiler tries to detect any source code which might result in run-time errors and refuses to compile it. The author's syntax checks assist the Alan compiler to perform this source code verification. For example, because we defined obj2
as a container in the syntax for the 'put' verb, the Alan compiler will allow Alan statements like LIST
and EMPTY
to be used in association with obj2
in the 'put' verb otherwise the compiler would not.
When we defined the 'list_inventory' verb we used the LIST
statement to display the contents of the 'inventory' object. LIST
can be used to display the contents of any container. We can add the statement LIST Tin
to the DESCRIPTION
section of the 'tin' object so the contents of the rubbish tin are included in the 'street' location description.
OBJECT Tin NAME Rubbish Tin AT Street CONTAINER IS NOT Takeable. DESCRIPTION LIST Tin. END OBJECT.
If there is nothing in the rubbish tin, the default text "The rubbish tin is empty'"appears in the location description. When playing the example game for lesson six, try putting the note into the rubbish tin and then using the 'look' command to see the effect of the LIST
statement.
Because we're not looking at them in this lesson some more of the verbs we defined in earlier lessons have been taken out of the main example file and added to the verbs in library1.ala
to make library2.ala
.
( Library2.ala
is $include'
d into the lesson7.ala
file.)
A player may not want to play the whole game at one time. The Alan SAVE
and RESTORE
statements allow the player to record where they got to in a game and return to that point at a later time. SAVE
records the current state of the game (eg: player's current location, value of object attributes, etc) to a disk file. RESTORE
reads a previously saved disk file and restores all the game attributes to the recorded state.
As with the QUIT
statement we need to create simple verbs to allow the player to use SAVE
and RESTORE
.
SYNTAX 'save'='save'. VERB 'save' DOES SAVE. END VERB. SYNTAX 'restore'='restore'. VERB 'restore' DOES RESTORE. LOOK. END VERB.
The 'restore' command includes a LOOK
statement to display the description of the player's location after the restore. This isn't essential but its most likely the player will need a reminder of where they were at when they last saved the game.
See the START
section in the lesson7.ala
file for an example.
In previous lessons the START
section of the game only contained the VISITS
statement. Other statements can go in the START
section too and, of course, some text to introduce the game is a good idea. You can put in a game title and copyright information as well as a paragraph or two to set the scene for your game.
The player will normally expect to be able to take a closer look at any objects in the game. If an object is mentioned in the location description the player will probably try to examine it.
So for each defined object we should define an examine verb which describes it in detail.
OBJECT Control NAME Remote Control AT Hallway DESCRIPTION "There is a home-made electronic remote control here." VERB Examine DOES "The remote control has two large buttons. One button is made of green plastic, the other is red." END VERB. END OBJECT Control.
Local verbs, defined within an object or location, can be used in combination with global definitions, defined in the main body of the source code.
A common example of this approach is the examine verb. With some objects there may be nothing worth saying about it except what is already described in the location description. We can define a default examine verb outside any object definition that will apply to all objects.
VERB Examine DOES "There is nothing significant to say about the $1" END VERB.
That introduces a problem when the player examines an object that does have a specific 'examine' verb defined. Normally, when there is both a global and 'local' object definition of a verb Arun will execute first the global verb and then the object one. So in this example the following contradictory text would be displayed
There is nothing significant to say about the control. The remote control has two large buttons.
One button is made of green plastic, the other is
red.
So we need to tell Arun to only execute the object-specific verb. This is done by adding the keyword ONLY
to the object's verb definition.
VERB Examine DOES ONLY "The remote control has two large buttons. One button is made of green plastic, the other is red." END VERB.
There is another example of a verb defined for an object in the example game for this lesson. In previous examples if a player tried to 'take' the bomb a message "You can't take that" was displayed because the bomb object was defined as ' IS NOT takeable
'. We can make the bomb 'takeable' by removing the ' IS NOT takeable
' statement. The bomb will then become 'takeable' as that is the default for all objects as specified in the OBJECT ATTRIBUTES
statement at the start of the source code. We can then define a 'take' verb within the bomb object definition which describes the disastrous consequences of trying to get the bomb and then ends the game - by using the QUIT
statement.
VERB Take DOES ONLY "The vibrations as you try to remove the bomb from the lamp post upsets its delicate internal mechanism. The bomb explodes.$p$p You have lost the game.$p" SCORE. QUIT. END VERB.
In some cases it is useful to have both the global and local definitions of a verb execute. In such cases you wouldn't have an ONLY
clause in the local verb definition.
For example, the verb 'read' could have global definition that checks whether the player has the object and if not, automatically picks it up while a local definition within each object displays what's written on that particular object.
OBJECT Note AT Street DESCRIPTION "There is a grubby piece notepaper here with some scrawled writing on it." VERB Read DOES "Its just someone's old shopping list scrawled on the notepaper." END VERB Read. END OBJECT Note. VERB Read DOES IF OBJECT NOT IN Inventory AND OBJECT IS Takeable THEN LOCATE OBJECT IN Inventory. "(You pick up the $1.)$p" END IF. END VERB Read.
We've already seen how to allow the player to use alternative names for verbs by defining synonyms. For example we can define the abbreviation 'x' as a synonym for 'examine'. In some cases you may want to allow an alternative way of phrasing a command which can't be handled by verb synonyms because the syntax for the two verbs is different.
For example we may like to allow 'look at object' as an alternative to 'examine object'. This verb is obviously different from 'examine object' as it has three words, not two. You could define a separate verb with its own CHECK
s and DOES
statements and so on but this would be a bit tedious if, like 'examine', the verb is defined in many different places in the source code. Fortunately Alan allows you to list more than one verbname in a single VERB
definition. So while you must define the syntax for alternative verbs individually, as long as the verbs have the same parameters, you don't need separate VERB
s definitions.
A 'look at object' command requires two words - 'look' and 'at' - plus an object name. The default Alan verb syntax doesn't allow that so the syntax for 'look at object' must be explicitly defined. We would define the syntax for a command called 'look_at' to contain two words - 'look' and 'at' - followed by the name of object (referred to by the parameter name 'obj1')
SYNTAX look_at='look' 'at' (obj1).
We didn't need to define a syntax for the 'examine' verb earlier because 'examine' used the default 'verbname-followed-by-objectname' syntax. That means 'examine' uses, by default, the parameter name 'object'. We now want to allow the player to use it and 'look_at' interchangeably which means 'examine' and 'look_at' will share the same verb definitions. Therefore the 'examine' verb must have the same parameter name (obj1) as 'look_at'. To specify the parameter name for 'examine' we need to include a syntax statement for 'examine' in our source code too.
SYNTAX examine=examine (obj1).
Then wherever we define the 'examine' verb we can simultaneously define 'look_at' as well simply by adding ' , look_at
' to the VERB
statement - like this
VERB Examine, look_at CHECK Obj1 HERE ELSE "Its not here." DOES ONLY "The remote control has two large buttons. One button is made of green plastic, the other is red." END VERB.
CHECK
s in Exits As with verbs, the CHECK
statement can be used with location exits to make exits change depending on current circumstances. The most common example found in text adventures is doors. When a door is open the player can exit otherwise a message is displayed saying the door is shut.
A door could be defined along with a few object attributes - to be used in the definition of an 'open' verb - like this
OBJECT Front_Door NAME Door AT Porch IS NOT Takeable. IS NOT Open. IS Openable. END OBJECT Front_Door.
The 'open' verb along with a 'close' verb can then be defined
VERB Open CHECK OBJECT IS Openable ELSE "You can't open that." AND OBJECT IS NOT Open ELSE "The $o is already open" DOES "The $o is unlocked and opens easily." MAKE OBJECT Open. END VERB. VERB Close CHECK OBJECT IS Openable ELSE "You can't close that." AND OBJECT IS Open ELSE "The $o is already closed" DOES "The door is now closed." MAKE OBJECT NOT open. END VERB.
Note the use of the MAKE
statement to change the value of an attribute.
Whether the door is open or not can now be checked in an EXIT
statement.
LOCATION Porch NAME Front Porch DESCRIPTION "You are standing on a wooden porch. The front door of the house(to the north of you) seems newly installed and very strong." EXIT south TO Street. EXIT north TO Hallway CHECK Front_Door IS open ELSE "The door is closed." END EXIT north. END LOCATION Porch.
Those object, verb and exit definitions will work ok but that's only half the story. When the player goes through the doorway to the other location the door should still be visible and openable. As far as the player is concerned he expects to see the same door but as it is another location the game author needs to create a second door object at the second location and create verbs that open and close the two objects simultaneously.
In this example game there are only two openable objects so global 'open' and 'close' verbs would do but normally its best to use a combination of global and local verbs.
The global 'open' and 'close' verbs can check that the commands are feasible while local verbs within each door object can be used, if the global checks are passed, to change the attributes of the correct objects.
--Global verbs VERB Open CHECK OBJECT IS Openable ELSE "You can't open that." AND OBJECT IS NOT Open ELSE "The $o is already open" END VERB. VERB Close CHECK OBJECT IS Openable ELSE "You can't close that." AND OBJECT IS Open ELSE "The $o is already closed" END VERB. OBJECT Front_Door NAME Door AT Porch IS NOT Takeable. IS NOT Open. IS Openable. VERB Open DOES "The door is unlocked and opens easily. Inside the house you can see a dark corridor" MAKE Front_Door open. MAKE Door2 open. END VERB. VERB Close DOES "The door is now closed." MAKE Door2 NOT open. MAKE Front_Door NOT open. END VERB. END OBJECT Front_Door. OBJECT Door2 NAME Door AT Porch IS NOT Takeable. IS NOT Open. IS Openable. VERB Open DOES "You open the hallway door, letting in some welcome light and fresh air" MAKE Front_Door open. MAKE Door2 open. END VERB. VERB Close DOES "You close the door. With the light from the outside world gone, the hallway is now dark and mysterious." MAKE Door2 NOT open. MAKE Front_Door NOT open. END VERB. END OBJECT Door2.
As with verb definitions, you can allow alternative player commands to use the same EXIT
definition by listing the allowed words in the EXIT
definition.
Defining 'enter' as a synonym for 'north' would mean that, in any part of the game, the player can type 'enter' to go north. In many locations using 'enter' this way wouldn't make sense. So listing 'enter' as an alternative in the EXIT
definition at this particular location is better.
EXIT north,enter,'in' TO Hallway Check Front_Door IS open ELSE "The door is closed." END EXIT north.
In the example above 'north, 'enter' and 'in' are all equivalent. 'in' is in single-quotes because it is an Alan keyword. Similarly if you wanted to use 'exit' as an EXIT
command you would have to put it in single-quotes as it is obviously an Alan keyword also.
EXIT south,'exit' TO Porch Check Door2 IS open ELSE "The door is closed." END EXIT south.
The container property can be applied to objects that aren't obviously containers. It can be a useful way to group items together so that the game can treat all the objects in the group as one unit. For example, if the player picks up the remote control device in the example game he also picks up the two buttons on it. The two buttons are individually defined as objects so the player can push and examine them.
OBJECT Control NAME Remote Control AT Hallway CONTAINER DESCRIPTION "There is a home-made electronic remote control here." VERB Examine, look_at DOES ONLY "The remote control has two large buttons. One button is made of green plastic, the other is red. Above the green one is a plastic tag labelled 'Disarm'. Above the red one is another tag labelled 'Detonate'." END VERB. END OBJECT Control.
The two buttons are mentioned in the 'examine' text for the 'control' object so they don't need their own descriptive text defined in their object definitions. If the author simply left out the DESCRIPTION
statement when defining the button objects, Alan would insert the default "There is a objectname here" so text like this would be displayed
There is a home-made electronic remote control here. There is a green button here. There is a red button here.
To avoid this the author can define a blank description for the button objects.
OBJECT Butt1 NAME Green Button IN Control DESCRIPTION END OBJECT Butt1.
The buttons should also have the attribute NOT Takeable
else the player could 'take' a button separately from the rest of the remote control. (Making the buttons NOT Takeable
won't stop the player picking up the remote control itself and therefore the buttons along with it.)
OBJECT Butt1 NAME Green Button IN Control IS NOT Takeable. DESCRIPTION END OBJECT Butt1.
Normally the player would expect to be able to put objects into a container. Though its not obvious from the description that the remote control is a container object, if the player should happen to try to put something into the remote control, Arun will happily oblige with, for example, "You put the notepaper in the remote control."
One way to disable 'put' is to define a local 'put' verb within the 'control' object which will over-rule the normal action of 'put'
VERB put CHECK Obj1 IN Inventory ELSE "You don't have the $1." DOES ONLY "You can't put anything in the $2." END VERB.
Another way is to use a feature of the CONTAINER
attribute called LIMITS
. The author can define the maximum number of objects a container can hold by specifying the maximum 'count' in a LIMITS
statement. In the case of the remote control, the maximum count can be set to zero to effectively disable putting anything in the control.
OBJECT Control NAME Remote Control AT Hallway CONTAINER LIMITS COUNT 0 THEN "You can't put anything in there!" DESCRIPTION "There is a home-made electronic remote control here." END OBJECT.
(In the case of this container which already contains the two button objects you could alternatively use ' LIMITS COUNT 2
' so the player can't add any more objects to the container.)
The object definitions for the remote control and its two buttons are now done. With a definition of the verb 'push' for each of the button objects the author can provide a way for the player to solve the bomb 'problem' and win the game.
OBJECT Butt1 NAME Green Button IN Control IS NOT Takeable. DESCRIPTION "" VERB Push DOES ONLY "You push the green button. You hear a small click. Nothing else happens. Then you hear a voice call $p ""Hey! The bomb has stopped ticking!"" $p$PYou have won the game!$p" SCORE. QUIT. END VERB Push. END OBJECT Butt1. OBJECT Butt2 NAME Red Button IN Control IS NOT Takeable. DESCRIPTION VERB Push DOES ONLY "You push the red button. You hear a small click. There is a dazzling flash of light which is almost instantly followed by an overwhelming blast of noise and fire.$p The bomb has exploded. $p$PSorry, you have lost the game!$p" SCORE. QUIT. END VERB Push. END OBJECT Butt2.
By the end of the previous lesson we've created a pretty complete Alan adventure game. Its got locations, verbs, objects, a way the player can win the game and a couple of ways they can lose it. So what else is there to do?
Well, besides from the obvious - the plot is boring and the writing is too! - the game would need testing if it wasn't just an example game in a tutorial. I don't mean testing by the author - after all, I've already tried to ensure that the examples compile and basically make sense. A real game needs more testing than that. Any game that is going to be published should be played by someone other than the author before its released.
A different mind, or preferably minds, will find bugs and try different things the author never allowed for and get stuck in places the author thought were easy and so on. The author can use the feedback from test players to fix the bugs and polish the way the game plays before it is published. This process is known as 'beta testing' in computer industry jargon. A little beta testing can make all the difference between a game appearing clunky and 'amateur' to the player and a game appearing polished and 'professional'.
The creation of synonyms and alternative verbs was demonstrated throughout the tutorial. Synonyms, alternative commands and multiple ways to solve entire puzzles and problems are very important methods of making interactive fiction enjoyable for the player. Unless its the point of the game or puzzle, the player will not appreciate 'guess the word' puzzles that exist simply because the author didn't think to allow alternative ways of entering commands.
Your game might find its way into the hands of someone unfamiliar with interactive fiction especially if you release it on the Internet. So it would be good to include information about common i.f. game commands, perhaps hints to solve the puzzles in your game and how to contact the author to give feedback. You might want to advertise the major landmarks of the i.f. 'community' such as the i.f. archive and the usenet newsgroups.
You could include that sort of information within the game by defining commands such as 'help' or 'info'. Alternatively you could simply distribute a separate text file containing such information along with the two game files (the .dat
and .acd
files. )
Even if you display most information with commands within the game, you should certainly include a text file anyway to tell potential players where to find versions of the interpreter (the Arun program) to play the game on different computer systems. You might package the game with a copy of the interpreter for a particular system but you never know if all the people who end up with a copy of your game will have that particular computer system.
Naturally, because this document is a tutorial, not a manual, quite a few of the features of Alan haven't been mentioned here.
I've left out many details about the Alan features that I have described in this tutorial. I've also left out some of the most advanced and dynamic features of Alan entirely ....
.... Events - the author can make things happen in the game independently of the player's commands. For example, the bomb goes off a few turns after the player touches it; the note blows down the street in the wind at some random point in the game.
.... Actors - the author can include other characters in the game who can interact with the player's character or act independantly. For example, a police constable could wander around the game and perhaps try to pick up the remote control and press the wrong button.
.... Rules - the author can specify that certain things happen when particular circumstances occur in the game. For example, if the police constable is at the street when the note blows into the location, the police constable picks up the note and gives it to the player.
After the reader has completed this tutorial and worked with Alan for a while, I suggest returning to the manual, especially chapter three, for comprehensive information on all the features of Alan.
I wish you the best of luck as you learn and use the Alan Adventure Language system and look forward to seeing you release complete and polished games.
chapter 2: Tutorial
chapter 6: Hints and Tips
chapter 7: Adventure Construction
The Alan web site at http://www.pp.softlab.se/thomas.nilsson/alan/ has the latest available versions of the Alan compilers and interpreters, an online version of the manual, example Alan games and a Frequently Asked Questions section with explanations and tips not included in the manual. (One part of the 'FAQ' explains where to get cwsdpmi.exe which is required to run Alan on MS-DOS PC's without running a version of Microsoft Windows.)
The Interactive Fiction Archive at ftp://ftp.gmd.de/if-archive has most of the programs and information available at the Alan web site plus the 'Etudes' examples, the 'Standard' library example and the 'Starter' Apple Macintosh program to graphically create the basics of an Alan game.
The Alan information and programs are in the ftp://ftp.gmd.de/if-archive/programming/alan/ sub-directory.
If you want to explore the whole treasure trove of interactive fiction available at the Archive then start with the introductory 'readme' file - ftp://ftp.gmd.de/if-archive/README
The Alan software and manuals are free but you should still become a registered user. You can register via Internet electronic mail. Send a one-line message REGISTER (note: that text goes in the message itself not the subject heading) to alan-request@softlab.lejonet.se
rec.arts.int-fiction - discusses i.f. authoring systems and issues related to writing i.f. You can post messages here about using Alan to write games, advertise for beta-testers, etc
rec.games.int-fiction - discusses playing i.f. games, hints for solving specific games etc.
Thomas Nilsson is the author of Alan. You can email him if you find bugs in the Alan system or have problems using Alan that you can't solve reading the manual or posting to the r.a.i-f newsgroup. His email address is thoni@softlab.lejonet.se
Thanks to Thomas Nilsson for checking the drafts of this tutorial and offering much useful advice. Thanks also to the beginning Alan programmers who received early drafts and whose experiences helped refine the content of this version.
I would appreciate further feedback so that I can continue to improve the tutorial. If you have any comments or criticisms to make or find errors in this tutorial you can email me at stephen.griffiths@xtra.co.nz
The complete tutorial is made up of the following files:
tutor.htm
- this document in HTML format
readme.txt
- summary info about Alan and this tutorial
intro.ala
- sample Alan source code to test Alan system installed
lesson1.ala
lesson2.ala
lesson3.ala
lesson4.ala
- sample Alan source code files used
lesson5.ala
- as examples in the tutorial.
lesson6.ala
lesson7.ala
library1.ala
- sample Alan source code for commonly
library2.ala
- used commands and functions.