Subsections


5 Language

This section gives a complete detailed description of the IFM language.


5.1 Symbols

In the following sections, these symbols are used:

5.2 Format

IFM generally has a free-format layout -- i.e. whitespace may be placed anywhere to increase readability. The only exception is inside quoted strings, where spaces are significant. Comments may be added, starting with a hash (#) and continuing to the end of the line. All commands are terminated with a semicolon.

5.3 Control

The overall title of the map may be set using the command

title STRING;
If a map has several sections, you can set the title of each section using the command

map STRING;
This sets the title of the next map section. If you use this command at all, then the number of uses should be the same as the actual number of map sections. It's conventional (but not required) to put the map command just before the room that starts a new map section.

If your map uses features that are only present in later versions of IFM, you can indicate that up front by using the command

require NUMBER;
Then, if the IFM version number is less than this number, parsing will abort immediately, avoiding lots of potentially confusing syntax errors.8

5.4 Tags

All IFM objects may be given tag names, so that you can refer to them in other commands. Tags for different types of object are independent -- for example, you could have a room and an item with the same tag. However, tags for similar objects must be unique.

In many cases, you are allowed to refer to a tag name anywhere, even earlier in the file that you defined it (as long as the tag is defined somewhere!). Exceptions are the room from ID clause (see Section 5.5.1) and tags in commands that modify existing objects (see Section 5.5) -- these tags must be defined before being used.

The special tag last may be used to refer to the last object that was defined (depending on the context). Also, within an individual command, the special tag it may be used to refer to the most recent object tag.


5.5 Commands

There are five different types of object in IFM: rooms, items, links, joins and tasks. Each is created using its own command, the general format of which is:

<type> <body> [attribute-list];
For rooms, items and tasks, <body> is just a string description. For links and joins, it specifies two room tags to link or join together.

Many of the attributes or objects accept a list of tags as arguments. All of these, if specified more than once in the same object, concatenate the lists together.

Once an object as been declared with a tag name, its attributes can be modified by later commands referring to that tag, like this:

<type> ID [attribute-list];
where ID is the tag name of the object. Note that the tag must be defined earlier in the file than it is used.


5.5.1 Rooms

A new room is added using the command

room STRING [attribute-list];
where STRING is a description of the room. Room attributes can be:


5.5.2 Items

An item is introduced using the command

item STRING [attribute-list];
where STRING is the item description. Item attributes can be:


5.5.3 Links

You can create extra room links using the command

link ID to ID [attribute-list];
and the following attributes may be specified:


5.5.4 Joins

There is a standalone join command which joins two rooms on different map sections:

join ID to ID [attribute-list];
The following attributes may be specified:


5.5.5 Tasks

You can indicate tasks which need to be done in order to solve the game using the command

task STRING [attribute-list];
and these are the available attributes:


5.6 Variables

Various aspects of output are controlled by variables. These are set using the following syntax:

[FORMAT.]ID = NUMBER | STRING | undef [in style ID];
FORMAT, if specified, is the name of a specific output format -- the variable then applies only to that output format. ID is the name of the variable, and it can take a numeric or string value. Note that setting a variable to the value undef effectively removes it. If the style clause is present, this means to only set the variable to this value in the specified style (see Section 5.7).

You can use the value of a defined variable anywhere in the input where a number or string is expected, by prefixing it with a dollar ($) symbol.

All strings that are printed by IFM output formats undergo variable substitution -- that is, parts of the string which look like variable references get the value of the variable inserted. If you want a literal $ inside a string, use $$. If you want substitution to be performed on a variable that is cuddled up to other text that looks like part of the variable name, you must surround it with twiddly brackets, like ${this}. Note that variable substitution only happens when the string is output -- this happens after all other processing, so it is the final value of the variable that will be substituted.

Some output formats use variables so that you can customize them. They expect certain variables to be defined, and give an error if they aren't. The default values for these variables are set in the initialization file -- see Section 4.4.


5.7 Styles

A ``style'' defines a set of variables with particular values, so that those values can be referred to together. IFM keeps track of the currently active list of styles, and there are two commands which change this list. The command

style ID;
pushes the specified style onto the style list. This style becomes the current style. Any IFM objects declared while a style list is in force will by default be output in those styles. Any variable setting is by default in the current style (though you can specify a particular style using the in style clause -- see Section 5.6).

The command

endstyle [ID];
pops the current style from the style list. The previous style on the list (if any) becomes the current style. The ID, if specified, should match the ID in the corresponding style command, or a warning is given.

Each display style has its own set of values for customization variables. On output, when the value of a variable is needed for displaying an object, the style list for that object is searched in reverse order of declaration. The value used is from the first style to define this variable. If no style defines it, then the default value is used.

If a style is referenced by an object but not defined anywhere in the input, then its definition is assumed to be in a separate file, which is searched for using the standard search path. The name of this file is formed by adding a .ifm suffix to the style name. If the file is not found, or it does not define the required style, a warning is given.


5.8 Expressions

Whenever a number is expected in IFM input, you can supply an arithmetic expression. An expression can be a number or a variable value, or a combination using the following constructs (in order of precedence):


( expr ) parentheses
expr expr exponentiation
+ expr unary plus
- expr unary minus
expr * expr multiply
expr / expr divide
expr % expr remainder
expr + expr addition
expr - expr subtraction


Note that in expressions, all variables are treated as numeric. If a variable is set to be a string and is then used in an expression, its numeric value will be read from the string. For most strings, this will be zero. This means that if you want to set a string variable to be exactly equal to another variable, you can't say something like

string_var = $other_string_var;
because the right hand side is an expression, which is treated as numeric. The way to do it is to use variable substitution in strings:

string_var = "$other_string_var";


5.9 Preprocessor

Before IFM sees any input, it is ``preprocessed'' -- special preprocessing directives are acted upon and removed. This allows you to include other files, define macros, and process the input conditionally.

The preprocessing directives all begin with a percent symbol and must be at the start of a line. Some of the available preprocessing directives are:9

A few macros are predefined and available to all input:

IFM also comes with a few predefined include files for you to use: