Roger Firth's IF pages | ![]() |
Inform 6: Frequently Asked Questions | ![]() |
![]() |
Preparing |
These topics are about installing the necessary files, and learning how to type an Inform program:
What do the various file extensions like 'Z5' signify?
Where should I store the various Inform files?
Recommended folder settings (PC and Mac downloads)
How do I compile on a PC running XP?
How do I compile on a Mac running OS X?
What can I expect when I try to compile my program?
Locating errors in your code
Why does my game start off so big?
How large is it likely to grow
How do I change the compiler settings?
ICL files, switches, path variables and memory settings
Does it matter how I structure my game file?
Basic layout of an Inform source file
Does it matter how I organize my object definitions?
Basic structure of an object definition
Does it matter how I lay out my code?
Tips on readability of source code
How does a game begin?
The Initialise() entry point routine
Banners
Waiting for a keypress
Equipping and customising the Player Character
Starting daemons and timers
Setting lookmode
Restoring a previous game
How does a game end?
Using deadflag
DeathMessage(), PrintRank() and Amusing()
Is there a good Integrated Development Environment?
How do I use Modules?
Can I write a game in French?
Four steps to write games in other languages than English
In an operating environment like the PC where filename extensions are widely used, you're likely to come across some of these values:
Extension |
Used for |
|---|---|
.INF |
Files containing Inform source programs. |
.H |
'Header' files containing Inform source statements which are intended to be #Included into .INF files. |
.Z5 and .Z8 |
The vast majority of today's compiled Z-machine games: .Z5 (Infocom's 'advanced' design) is normal unless the game size exceeds 256Kb, whereupon .Z8 permits an increase to 512Kb. |
.Z3 and .Z6 |
Infrequent circumstances: .Z3 (Infocom's 'standard' design) is nowadays created only to suit some restricted-memory interpreters which cannot handle .Z5 files; .Z6 (Infocom's 'graphical' design) lacks the development tools and interpreter support for widespread acceptance. |
.DAT |
Infocom games. Note that interpreters use information from within the file, rather than the file's extension, to determine its version; any Z-machine interpreter should be able to play a .DAT file. |
.ULX |
Inform games which have been compiled to run on the Glulx virtual machine. |
.BLB |
Blorb files: a packaged collection of sounds and/or images which can be invoked from a .Z6 or .ULX game. |
.SAV |
Preserving a game's state, created by the SAVE verb. |
.LOG or .SCR |
Keeping a copy of everything displayed during a game, created by the SCRIPT ON verb. |
.REC |
Keeping a copy of every command typed while debugging a game, created by the RECORDING ON verb and re-used by the REPLAY verb. |
When you start programming in Inform, you need to download various program and data files, and store them in some convenient arrangement of folders or directories. How you do that is entirely up to you; some people simply place everything in a single folder, but we think that too easily becomes confusing. We like to keep the 'system' files -- the Library, compiler and interpreter -- separate from the game files that we're editing, so our preference is for a logical organization of folders. On a PC it looks like this:
If you like this approach, you can download the PC folders; this is a 1Mb compressed file which also contains enough Inform files to get started with.
On a Mac running OS X it looks very similar:
Here you can download the Mac folders as a compressed file with equivalent contents. Put this file in a temporary location on your Mac and use a tool like StuffIt Expander to unpack it. You'll now have a new Inform folder, that you should place in a suitable location in your hard disk (for example, your home directory).
Or, of course, you can just follow the instructions on Graham's page and fetch the individual files yourself. If you do this, remember to rename the downloaded Library files to have an extension of ".h" (for example, rename Grammar to Grammar.h).
On UNIX, you need to be careful because filenames are case-sensitive. I suggest that you stick to lower case filenames, and then add appropriate symbolic links. For example, one of the Library files is called verblib.h; by adding links from Verblib.h and VerbLib.h to that file, you'll be able to compile downloaded games whose source file #Includes any of those forms.
The PC version of the Inform compiler, Inform.exe, is a Windows console application; it doesn't have its own Graphical User Interface (GUI) with pull-down menus and dialog boxes, but instead expects to be given the information it needs (such as the name of the file you wish to compile) on the command line. This means that nothing much happens if you just double-click on its icon, since this runs the compiler but doesn't tell it what to compile. To be able to do that, you need to run the compiler in a Command Prompt window. Click start and then Run..., type command and press Enter (or alternatively click start and select Programs, Accessories and finally Command Prompt): a Command Prompt window appears. Make the folder (Inform\Games\MyGame1) containing your first game (MyGame1.inf) your 'current directory' by typing something like cd \path\to\game_folder and try to run the compiler:
C:\> cd \My Documents\Inform\Games\MyGame1 C:\My Documents\Inform\Games\MyGame1> Inform MyGame1 'Inform' is not recognized as an internal or external command, operable program or batch file.
Unfortunately, if you've followed our advice about keeping the compiler and library files separate from your games, XP won't be able to find the compiler, and so doesn't recognize your 'Inform' command. Instead, type this longer form which tells the computer where you've stored the compiler:
C:\My Documents\Inform\Games\MyGame1> ..\..\Lib\Base\Inform MyGame1 Inform 6.30 for Win32 (27th Feb 2004) MyGame1.inf(7): Fatal error: Couldn't open source file "Parser.h"
This is better -- the compiler has started to run -- but there's still a problem: you now discover that the compiler can't find the Library files, so their location must also be specified:
C:\My Documents\Inform\Games\MyGame1> ..\..\Lib\Base\Inform +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib MyGame1 Inform 6.30 for Win32 (27th Feb 2004)
That's it; the compilation has worked (really -- you don't see any 'successful' message). But it's a real pain having to open a Command window and type all that stuff each time you compile; it's much cleaner to put the commands in a batch file MYGAME1.BAT:
..\..\Lib\Base\Inform +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib MyGame1
This is a file which you can double-click; it automatically opens a Command window and runs the compiler in it, but then immediately closes the window before you can see what happened. To prevent this auto-close, add a second line to your batch file:
..\..\Lib\Base\Inform +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib MyGame1 pause "at end of compilation"
And now you can double-click MYGAME1.BAT, the compiler runs and you can read any error messages, before pressing any key to close the Command Prompt window. A better solution than all of this, however, is to get yourself a decent text editor within which you can both compile and test your work-in-progress -- see the section on IDEs.
In a few cases, it's useful to capture compiler information to a file; for example, when you use flags like -u (work out most useful abbreviations) or -z (print memory map of the Z-machine). Do this by adding to the end of the compilation command:
..\..\Lib\Base\Inform +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib MyGame1 >MyFile.txt
Let's spend just a little longer on that +include_path= parameter. This is telling the compiler where to look for files which you mention in Include directives, for example when you say Include "Parser";. The parameter specifies three places, separated by commas, for the compiler to try:
Parameter |
Refers to |
|---|---|
.\ |
The current folder, containing the game source file. |
..\..\Lib\Base |
Up one folder level (to Games), up another folder level (to Inform), then down again to the Lib folder and the Base folder below that. |
..\..\Lib\Contrib |
Up one folder level (to Games), up another folder level (to Inform), then down again to the Lib folder and the Contrib folder below that. |
The compiler tries those three locations in sequence each time that it needs to Include a file into your game source: first the game's own folder, then the Base folder (where the standard Library files are stored), and finally the Contrib folder (where contributed extensions are stored). This scheme has a couple of advantages. First, it keeps the various file types nicely separated; this makes them easier to find, and helps to prevent confusion. Second, it means that you can make experimental changes to Library files and contributed files if you need to; just copy the file in question into the game's folder, and make your changes to that copy. Because the compiler looks first in the game's folder, it will use, for example, a copy of Parser.h from that folder in preference to the one in Lib\Base. You can experiment with changing the standard parser (if you're feeling brave) at no risk: other games won't be affected, and if you simply delete your modified form of the file, the compiler will revert to using the standard version.
The Inform compiler for OS X must be run through the Unix Terminal utility. If you double-click on its icon from a Finder window, nothing much happens: a Terminal window opens and runs the compiler without parameters, which triggers a "basic usage" message and ends up by stating that no compilation was requested. The compiler needs to be told which file to compile, and we must oblige by explicitely typing it.
There are two ways to approach this problem. One requires you to interact with the Unix Terminal for each compilation, while the other implies a bit of pre-configuring whenever you start a new game or project but then lets you operate through the Finder. In both cases, we're assuming that you're using the folder setup that was mentioned in the previous entry, and that the Inform folder is in your home directory.
Compiling with Terminal: part 1 -- the basics
|
Unix lore: A "shell" is a program that lets you interact with Unix, and it runs when you open a Terminal window. Its function is to interpret what you type on the keyboard, launch other programs (like cd or ls), display on the screen what those programs have to say and then await your pleasure in case there was something else you wanted. There are many different shells for Unix, each offering particular features and scripting languages. If you're unfamiliar with the use of Unix on your Mac,
there are a few interesting tutorials out there, like: |
We're using Mac OS X 10.3 (Panther) at the moment, which has three different Unix shells, tcsh, bash and zsh. By default Terminal launches the tcsh shell (despite the Mac Help telling you that "by default you use the bash shell"). This only becomes relevant a bit later on, when we'll tell you about a few syntax differences.
Go to Applications/Utilities and double-click on Terminal. This opens the utility which provides you with a set of windows to access the Unix command line. Supposing the computer is named Computer, and the user Boojum, you should see something like this:
Last login: Wed Jun 30 18:05:55 on ttyp1 Welcome to Darwin! [Computer:~] Boojum%
You have now the ability to type Unix commands in this window. cd enables us to change the current working folder and ls lists its contents (remember that names in Unix are case-sensitive; "LS" is different from "ls"). You can find out which shell you're currently using by typing:
echo $SHELL
When the Terminal utility starts, you are in your home directory, here denoted by the ~ symbol in [Computer:~]. In the folder Inform/Games/MyGame1 we have included MyGame1.inf which is a tiny skeleton game in Inform source format. This is the file we're going to use in order to test Inform. Type:
cd Inform/Games/MyGame1
We're now in the game folder. If you type ls you should see its contents:
About.htm MyGame1.command MyGame1.inf
The current release of the Inform compiler resides in the Inform/Lib/Base folder, and it's called inform630_macosx. Bear in mind that the name of the file inform630_macosx may have changed if a new version of the compiler has been released and this FAQ entry isn't up to date. In that case substitute inform630_macosx with the name of the version that you're using.
We could now try to run the compiler from here by typing:
~/Inform/Lib/Base/inform630_macosx MyGame1
As we said before, you need to specify the source file that you want to compile, in this case MyGame1.inf, but we don't need to mention its extension. After entering the above command, we're presented with the following output:
Inform 6.30 (27th Feb 2004) line 7: Fatal error: Couldn't open source file "Parser.h"
That "Fatal error" sounds worse than it really is. What we're seeing here is that the compiler has run, opened MyGame1.inf, and encountered a problem because in Line 7 of the source there was a reference to a library file that the compiler isn't able to find. We can improve our efforts by indicating to the compiler which folders should be investigated for interesting files:
~/Inform/Lib/Base/inform630_macosx +include_path=./,../../Lib/Base,../../Lib/Contrib MyGame1
And now we should see only this (somewhat terse) output:
Inform 6.30 (27th Feb 2004)
This is the compiler's way of saying that everything worked peachy, following the old-school philosophy that perfection means "nothing to complain about". The outcome can be seen if you type ls again. Among the files listed, you'll see a new one, MyGame.z5, which is the story file that can be played using a Z-machine interpreter.
Compiling with Terminal: part 2 -- adding an alias
This basic method of compilation is rather clumsy and inconvenient, requiring a lot of typing. There are three parts in our longish command:
inform630_macosx refers to the compiler program, and ~/Inform/Lib/Base is the name of the folder which contains it.
+include_path=./,../../Lib/Base,../../Lib/Contrib tells the compiler where to look for files like Parser and VerbLib which you've Included in the source file.
Three locations are suggested, separated by commas: this folder, which holds the source file (./); the folder holding the standard library files (../../Lib/Base); the folder holding useful bits and pieces contributed by the Inform community (../../Lib/Contrib). The three locations are searched in that order.
MyGame1 is the name of the Inform source file that we want to turn into a story file.
By convention, all Inform source files have an extension of .inf. However, Mac OS X may show its Kind as "FUJI BAS IMG document" and attempt to open it with GraphicConverter. If you're not a regular user of FUJI BAS IMG documents, you may want to change this: right-click on the file (or Ctrl-click), select Get Info. In the Open with tab, select TextEdit as the application and press the Change All... button. You're asked for confirmation.
Regarding the first two parts, the alias command comes to our rescue:
alias inform ~/Inform/Lib/Base/inform630_macosx +include_path=./,../../Lib/Base,../../Lib/Contrib
This is telling the Unix shell that typing inform is equivalent to typing ~/Inform/Lib/Base/inform630_macosx +include_path=./,../../Lib/Base,../../Lib/Contrib. Now we have access to the compiler (and the compiler has access to the library files) through the single word inform, regardless of the current working folder.
Note: The alias command is unfortunately one whose syntax isn't consistent in all Unix shells. If you're running zsh or bash, you have to type:
alias inform='~/Inform/Lib/Base/inform630_macosx +include_path=./,../../Lib/Base,../../Lib/Contrib'
With the alias defined, you can type simply:
inform MyGame1
and, as before, you should see the compiler run and report no errors:
Inform 6.30 (27th Feb 2004)
Compiling with Terminal: part 3 -- making the alias permanent
There's just one small glitch in this process. The alias that we have established is good only for this session. If you close the Terminal window and open a new one, the alias is gone. There's a fairly easy way to make it stick permanently: write it into a configuration file that is read every time that you open a Terminal window and launch the Unix shell.
To make the configuration file, we need a Unix text editor. The Unix shell in your OS X already has one, named pico. Open a new Terminal window (to ensure that we're at our home directory), type pico at the command prompt and you should see something like this:
Type the alias line that we need:
alias inform ~/Inform/Lib/Base/inform630_macosx +include_path=./,../../Lib/Base,../../Lib/Contrib
Now press Ctrl-O to save the configuration file. You're prompted for a name, which has to be very specific for this to be understood as a configuration file (watch that initial period):
.tcshrc
|
Unix tip: If you type the command ls in your home directory, you will see no .tcshrc file. This is because files beginning with a period are considered to be "hidden". You must use ls -a instead. |
... and hit Enter. Now, press Ctrl-X to exit pico. You'll be back at the command prompt. If you ever need to change the settings of the configuration file (because you have moved the Inform folder to a different location or because you downloaded a new version of the compiler), open a Terminal window and type:
pico ~/.tcshrc
Make the desired changes, save it with Ctrl-O, confirm the file name by pressing Enter, and exit with Ctrl-X.
Note: The .tcshrc configuration file is good only for the tcsh shell. You can follow a similar process if you work with bash or zsh, but the name and location of the configuration files vary.
To verify that everything works as it should, open a new Terminal window (Ctrl-N). Now the configuration file should have been incorporated into the Unix shell. Go to the game folder:
cd ~/Inform/Games/MyGame1
and type:
inform MyGame1
You should see our laconic friend:
Inform 6.30 (27th Feb 2004)
If, on the other hand, you get an error of some kind, something's amiss. Double-check these instructions, make sure that the path and filenames are correct and please confirm that the ever-important .tcshrc file is in your home directory.
Compiling with Finder: part 1 -- using a command-line file
If you have followed the above instructions to configure your system, every time that you need to compile your source code you must open a Terminal window, browse to the game_folder where your source file resides and type inform source_file. If you don't close the Terminal window, the next time you need to compile you only have to press the up-arrow key and the last command that you typed (inform source_file) re-appears, making compilation just a two-keystroke action.
We could avoid the need to open a Terminal window if we create an executable command-line file (also known as a "shell script"). Basically, you can create a text file which includes a bunch of Unix commands and make it executable, so that you may simply double-click on it from the Finder and forget about the hassle of using the Terminal utility while coding your game.
The download includes such an executable in Inform/Games/MyGame1, called MyGame1.command. This file contains two lines of instructions, editable with any text editor:
cd ~/Inform/Games/MyGame1 ../../Lib/Base/inform630_macosx +include_path=./,../../Lib/Base,../../Lib/Contrib MyGame1
The first one sets ~/Inform/Games/MyGame1/ as your working directory, and the second one compiles MyGame1.inf, as we have seen in the previous section.
To test that it works, move the story file MyGame1.z5 to the Trash and then double-click MyGame1.command. A shell window opens to tell you about the process (and to list compilation errors when necessary). If the final lines look something like this:
Inform 6.30 (27th Feb 2004) logout [Process completed]
... it means that compilation was successful. A new MyGame1.z5 story file pops up in your folder.
You can copy this executable file to any folder where there is a source file to compile, but you'll have to make changes to the working folder path and the name of the source file.
Compiling with Finder: part 2 -- editing the command-line file
There are two peculiarities that lets your system understand that MyGame1.command is a Terminal Shell Script. Mac Help will tell you that "the .command filename extension is not required", whereas in fact it's essential. You also need to set an attribute of the file which marks it as "executable" (the "executable bits"). If it doesn't meet both conditions, MyGame1.command won't run as it should.
You have to be careful when editing this file: if you were, for instance, to open it in a text editor and save it to a different location with a different name, the executable bits might get lost, and when you double-click it, you would see an error message saying that the file could not be opened because it's probably not executable.
To make a command file from scratch (also, to fix the problem of "lost" executable bits) you can follow these simple steps:
Open any text editor and write (using your own values for the game_folder and source_file):
cd ~/Inform/Games/game_folder ../../Lib/Base/inform630_macosx +include_path=./,../../Lib/Base,../../Lib/Contrib source_file
Save the file in the folder game_folder and call it source_file.command. Make sure that the text editor doesn't append a .txt extension. If it does, rename the file manually.
Open a Terminal window and browse until you are in the folder game_folder.
Type:
chmod 777 source_file.command
This command sets all the executable bits for the file and marks it as "executable".
Close the Terminal window.
Now, everytime you need to compile your game, you can just double-click on source_file.command from the Finder.
Running the game after compiling with Terminal or Finder
After a successful compilation, if you look at the Finder window of MyGame1, there should be a story file MyGame1.z5. Use the Finder to display the contents of the Inform/Bin/Zoom folder, and double-click Zoom, the game interpreter. It will present an Open dialog box. Browse to display the Inform/Games/MyGame1 folder, and open MyGame1.z5.
When the system first "sees" the Zoom interpreter, it automatically creates an association with story files whose extension is .z5 (and with other Infocom formats). From now on, you'll be able to play a game simply by double-clicking its story file.
The short answer is: lots of errors. If you think of the compiler as a tool for finding your programming mistakes, with the generation of runnable Z-code as a fortuitous by-product, you'll be close to the mark. Just occasionally a compilation is successful, but that's the exception rather than the rule; it's much more likely that it will fail, probably producing a lot of obscure messages. So, you should be neither surprised nor worried by a mass of error reports.
When you see a long list of compilation errors, look only at the first one. Solve that problem and recompile: you'll often find that several of the error messages -- not only the first one -- disappear. So then concentrate on what's now become the first error, fix that... and repeat this cycle until the game compiles cleanly.
How do you know that you've got a clean -- error-free -- compilation? Because the compiler doesn't complain (it's like the dog that didn't bark in the night). If all that you see is something like this:
Inform 6.30 for Win32 (27th Feb 2004)
then things have gone well for you.
Every error message mentions the line number in your game where the error was detected, though that line isn't necessarily where the actual mistake occurs. Still, it's the best clue you'll get, so study that line, and the one before it, looking for things like: missing or misplaced commas and semicolons; mismatched pairs of apostrophes '...', quotes "...", parentheses (...), brackets [...] and braces {...}; misspelled names for objects or variables.
As well as errors, you may also encounter warning messages. While these aren't as serious -- they don't prevent generation of Z-code -- it isn't a good idea to ignore them. A warning usually means that something isn't quite as you'd planned; you'll help yourself by fixing warnings as well as errors, so that your game compiles completely cleanly.
Here's an example which illustrates some of this. Suppose that you'd typed the simple example shown earlier in So, what is Inform?, making the understandable mistake of forgetting to put a semicolon at the end of line 19:
[ Initialise
The compilation produces these messages:
C:\My Documents\Inform\Games\Ruins\Ruins.inf(19): Error: Expected local variable name or ';' but found = > location = C:\My Documents\Inform\Games\Ruins\Ruins.inf(19): Warning: Local variable "location" declared but not used Compiled with 1 error and 1 warning (no output)
You'll see both an Error which (sort of) suggests that a semicolon may be missing, plus a completely spurious Warning about "location" not being used. Once you spot the missing semicolon, the Warning disappears also.
The very smallest program using the Inform language is perhaps:
[ Main; "ok"; ];
and the compiled size of that is just 1.5Kb -- pretty compact, but not a whole bundle of fun as a piece of interactive fiction. A minimal IF game needs at least one room, and that calls for the library files to be Included, so for all practical purposes your starting point is something more like this:
Constant Story "STORY";
Constant Headline "^HEADLINE^";
Include "Parser";
Include "VerbLib";
Object theRoom "A room"
with description "Empty.",
has light;
[ Initialise;
location = theRoom;
];
Include "Grammar";
which clocks in at a hefty 48.5Kb, of which only about 50 bytes is due to your strings, 'theRoom' object and 'Initialise' routine: literally 99.9% of that file is the parser, verb definitions, standard directions and other model world fundamentals provided by the library. So that's your realistic baseline: every game starts off with approximately 50Kb of standard -- and virtually indispensible -- overhead.
In fact, they start off as small as that only if you specify the -~S compiler switch, which de-activates Strict mode. If you specify -D~S then you get Debug (but not Strict) mode and the game grows to 55Kb, while -DS gives you both modes, at 76Kb. (For completeness, adding the -X switch incorporates the Infix debugger as well, for a total size of 137Kb; that isn't something you often need, though.) In fact, -S is the compiler's default setting, so even if you specify no switches at all, that's what you'll get. Fortunately, this isn't an issue: you want Strict (and usually Debug) modes to be active when you're authoring a new game, because of the assistance they give you in defeating silly programming errors.
We've talked about the minimum size of a game; what about the maximum size? Well, that's well-defined: it's 256Kb if you compile to Version 5, which is the default, and 512Kb if you use the -v8 switch to compile to Version 8. That's double the size limit at almost no cost, which is a damn good deal. (It's not entirely free; the same game is about 2% bigger in Version 8 than in Version 5, because in the V8 format there's a little more space wasted between each string and each routine, but the loss is pretty trivial.) And if you supply the -G switch to compile for the Glulx virtual machine, then there's effectively no size limit at all.
Finally, is there any way of telling how big your game will be when finished? Only very roughly. Once you've written a reasonable proportion, say one third to one half, you should be able to guess at the eventual quantity of source code, and then use this chart to estimate the final size of the compiled game.
The chart shows source size (horizontally) versus compiled game size (vertically).
The points are measured from real games, but you should treat this data with caution:
lots of factors can influence the results, such as the quantity of comments in the source,
and the number of library extensions which you Include into your game.
The rule of thumb seems to be: up to 400Kb of source will compile to Version 5,
up to 800Kb of source will compile to Version 8,
and if you've got more source than that, you're probably looking at a Glulx game.
More information in the DM: |
When you run the Inform compiler, you have as a minimum to tell it the name of the source file containing your game. For example, assuming that Inform represents the compiler program, and that your current folder/directory contains an error-free source file myGame.inf as well as all of the library files, then on a PC this command should be sufficient to create a Z-Machine game myGame.z5:
Inform myGame
Often, you need to provide additional information to the compiler. This information comes in four forms: ICL files, switches, path variables and memory settings, and can be provided using two methods: on the command line and in the source file. We'll describe the two methods first.
Method: On the command line
This is the traditional way on many platforms: you simply give the additional information before or after the name of your source file. For example:
Inform -X myGame +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib
This compiles myGame.inf, searching for Included files in the specified path, and incorporating the Infix debugger into myGame.z5.
Method: In the source file
Starting with Inform 6.30, you can also supply any additional information as special comment lines at the start of your source file. For example, if myGame.inf begins thus:
!% +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib !% -X Constant Story "..."; Constant Headline "...";
then you can run the compiler like this to have exactly the same effect as the previous example:
Inform myGame
The special comments beginning with !% must be the very first lines in the source file.
You can combine the two methods: a good plan is to define +include_path= on the command line (since it's probably the same for all games that you compile), while specifying switches and memory settings at the start of the source file (since they're game-specific, and often need changing as your game develops).
There's also a Switches directive which enables some switches to be set within the source file, but it's less useful and has been superseded by the !% technique.
Info: ICL files
ICL files are given in parentheses '(filename)'. An Inform Command Language file can contain any of these four forms, one to a line. For example:
Inform (myCommands) myGame
The use of ICL files is fairly uncommon nowadays.
Info: Switches
More information in the DM: |
Switches are introduced by a minus sign '-'. For example, -v8 specifies Version 8 output, -z asks the compiler to print a Z-Machine memory map, and -~S turns off Strict mode. You can merge several switches behind a single minus; -v8z~S is the same as -v8 -z -~S. If you keep them separate, you need spaces between each (-v8-z-~S is wrong). Case matters: -s is different from -S. For example:
Inform -~Sv8 myGame
Info: Path variables
Path variables are introduced by a plus sign '+', and specify directories to be used by the compiler. The default in all cases is the current directory:
Variable |
Specifies |
|---|---|
+include_path=dir,dir,dir,... |
One or more directories to be searched in sequence when handling a Include directive. This is probably the only path variable that you're likely to need. |
+source_path=dir,dir,dir,... |
One or more directories to be searched in sequence when looking for the source file. |
+icl_path=dir,dir,dir,... |
One or more directories to be searched in sequence when looking for an ICL file. |
+code_path=dir |
The directory where the compiler should write the Z-code game file. |
+temporary_path=dir |
The directory where the compiler should write any temporary files that it needs. |
For example:
Inform myGame +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib
Info: Memory settings
Memory settings are introduced by a dollar sign '$', and control how much memory the compiler thinks it will need to compile the game. You need worry about these settings only if a compilation fails with a message that you need to increase one of the values:
Setting |
Specifies |
|---|---|
$MAX_ABBREVS=64 |
The maximum number of declared abbreviations. It is not allowed to exceed 64. |
$MAX_ACTIONS=200 |
The maximum number of actions -- that is, routines such as TakeSub which are referenced in the grammar table. |
$MAX_ADJECTIVES=50 |
The maximum number of different "adjectives" in the grammar table. Adjectives are misleadingly named: they are words such as "in", "under" and the like. |
$NUM_ATTR_BYTES=6 |
The space used to store attribute flags. Each byte stores eight attribytes. In Z-code this is always 6 (only 4 are used in v3 games). In Glulx it can be any number which is a multiple of four, plus three. |
$MAX_CLASSES=64 |
The maximum number of object classes which can be defined. This is cheap to increase. |
$MAX_CLASS_TABLE_SIZE=1000 |
The number of bytes allocated to hold the table of properties to inherit from each class. |
$MAX_DICT_ENTRIES=2000 |
The maximum number of words which can be entered into the game's dictionary. It costs 29 bytes to increase this by one. |
$DICT_WORD_SIZE=6 |
The number of characters in a dictionary word. In Z-code this is always 6 (only 4 are used in v3 games). In Glulx it can be any number. |
$MAX_EXPRESSION_NODES=100 |
The maximum number of nodes in the expression evaluator's storage for parse trees. In effect, it measures how complicated algebraic expressions are allowed to be. Increasing it by one costs about 80 bytes. |
$MAX_GLOBAL_VARIABLES=240 |
The number of global variables allowed in the program. (Glulx only) |
$HASH_TAB_SIZE=512 |
The size of the hash tables used for the heaviest symbols banks. |
$MAX_INCLUSION_DEPTH=5 |
The number of nested Includes permitted. |
$MAX_INDIV_PROP_TABLE_SIZE=15000 |
The number of bytes allocated to hold the table of ..variable values. |
$MAX_LABELS=1000 |
The maximum number of label points in any one routine. (If the -k debugging information switch is set, MAX_LABELS is raised to a minimum level of 2000, as about twice the normal number of label points are needed to generate tables of how source code corresponds to positions in compiled code.) |
$MAX_LINESPACE=16000 |
The size of workspace used to store grammar lines, so may need increasing in games with complex or extensive grammars. |
$MAX_LINK_DATA_SIZE=2000 |
The size in bytes of a buffer to hold module link data before it's written into longer-term storage. 2000 bytes is plenty. |
$MAX_LOCAL_VARIABLES=16 |
The number of local variables (including arguments) allowed in a procedure. (Glulx only) |
$MAX_LOW_STRINGS=2048 |
The size in bytes of a buffer to hold all the compiled "low strings" which are to be written above the synonyms table in the Z-machine. |
$MAX_NUM_STATIC_STRINGS=20000 |
The maximum number of compiled strings allowed in the program. (Glulx only) |
$MAX_OBJECTS=640 |
The maximum number of objects. (If compiling a version-3 game, 255 is an absolute maximum in any event.) |
$MAX_OBJ_PROP_COUNT=128 |
The maximum number of properties a single object can have. (Glulx only) |
$MAX_OBJ_PROP_TABLE_SIZE=4096 |
The number of words allocated to hold a single object's properties. (Glulx only) |
$MAX_PROP_TABLE_SIZE=30000 |
The number of bytes allocated to hold the properties table. |
$MAX_QTEXT_SIZE=4000 |
The maximum length of a quoted string. Increasing by 1 costs 5 bytes (for lexical analysis memory). Inform automatically ensures that MAX_STATIC_STRINGS is at least twice the size of this. |
$MAX_SOURCE_FILES=256 |
The number of source files that can be read in the compilation. |
$MAX_SYMBOLS=10000 |
The maximum number of symbols -- names of variables, objects, routines, the many internal Inform-generated names and so on. |
$MAX_STATIC_DATA=10000 |
The size of an array of integers holding initial values for arrays and strings stored as ASCII inside the Z-machine. It should be at least 1024. |
$MAX_STATIC_STRINGS=8000 |
The size in bytes of a buffer to hold compiled strings before they're written into longer-term storage. 2000 bytes is plenty, allowing string constants of up to about 3000 characters long. Inform automatically ensures that this is at least twice the size of MAX_QTEXT_SIZE, to be on the safe side. |
$SYMBOLS_CHUNK_SIZE=5000 |
The symbols names are stored in memory which is allocated in chunks of size SYMBOLS_CHUNK_SIZE. |
$MAX_TRANSCRIPT_SIZE=200000 |
Allocated only for the abbreviations optimisation switch, and has the size in bytes of a buffer to hold the entire text of the game being compiled: it has to be enormous, say 100000 to 200000. |
$MAX_VERBS=200 |
The maximum number of verbs (such as "take") which can be defined, each with its own grammar. To increase it by one costs about 128 bytes. A full game will contain at least 100. |
$MAX_VERBSPACE=4096 |
The size of workspace used to store verb words, so may need increasing in games with many synonyms: unlikely to exceed 4K. |
$MAX_ZCODE_SIZE=20000 |
The size in bytes of a buffer to hold compiled code for a single routine. (It applies to both Z-code and Glulx, despite the name.) As a guide, the longest library routine is about 6500 bytes long in Z-code; about twice that in Glulx. |
$SMALL |
Pre-defined values for all the above settings, for small, medium and large games respectively. Since the default is $HUGE and you generally only encounter any of these variables when the compiler tells you that you need to increase one of them, you can ignore these options. |
For example:
Inform myGame $MAX_STATIC_DATA=20000
You might run into a problem with the memory settings when compiling under Unix, since Unix command shells usually parse the dollar sign as a shell variable substitution. You need to put a backslash before it:
Inform myGame \$MAX_STATIC_DATA=20000
Or single-quote it:
Inform myGame '$MAX_STATIC_DATA=20000'
If you're using a Makefile, you have to go one step further, as the 'make' tool also treats the dollar sign as something special. In this case, something like this does the trick.
myGame.z5: myGame.inf
Inform '$$MAX_STATIC_DATA=20000' ...
More information in the DM: |
Yes and no. The general structure of an Inform file always follows the same basic pattern. (If you want more background on the #Include files, see Where are all those Library files used?.)
Every game should contain those five lines shown in Areas A, C and E. Then, typically:
Yes and no. The general way of defining an object without a parent (for example, a room) is roughly:
Object obj_name "external_name"
with prop_name value,
prop_name value,
...
prop_name value,
has attr_name attr_name ... attr_name;
and if there is a parent, one of:
Object -> obj_name "external_name"
...
Object obj_name "external_name" parent_obj_name
...
A child object always has to be defined later in the file than its parent; if you're using the "->" method to denote parentage, you need to pay slightly more attention to the precise order of things than when you're using the parent_obj_name technique.
Within an object definition, you can put either the with segment first (as shown above) or the has segment; it's a matter of personal choice. Also, the ordering of properties within the with segment, and the ordering of attributes within the has segment, is down to you. The important thing is to select a style with which you feel comfortable, and then to apply it consistently.
To define an object which, as well as belonging to the generic class of Object, is also a member of a class which you've created (there's a bit more on classes later), the extended syntax is one of:
More information in the DM: |
Object obj_name "external_name"
class class_name
with prop_name value,
...
class_name obj_name "external_name"
with prop_name value,
...
Yes and no (sorry). That's a "no" because, as long as the code is syntactically correct, the compiler doesn't care in the slightest about its layout. That's a "yes" because, if you write your code to be human-readable, you help yourself to visualize its logical structure and anticipate how it will behave at run-time. The trick is: learn how to use whitespace -- that's blank lines and varying indentation -- so that you can see at a glance what's supposed to be going on.
One excellent way of handling indentation is to enforce a regular grid by using tabs. Any good text editor will allow you to specify a value for tab spacing: four is a good number, but two, three and eight are also popular settings. Just find a value which seems right to you, and then stick to it.
Stick also to a consistent way of wrapping braces {...} around blocks of code. Which standard you adopt isn't nearly as important as employing that standard across the board. You want the code to 'look right' to you.
And to other people. It's fairly common, when fighting an intransigent problem, to post code fragments on the Usenet newsgroup rec.arts.int-fiction, so that other Inform programmers can help with the debugging. You'll find a more willing response if your code has obviously been laid out with care.
Roger Firth has a tool called INSTRUCTOR for cleaning up badly-formatted Inform code |
Format it properly as you go. It's always a mistake to type the code in roughly, telling yourself that you'll come back later to tidy it up; you almost certainly won't. Enforce your own discipline of doing it properly first time, every time.
Finally, when writing new code or changing an existing program, check frequently that the game still compiles cleanly. That way, you’ll catch silly syntax errors while your intentions are fresh in your mind.
A typical Inform game begins something like this; there are roughly three sections:
They thought that taking away your family would shatter your will. They thought that feeding you rubbish would make you plump, weak and lazy. They thought that wooden doors and metal bars would be able to keep you in your place, until the hour of doom. They thought wrong. |
The Prologue (optional) -- an opening text which normally sets up the mood of the narration and offers the first details of the story. |
GROINK RETRIBUTION An Interactive Porcine Vengeance. Copyright (c) 2003 by Superb Author. Release 1 / Serial number 030816 / Inform v6.21 Library 6/10 |
The Banner (optional), which displays the game's general information -- title, author, serial number, library version, etc. |
In the pigsty Mud, mud and more mud, enclosed by a wooden fence and one stone wall to the north. > |
The description of the starting room, followed by the command prompt. |
Let's take a look at the source code:
Constant Story "GROINK RETRIBUTION";
Constant Headline "^An Interactive Porcine Vengeance.
^Copyright (c) 2003 by Superb Author.^";
Include "Parser";
Include "VerbLib";
Object pigsty "In the pigsty"
with description
"Mud, mud and more mud, enclosed by a wooden
fence and one stone wall to the north.",
has light;
[ Initialise;
location = pigsty;
"^^They thought that taking away your family would shatter
your will. They thought that feeding you rubbish would
make you plump, weak and lazy. They thought that wooden
doors and metal bars would be able to keep you in your
place, until the hour of doom.
^^
They thought wrong.^^";
];
Include "Grammar";
More information in the DM: |
The DM tells us early on that all Inform programs must begin with the definition of a routine called Main() -- for a superficial overview of how a game runs, read this later topic -- which may invite new readers to believe that their game's source code must contain such a definition. That is not so. The library, which we Include in our source file (through Parser, VerbLib and Grammar), has already taken care of writing Main() and paving our way with necessary defaults.
We do need, however, to define a routine called Initialise, which runs before any text is printed and whose only mandatory task is to set the location variable to the starting room:
location = pigsty;
Bear in mind that the location doesn't have to be a room: it may be a container (the player starts the game locked up inside a wardrobe) or a supporter (a few games start with the Player Character (PC) waking up on his bed).
More information in the DM: |
Other than that, you can use Initialise() to write, set up and trigger just about anything that needs to be, well, initialised, before the game runs: assign starting values to variables, give possessions to the PC, start up daemons and timers which need to be functioning from the beginning, etc. In our example, we wish to display the prologue text, and we do it at the end of the routine with the quoted string statement -- which equates to (a) display the string, (b) output a newline character and (c) return.
Eventually, Initialise() runs out of statements and returns, at which moment the game banner is automatically printed. The banner is made up from three parts: the game title, defined by the constant Story (optional); the author's name, copyright info, description of game or whatever you wish for a headline, defined by the constant Headline (optional); and a line comprising the release number (1 by default, unless you define otherwise with the directive Release), the serial number (the date of compilation in YYMMDD format by default, unless you define otherwise with the directive Serial) and the versions of the compiler and the library. If you do not define the constants Story and Headline, the banner will consist only of this last line.
The banner is to players like the opening titles in a movie: from here on we're deep in the story/game business. However, you may want your game not to print a banner at the very beginning, because you wish, for example, to turn the prologue into an interactive opening sequence instead of a bunch of read-only paragraphs. For this, you must explicitly return 2 at the end of Initialise():
[ Initialise;
location = pigsty;
print "^^They thought ... ! explicit print statement doesn't return after displaying the text.
They thought wrong.^^";
return 2;
];
This will stop the banner from appearing after Initialise() has run its course. Now, you should include the call
Banner();
wherever it's appropriate for your game to print one; the copyright notice at the start of the DM explains the importance of the information it displays. Players, from their end, can summon up the banner whenever they want with the use of the VERSION command.
When Initialise() finishes, banner or no banner, the starting room comes up on the screen. That means that you must always define at least this room (in our example case, the pigsty).
So let's take another look at our (slightly revised) source code:
This source code... |
... means... |
... and is |
|---|---|---|
Constant Story "GROINK RETRIBUTION"; |
Defines the title of the game. (*) |
Optional |
Constant Headline "^An Interactive Porcine Vengeance.
^Copyright (c) 2003 by Superb Author.^"; |
Copyright info, description, etc. (*) |
Optional |
Release 1; |
Game release (1 by default). (*) |
Optional |
Serial 030816; |
Serial number (YYMMDD of compilation by default). (*) |
Optional |
Include "Parser"; |
Includes library file Parser.h |
Mandatory |
Include "VerbLib"; |
Includes library file Verblib.h |
Mandatory |
Object pigsty "In the pigsty"
with description
"Mud, mud and more mud, enclosed by a wooden
fence and one stone wall to the north.",
has light; |
Definition of the starting room. |
Mandatory |
[ Initialise; |
Starting definition of the Initialise() routine. |
Mandatory |
location = pigsty; |
Set location variable to starting room. |
Mandatory |
print "^^They thought that taking away your family would
shatter your will. They thought that feeding you
rubbish would make you plump, weak and lazy. They
thought that wooden doors and metal bars would be
able to keep you in your place, until the hour of
doom.^^They thought wrong.^^"; |
Prologue text. |
Optional |
return 2; |
If present, the banner won't appear. |
Optional |
]; |
End marker of the Initialise() routine. |
Mandatory |
Include "Grammar"; |
Include library file Grammar.h |
Mandatory |
(*) These entries are part of the game banner.
More information in the DM: |
Initialise() lets you effectively decide how to present your game to players, a delicate moment in which you seldom want to give the wrong impression. Your imagination is the only limit here, but let's take inventory of some examples and common uses.
Ability to pause execution until the player presses a key
If you decide to write a long introduction, you can simply code a print statement, open the double quotation marks (") and begin typing your magnum opus until smoke comes out from the keyboard:
print "Call me Ishmael. Some years ago...
...only found another orphan.
^^
finis.";
At run-time, this procedure will fill the interpreter's screen with text and, when it reaches the bottom, a [MORE] prompt will appear, waiting for the player to hit a key in order to fill another screen. You may want, however, to have a little more control on the quantity of displayed text, in favour of suspense or to set the pace of information disclosure.
print "^Welcome to the Dark Ribbon Club. There
are three ways to acquire membership:";
KeyCharPrimitive(); ! Wait for the player to hit a key.
print "^^(a) Read Muffungus incantations to an
audience of midget Praetorians under a
moonless sky.";
KeyCharPrimitive(); ! Wait for the player to hit a key.
print "^(b) Eat snails and oysters in rapid
succession for seven days without pause.";
KeyCharPrimitive(); ! Wait for the player to hit a key.
print "^(c) Become the slave of a club member
until he decides to set you free.
^^
The choice is all yours...";
The KeyCharPrimitive() library routine is responsible for the trick. In this simple form, it pauses the game's execution until the player hits any key. This technique may be combined with clearing the screen before the new text appears, using another library routine:
print "^Welcome to the Dark Ribbon Club.";
KeyCharPrimitive(); ! Wait for the player to hit a key.
ClearScreen(); ! Clear screen.
print "^^The place where power and secrecy
join forces to create a paroxysm of
political greatness.";
Adding your own line to the banner
A common feature is a line displayed at the start of the game, suggesting that players might want to seek help, or read the game credits, or check the terms of the game's licence; a good place to do this is right after the banner information appears. So, call Banner() within Initialise(), then display your additional line, and then return 2 as we have seen above:
[ Initialise;
location = pigsty;
print "They thought..."; ! Display the prologue text.
Banner(); ! Call up the standard banner.
print "Type HELP for information on licencing and credits, or if you get stuck.^";
return 2; ! No need to display the banner again.
];
Calling up cool banners
If the regular banner does not satisfy your requirements and you need to produce a title page of astounding singularity, you should return 2 from Initialise() and make a call to your own printing routine:
[ Initialise i;
location = pigsty;
print "They thought..."; ! Display the prologue text.
KeyCharPrimitive(); ! Wait for the player to hit a key.
MyCoolBanner(); ! Call up your customised banner.
return 2;
];
And then, of course, you must write a routine to suit your needs:
[ MyCoolBanner;
...
your code here
...
];
This usually involves messing around with centring text, displaying boxed quotations or flashy effects like typing one character at a time, and other advanced stuff which is better left alone for the time being.
Changing defaults for library pre-defined objects or behaviour
Inform's library defines a whole bunch of objects and default configurations which are ready to use by the game designer. There are times when you might wish to alter some pre-defined characteristic. The description of the dark ("It is pitch dark, and you can't see a thing.") or that of the Player Character ("As good-looking as ever.") are common examples:
thedark.description = "You are engulfed in creepy shadows."; player.description = "A slender youth in the prime of life, hungry for experience and adventure.";
Or you may want to change the default inventory style:
inventory_style = FULLINV_BIT + ENGLISH_BIT + RECURSE_BIT;
Equipping the player with possessions
If the PC needs to start the game carrying some objects around, Initialise() is the perfect place to do it:
move axe to player; move pants to player; give pants worn;
The move statement makes the desired object a possession of the player. We are also setting the worn attribute so that the pants object comes into the scene covering all the embarrassing bits as opposed to being carried in the player's hands.
Changing the player into a user-defined character
To learn about the technical aspects of the player object defined by the library, you may consult this later topic. For now, let's just suppose that the human being with the pre-defined defaults represented by the library's selfobj are not suitable for your protagonist. We have already seen that it's easy to change its description -- or, in fact, other properties -- through the player variable, but if the changes are more extensive, you might need to define an altogether different player object:
Object SelfVampire "(self object)"
with short_name [; return L__M(##Miscellany, 18); ],
description "As terrifying as ever.",
...
has animate concealed proper transparent;
In Initialise() you have two ways of making the change; through the variable player:
player = SelfVampire;
or with the library routine ChangePlayer():
ChangePlayer(SelfVampire);
You should use either technique before you set the location variable. If you need to change the player again during the course of the game, you should use only ChangePlayer().
Starting up timers and daemons
More information in the DM: |
If a timer or a daemon (to learn more about them you may consult this later topic) needs to be functioning from the beginning of the game, you can easily activate them in Initialise() by calling their respective library routines:
StartDaemon(CleaningRobot); SetTimer(VaultDoor, 10);
Setting up a game with "real" time
More information in the DM: |
Every time that the player performs an action (except those defined as meta actions -- SAVE, RESTORE, RESTART and the like) it counts as one "turn". In the status line of a normal Inform game, we can see the current turn count right next to the current score. However, you can replace the turn and score counters by a clock displaying the time that is passing in the model world.
First, add this line at the top of your source code:
Statusline time;
And then, in Initialise():
SetTime(time, rate);
where time is a number between 0 and 1439 defining the minutes since midnight, and rate is another number which specifies how many minutes you wish to push the clock forward at each turn. Suppose we want to start the game at 1:05 a.m., and each turn to count as five minutes:
SetTime(65, 5);
Change the default BRIEF lookmode into SUPERBRIEF or VERBOSE
Normally, an Inform game will set BRIEF as the default look mode, which gives long descriptions of places never before visited and short descriptions otherwise. You can change this by setting the variable lookmode to a suitable value:
lookmode = 1; ! BRIEF mode. lookmode = 2; ! VERBOSE mode (always long descriptions). lookmode = 3; ! SUPERBRIEF mode (always short descriptions).
Ability to restore a previously saved game before anything interesting happens
Some games include lengthy prologues or introductory sequences and, as much as this narration technique might be necessary to give players all the relevant information before the action begins, it gets annoying to have to go through the same ramble every time you run the game. You can offer players the option to immediately restore a previously-SAVEd game:
print "Would you like to restore an old game? "; if (YesOrNo()) <Restore>;
The YesOrNo() library routine waits for the player to type either YES (which makes the if (...) test true and executes the Restore action) or NO (which equals to false; execution proceeds without restoring).
More information in the DM: |
Every turn, Inform checks the value of a library variable called deadflag. It can be:
0 |
The usual state. Inform assumes that nothing drastic has happened to the Player Character (PC) and continues game execution. |
1 |
Game has been lost -- the PC has died. |
2 |
Game has been won. |
3,4,... |
Game has been lost -- the PC has suffered a user-defined demise. |
Note: It's remarkable the lack of apparent symmetry between Winning and Dying as the only pre-defined defaults of the library. It probably pays homage to Ye Olde Adventurers, who knew not of the word Losing, and nothing short of death would stop them in their tracks.
A value of deadflag other than zero will finish the game. To achieve this, you just have to make the assignment:
deadflag = 2;
wherever you need it, and the result will be:
*** You have won *** In that game you scored 35 out of a possible 100, in 325 turns. Would you like to RESTART, RESTORE a saved game or QUIT?
We have three lines: (a) an informative message of the fate of the PC, in bold face and highlighted by asterisks to ensure that the point gets home; (b) a summary of the achieved score and turn count; (c) available options now that the game is over. The value of deadflag affects the demise-message -- though it does not affect the bold face or the asterisks. A value of 1 will print "You have died" and, for whatever other alternate endings you may need, you will be using values of 3 or more. In this case, you must provide a library entry-point routine called DeathMessage(), in which you specify the equivalence between deadflag values and final one-liners:
[ DeathMessage;
switch (deadflag) {
3: print "You acted unwisely.";
4: print "You have shot your own foot.";
5: print "You rot in jail.";
...
}
];
You can customise a little the score line if you use the PrintRank() entry point routine, which lets you award flamboyant ranks to the player depending on the value of the score variable:
More information in the DM: |
[ PrintRank;
print ", earning you the rank of ";
if (score >= 90) "Legend of the Far West.";
if (score >= 70) "Marshall.";
if (score >= 50) "Deputy.";
if (score >= 30) "Cowboy.";
"Tenderfoot.";
];
This will result in something like:
In that game you scored 35 out of a possible 100, in 325 turns, earning you the rank of Cowboy.
The final Win/Lose line tells the player that he can now perform only three actions, RESTART, RESTORE a saved game or QUIT. This is not entirely accurate. If the game designer implements a score system based on tasks, players may at this point demand a FULLSCORE, which will tell them in detail how many points they got for each accomplished task. Additionally, players may invoke the command UNDO, thus returning to the previous turn, just before they managed to bring the game to one of its conclusions. You can make players aware of this possibility by writing the following constant:
Constant DEATH_MENTION_UNDO;
and the last line will change to:
Would you like to RESTART, RESTORE a saved game, UNDO your last move or QUIT?
It is not uncommon for a game to include Easter-eggs or funny responses for highly improbable actions. These tend to go unnoticed by most players, but Inform gives you an ace up your sleeve to prevent the waste of your most inspired moments. You can define:
Constant AMUSING_PROVIDED;
along with an entry point routine called Amusing(), in which you can list all the interesting things that the player may have missed:
[ Amusing;
print "Have you tried to kiss the Ancient Mariner?^
Or place the pearl inside Coleridge's wig?^
...";
];
and, only if the player has won the game (deadflag=2), this will result in:
Would you like to RESTART, RESTORE a saved game, see some suggestions for AMUSING things to do or QUIT?
As we speak, there isn't an Inform IDE which is generally agreed to be both reliable and effective, and which is in widespread use (though there are a few upcoming possibilities; see Richard Northedge's Imaginate, Mike Perlini's IF-IDE and Donnie Russell's Implementor on the PC, and Scott Forbes' Yonk on the Mac). Until that situation changes, we survive by using a ordinary text editor like NotePad (not a word processor -- you don't want any funny formatting characters mixed in with the program).
Having said that, NotePad is not very powerful; an industrial-strength editor will do wonders for your Inform productivity, especially if it offers syntax colouring and the ability to compile and run Inform games without leaving the editor. Several good possibilities are listed in Roger Firth's List of IF Editors, and in the RAIF FAQ. For the PC, TextPad is my recommendation, and here are instructions on how to harmonize it with Inform. If you do this in conjunction with the folder structure suggested in the first topic, use this line when you come to the part about setting the Parameters for the Inform compiler:
$File -S +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib
More information in the DM: |
Don't; they were designed to solve a problem which no longer exists.
The idea behind pre-compiled library modules was to cut down on the time taken to compile your game, back in the days when PCs were steam-powered and slow. Nowadays, PCs are much much faster, and the compilation time saving is tiny, much less than the period it would take you to learn how the module system is meant to work. Also, there are some snags to be aware of: various techniques for modifying the standard Library behaviour simply don't work as expected with pre-compiled modules; they aren't compatible with Version 8 stories, and so on. Most worryingly, there's the chicken and egg effect: because the module system is so little used, it is suspected of being more buggy than the rest of Inform, so people avoid using it, so the bugs aren't found... Be warned; modules simply aren't worth bothering about.
Yes, you can -- and in several other languages as well (assuming, of course, that you already speak the language fluently). Inform is currently unique in being the only IF development system to offer this degree of support for non-English game creation.
To write a game in one of these languages is simple; just do this:
Include "Parser"; Include "VerbLib"; Include "Grammar"; ! change this line
..\..\Lib\Base\Inform +language_name=French +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib RUINS pause "at end of compilation"
Rien de plus simple!
Preparing |