Five kinds of error are reported by Inform: a fatal error is a breakdown severe enough to make Inform stop working at once; an error allows Inform to continue for the time being, but will normally cause Inform not to output the story file (because it is suspected of being damaged); and a warning means that Inform suspects you may have made a mistake, but will not take any action itself. The fourth kind is an ICL error, where a mistake has been made in a file of ICL commands for Inform to follow: an error on the command line is called a “command line error” but is just another way to get an ICL error. And the fifth is a compiler error, which appears if Inform's internal cross-checking shows that it is malfunctioning. The text reporting a compiler error asks the user to report it the author of Inform.
Too many errors: giving up
After 100 errors, Inform stops, in case it has been given the wrong source file altogether, such as a program written in a different language.
· · · · ·
Most commonly, Inform has the wrong filename:
Couldn't open source file
‹filename›
Couldn't open output file
‹filename›
(and so on). More seriously the whole process of file input/output (or “I/O”) may go wrong for some reason to do with the host computer: for instance, if it runs out of disc space. Such errors are rare and look like this:
I/O failure: couldn't read from source file
I/O failure: couldn't backtrack on story file for checksum
and so forth. The explanation might be that two tasks are vying for control of the same file (e.g., two independent Inform compilations trying to write a debugging information file with the same name), or that the file has somehow been left “open” by earlier, aborted compilation. Normally you can only have at most 256 files of source code in a single compilation. If this limit is passed, Inform generates the error
Program contains too many source files: increase #define MAX_SOURCE_FILES
This might happen if file A includes file B which includes file C which includes file A which… and so on. Finally, if a non-existent pathname variable is set in ICL, the error
No such path setting as ‹name›
is generated.
· · · · ·
If there is not enough memory even to get started, the following appear:
Run out of memory allocating ‹n›
bytes for ‹something›
Run out of memory allocating array of ‹n›x‹m› bytes for ‹something›
More often memory will run out in the course of compilation, like so:
The memory setting ‹setting› (which is ‹value› at present) has been exceeded. Try running Inform again with $‹setting›=‹larger-value› on the command line.
(For details of memory settings, see §39 above.) In a really colossal game, it is just conceivable that you might hit
One of the memory blocks has exceeded 640K
which would need Inform to be recompiled to get around (but I do not expect anyone ever to have this trouble, because other limits would be reached first). Much more likely is the error
The story file/module exceeds version ‹n› limit (‹m›K) by ‹b› bytes
If you're already using version 8, then the story file
is full: you might be able to squeeze more game in using the Abbreviate
directive, but basically you're near to the maximum game size possible.
Otherwise, the error suggests that you might want to change the version
from 5 to 8, and the game will be able to grow at least twice as large
again. It's also possible to run out not of story file space but of
byte-accessible memory:
This program has overflowed the maximum readable-memory size of the Z-machine format. See the memory map below: the start of the area marked "above readable memory" must be brought down to $10000 or less.
Inform then prints out a memory map so that you can see what contributed to the exhaustion: there is detailed advice on this vexatious error in §45. Finally, you can also exhaust the number of classes:
Inform's maximum possible number of classes (whatever amount of memory is allocated) has been reached. If this causes serious inconvenience, please contact the author.
At time of writing, this maximum is 256 and nobody has yet contacted the author.
In the following, anything in double-quotes is a quotation from your source code; other strings are in single-quotes. The most common error by far takes the form:
Expected ‹...› but found ‹...›
There are 112 such errors, most of them straightforward to sort out, but a few take some practice. One of the trickiest things to diagnose is a loop statement having been misspelt. For example, the lines
pritn "Hello"; While (x == y) print "x is still y^";
produce one error each:
line 1: Error: Expected assignment or statement but found pritn line 2: Error: Expected ';' but found print
The first is fine. The second is odd: a human immediately
sees that While
is meant to be a while
loop,
but Inform is not able to make textual guesses like this. Instead Inform
decides that the code intended was
While (x == y); print "x is still y^";
with While
assumed to be the name of
a function which hasn't been declared yet. Thus, Inform thinks the
mistake is that the ;
has been missed out.
In that example, Inform repaired the situation and was able to carry on as normal in subsequent lines. But it sometimes happens that a whole cascade of errors is thrown up, in code which the user is fairly sure must be nearly right. What has happened is that one syntax mistake threw Inform off the right track, so that it continued not to know where it was for many lines in a row. Look at the first error message, fix that and then try again.
· · · · ·
In that last error message, “number” is used in the linguistic sense, of singular versus plural.
· · · · ·
Characters are given by ISO Latin-1 code number if in this set, and otherwise by Unicode number, and are also printed if this is possible. For instance, if you try to use an accented character as part of an identifier name, you cause an error like so:
Error: Illegal character found in source: (ISO Latin1) $e9,
i.e., 'e'
> Object cafe
because identifiers may only use the letters A to Z, in upper and lower case, the digits 0 to 9 and the underscore character _. The same kind of error is produced if you try to use (say) the ^ character outside of quotation marks. The characters legal in unquoted Inform source code are:
‹new-line›
‹form-feed›
‹space›
‹tab›
0123456789
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
()[]{}<>"',.:;?!+-*/%=&|~#@_
· · · · ·
The limit of 233 global variables is absolute: a program even approaching this limit should probably be making more use of object properties to store its information. “Entries… must be known constants” is a restriction on what byte or string arrays may contain: basically, numbers or characters; defined constants (such as object names) may only be used if they have already been defined. This restriction does not apply to the more normally used word and table arrays.
· · · · ·
Note that the system function random
, when
it takes more than one argument, can only take constant arguments,
as this enables the possibilities to be stored efficiently within
the program. Thus random(random(10), location)
will
produce an error. To make a random choice between non-constant values,
write a switch
statement instead.
· · · · ·
“Operators” include not only addition
+
, multiplication *
and so on, but also
higher-level things like -->
(“array entry”)
and .
(“property value”) and ::
(“superclass”). An example of an operator where “Evaluating
this has no effect” is in the statement
34 * score;
where the multiplication is a waste of time, since nothing is done with the result. “= applied to ‹operator›” means something like
(4 / fish) = 7;
which literally means “set 4/fish
to 7”
and gives the error “= applied to /”.
“Brackets mandatory to clarify order” means that an expression is unclear as written, and this is often a caution that it would be wrong either way and needs to be reconsidered. For instance:
if (parent(axe) == location == Hall_of_Mists) ...
This looks as if it might mean “if these three
values are all equal”, but does not: the result of ==
is
either true
or false
, so whichever comparison happens
first, the other one compares against one of these values.
· · · · ·
For instance, print (bold) X
gives the
“reserved word in print specification” error because bold
is a keyword that has some meaning already (the statement style
bold;
changes the type face to bold). Anyway, call such a printing
routine something else.
· · · · ·
Note that “common properties” (those provided
by the library, or those declared with Property
) cannot
be made private
. All other properties arecalled “individual”.
The “number of duplicates” referred to is the number of duplicate
instances to make for a new class, and it needs to be a number Inform
can determine now, not later on in the source code (or in another module
altogether). The limit 10,000 is arbitrary and imposed to help prevent
accidents: in practice available memory is very unlikely to permit
anything like this many instances.
· · · · ·
At present verbs are limited to 20 grammar lines each, though this would be easy to increase. (A grammar of this kind of length can probably be written more efficiently using general parsing routines, however.)
· · · · ·
“Condition can't be determined” only
arises for Iftrue
and Iffalse
, which
make numerical or logical tests: for instance,
Iftrue #strings_offset == $4a50;
can't be determined because, although both quantities
are constants, the value of #strings_offset
will not be
known until compilation is finished. On the other hand, for example,
Iftrue #version_number > 5;
can be determined at any time, as the version number was set before compilation.
· · · · ·
· · · · ·
Note that the errors beginning “Link:” are exactly those occurring during the process of linking a module into the current compilation. They mostly arise when the same name is used for one purpose in the current program, and a different one in the module.
· · · · ·
· · · · ·
Finally, error messages can also be produced from
within the program (deliberately) using Message
. It may
be that a mysterious message is being caused by an included file
written by someone other than yourself.
‹type› ‹name› declared but not used
For example, a Global
directive was
used to create a variable, which was then never used in the program.
'=' used as condition: '==' intended?
Although a line like
if (x = 5) print "My name is Alan Partridge.";
is legal, it's probably a mistake: x = 5
sets x
to 5 and results in 5, so the condition is always
true. Presumably it was a mistype for x == 5
meaning
“test x
to see if it's equal to 5”.
Unlike C, Inform uses ':' to divide parts of a 'for' loop specification: replacing ';' with ':'
Programmers used to the C language will now and then
habitually type a for
loop in the form
for (i=0; i<10; i++) ...
but Inform needs colons, not semicolons: however, as it can see what was intended, it makes the correction automatically and issues only a warning.
Missing ','? Property data seems to contain the property name ‹name›
The following, part of an object declaration, is legal but unlikely:
with found_in MarbleHall short_name "conch shell", name "conch" "shell",
As written, the found_in
property has
a list of three values: MarbleHall
, short_name
and "conch shell"
. short_name
throws up the warning because Inform suspects that a comma was missed
out and the programmer intended
with found_in MarbleHall, short_name "conch shell", name "conch" "shell",
This is not a declared Attribute: ‹name›
Similarly, suppose that a game contains a pen. Then
the following give
statement is dubious but legal:
give MarbleDoorway pen;
The warning is caused because it's far more likely to be a misprint for
give MarbleDoorway open;
Without bracketing, the minus sign '-' is ambiguous
For example,
Array Doubtful --> 50 10 -20 56;
because Inform is not sure whether this contains three entries (the middle one being 10 − 20 = −10), or four. It guesses four, but suggests brackets to clarify the situation.
Entry in '->' or 'string' array not in range 0 to 255
Byte ->
and string
arrays can only hold numbers in the range 0 to 255. If a larger entry
is supplied, only the remainder mod 256 is stored, and this warning
is issued.
This statement can never be reached
There is no way that the statement being compiled can ever be executed when the game is played. Here is an obvious example:
return; print "Goodbye!";
where the print
statement can never be
reached, because a return
must just have happened.
Beginners often run into this example:
"You pick up the gauntlet."; score = score + 5; return;
Here the score = score + 5
statement
is never reached because the text, given on its own, means “print
this, then print a new-line, then return from the current routine”.
The intended behaviour needs something like
score = score + 5; "You pick up the gauntlet.";
Verb disagrees with previous verbs: ‹verb›
The Extend only
directive is used to
cleave off a set of synonymous English verbs and make them into a new
Inform verb. For instance, ordinarily “take”, “get”,
“carry” and “hold” are one single Inform verb,
but this directive could split off “carry” and “get”
from the other two. The warning would arise if one tried to split off
“take” and “drop” together, which come from
different original Inform verbs. (It's still conceivably usable, which
is why it's a warning, not an error.)
This does not set the final game's statusline
An attempt to choose, e.g., Statusline time
within a module, having no effect on the program into which the module
will one day be linked. Futile. Finally a ragbag of unlikely and fairly
self-explanatory contingencies:
The last of these messages is to allow for different module formats to be introduced in future releases of Inform, but so far there has only ever been module format 1, so nobody has ever produced this error.
· · · · ·
These all occur if Inform compiles a syntax which was correct under Inform 5 (or earlier) but has now been withdrawn in favour of something better.
▲▲
No Inform library file (or any other file marked System_file
)
produces warning messages. It may contain many declared but unused
routines, or may contain obsolete usages for the sake of backward
compatibility.