Roger Firth's IF pages

Home

Inform 6: Frequently Asked Questions

Email
Back up

Into
the Intro

Setting
the scene

Preparing
to program

Learning
the lingo

Dabbling
in data

Operating
on objects

Verbal
versatility

Bothered
by bugs

History and
hereafter

Worldly
woes

Inside
information

Tips and
techniques

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

What do the various file extensions like 'Z5' signify?

More information in the DM:
§41 §45

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.

Where should I store the various Inform files?

PC development environment

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.


Mac development environment

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.

How do I compile on a PC running XP?

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.

How do I compile on a Mac running OS X?

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:
Mac OS X Unix Tutorial

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:

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:

Pico text editor

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:

  1. 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

  2. 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.

  3. Open a Terminal window and browse until you are in the folder game_folder.

  4. Type:

      chmod 777 source_file.command

    This command sets all the executable bits for the file and marks it as "executable".

  5. 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.

What can I expect when I try to compile my program?

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.

Why does my game start off so big?

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.

Game size

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.

How do I change the compiler settings?

More information in the DM:
§39

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:
Table 3

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
$LARGE
$HUGE

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' ...

Does it matter how I structure my game file?

More information in the DM:
§4

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?.)


Areas in Inform file

Every game should contain those five lines shown in Areas A, C and E. Then, typically:

Does it matter how I organize my object definitions?

Yes and no. The general way of defining an object without a parent (for example, a room) is roughly:

More information in the DM:
§3.3 §4

  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:
§3.8

  Object  obj_name "external_name"
    class class_name
    with  prop_name value,
          ...

  class_name  obj_name "external_name"
    with  prop_name value,
          ...

Does it matter how I lay out my code?

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.

How does a game begin?

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:
§1.2

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:
§21

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:
§21 §42
and in Marnie Parker's
Stupid Initialise tricks

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:
§20

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:
§20

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).

How does a game end?

More information in the DM:
§21

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:
§22

  [ 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?

Is there a good Integrated Development Environment?

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

How do I use Modules?

More information in the DM:
§38

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.

Can I write a game in French?

More information in the DM:
§34 §35 §36 §37

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:

  1. Download two library files. You must obtain replacements for the two standard library files which contain English-language text: the language definition file English.h (which defines parser-significant words like AND, EXCEPT and THEN; pronouns like IT and THEM; compass directions; small numbers; and all of the messages), and the file of basic verb definitions Grammar.h. The replacements are typically called, for example, French.h and FrenchG.h. Put these replacement files in the same folder as the other library files; there's no need to get rid of English.h and Grammar.h.
  2. Change one of the standard Includes. Every English game source contains these three lines somewhere; the first two are fine as they are, but the third line should be changed to instead refer to the new grammar file FrenchG.h:
  3.   Include "Parser";
      Include "VerbLib";
      Include "Grammar";    ! change this line

  4. Modify your compilation process. You control the operation of the compiler by setting command-line switches (for example -X or -~S) and variables (for example, +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib). To compile using a non-English language, you need to defined another variable, thus: +language_name=French. The value that you provide here is used within parserm.h to Include the appropriate language definition file -- French.h in our example -- instead of the default English.h. Here's an example of a Windows batch file that could be used to compile a French version of RUINS.INF:
  5.   ..\..\Lib\Base\Inform +language_name=French +include_path=.\,..\..\Lib\Base,..\..\Lib\Contrib RUINS
      pause "at end of compilation"

  6. Think about fonts. If you intend to write in a language which makes heavy use of accented or unusual characters (such as Cyrillic or Greek), you'll also need to study the topic on character sets. With the Western European languages, this isn't usually a problem.

Rien de plus simple!

Into
the Intro

Setting
the scene

Preparing
to program

Learning
the lingo

Dabbling
in data

Operating
on objects

Verbal
versatility

Bothered
by bugs

History and
hereafter

Worldly
woes

Inside
information

Tips and
techniques