#LyX 1.4.2 created this file. For more info see http://www.lyx.org/
\lyxformat 245
\begin_document
\begin_header
\textclass article
\begin_preamble
\input{macros.tex}
\end_preamble
\language english
\inputencoding auto
\fontscheme default
\graphics default
\float_placement !htb
\paperfontsize default
\spacing single
\papersize a4paper
\use_geometry true
\use_amsmath 1
\cite_engine basic
\use_bibtopic false
\paperorientation portrait
\leftmargin 30mm
\topmargin 20mm
\rightmargin 30mm
\bottommargin 20mm
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\defskip medskip
\quotes_language english
\papercolumns 1
\papersides 1
\paperpagestyle fancy
\tracking_changes false
\output_changes true
\end_header
\begin_body
\begin_layout Title
\begin_inset Graphics
filename cover.eps
scale 70
rotateOrigin center
\end_inset
\end_layout
\begin_layout Date
\InsetSpace ~
\end_layout
\begin_layout Standard
\begin_inset ERT
status collapsed
\begin_layout Standard
\backslash
titlepage
\end_layout
\end_inset
\end_layout
\begin_layout Standard
\newpage
\end_layout
\begin_layout Quote
\align center
Copyright © 1997-2006 Glenn Hutchings
\end_layout
\begin_layout Quote
Permission is granted to copy, distribute and/or modify this document under
the terms of the GNU Free Documentation License, Version 1.1 or any later
version published by the Free Software Foundation; with no Invariant Sections,
with no Front-Cover Texts, and with no Back-Cover Texts.
A copy of the license is included in the section entitled
\begin_inset Quotes eld
\end_inset
GNU Free Documentation License.
\begin_inset Quotes erd
\end_inset
\end_layout
\begin_layout Standard
\newpage
\begin_inset LatexCommand \tableofcontents{}
\end_inset
\end_layout
\begin_layout Standard
\begin_inset FloatList figure
\end_inset
\end_layout
\begin_layout Standard
\begin_inset FloatList table
\end_inset
\end_layout
\begin_layout Standard
\newpage
\begin_inset ERT
status collapsed
\begin_layout Standard
\backslash
maintext
\end_layout
\end_inset
\end_layout
\begin_layout Section
Introduction
\begin_inset LatexCommand \label{sec:introduction}
\end_inset
\end_layout
\begin_layout Subsection
About IFM
\end_layout
\begin_layout Standard
IFM is a language for keeping track of your progress through an Interactive
Fiction game, and a program for producing various different sorts of output
using it.
You can record each room you visit and its relation to other rooms, the
initial locations of useful items you find, and the tasks you need to perform
in order to solve the game.
\end_layout
\begin_layout Standard
The IFM mapping commands are designed so that you can easily add to the
map as you explore the game.
You type in the rooms you visit and the directions you move in to reach
other rooms, and IFM calculates the position of each room in relation to
the others.
A map can consist of several independent sections, allowing you to divide
up the map however you like.
See Section
\begin_inset LatexCommand \ref{sec:making-maps}
\end_inset
for an example of how to make a map.
\end_layout
\begin_layout Standard
The IFM task commands, if used, allow you to specify the order in which
game-solving tasks must be done.
The IFM program can then calculate and print a high-level
\begin_inset Quotes eld
\end_inset
walkthrough
\begin_inset Quotes erd
\end_inset
of the game.
See Section
\begin_inset LatexCommand \ref{sec:solving-game}
\end_inset
for examples of how to do this.
\end_layout
\begin_layout Standard
Several output formats are available, including PostScript, Fig and ASCII
text---these are described in Section
\begin_inset LatexCommand \ref{sec:using-ifm}
\end_inset
.
Some of the output formats have a set of variables which control the appearance
of the output---see Section
\begin_inset LatexCommand \ref{sec:output-variables}
\end_inset
.
\end_layout
\begin_layout Subsection
History of IFM
\end_layout
\begin_layout Standard
When I started playing IF games, years ago, I did what many other people
did---made a rough map on paper of where I'd explored, so I could see which
directions I hadn't tried yet.
Inevitably, the maps always fell off the page and turned into a complete
mess.
\end_layout
\begin_layout Standard
My first attempt at solving this problem was to make use of the tools I
had available to draw the map for me.
So I started typing the map network into a file, and wrote a small Perl
script to convert the data into something that groff could read and draw
a map from.
I also added a way of recording which items I'd found, and whether I'd
found a use for them yet.
\end_layout
\begin_layout Standard
As it stood, this worked quite well---it produced nice maps and lists of
items so I could see where I'd got to.
The only problem was that it was just as tedious making maps this way as
on paper, since I had to work out the offset of each room relative to a
fixed origin.
\end_layout
\begin_layout Standard
Eventually I decided that enough was enough.
I wanted to be able to add stuff to the map as I played the game, without
having to worry about offsets or anything irrelevant like that.
Hence the main design criteria for IFM.
The other criteria were easy---an input language, for flexibility and extendabi
lity, and a program for converting files in this language into different
types of output.
\end_layout
\begin_layout Standard
Partway through writing the initial version of IFM, I had the idea that
it would be nice to be able to somehow record not only the map and items
found so far, but what's been done to solve the game.
The concept of tasks appeared, which immediately tripled the size of the
program and caused all sorts of headaches.
\end_layout
\begin_layout Standard
But eventually it got to the stage where it might be worth releasing, so
in June 1998 the first version appeared in the IF archive.
Very soon after that, I got a lot of feedback from one Dave Chapeskie (
\family typewriter
dchapes@ddm.wox.org
\family default
), who made a lot of great suggestions for improvements and new features.
He also very kindly started up a Web page for IFM maps; you can find it
at
\begin_inset LatexCommand \url{http://www.sentex.net/~dchapes/ifm}
\end_inset
.
\end_layout
\begin_layout Standard
And now, finally, it's finished and I can go back to that IF game I was
playing.
\begin_inset Foot
status collapsed
\begin_layout Standard
Oh all right.
Maybe
\emph on
one
\emph default
more feature\SpecialChar \ldots{}
\end_layout
\end_inset
\end_layout
\begin_layout Standard
\newpage
\end_layout
\begin_layout Section
Making Maps
\begin_inset LatexCommand \label{sec:making-maps}
\end_inset
\end_layout
\begin_layout Standard
This section gives you a tour of the main commands for making maps.
It's not complete; see Section
\begin_inset LatexCommand \ref{sec:language}
\end_inset
for a full list of commands.
\end_layout
\begin_layout Subsection
Introduction to Maps
\end_layout
\begin_layout Standard
The traditional Infocom-style way of drawing Interactive Fiction maps is
the
\begin_inset Quotes eld
\end_inset
boxes-and-lines
\begin_inset Quotes srd
\end_inset
method; an example is shown in Figure
\begin_inset LatexCommand \ref{fig:example-map}
\end_inset
.
This is the style of map that IFM produces.
Rooms are represented as boxes on a square grid, and links between the
rooms are drawn as lines connecting them.
Links emanate from rooms in any of the eight standard compass directions,
and also follow the grid.
In the following sections, we'll introduce the IFM commands that can be
used to draw this example map.
\begin_inset Float figure
placement htbp
wide false
sideways false
status collapsed
\begin_layout Standard
\align center
\begin_inset Graphics
filename example.eps
display color
rotateOrigin center
\end_inset
\end_layout
\begin_layout Caption
Infocom-style map
\begin_inset LatexCommand \label{fig:example-map}
\end_inset
\end_layout
\end_inset
\end_layout
\begin_layout Subsection
Adding Rooms
\end_layout
\begin_layout Standard
To draw the example map from the previous section, you first choose an arbitrary
start location: the kitchen (when mapping a real game, you'd choose your
actual start location).
To add the kitchen, just type this:
\end_layout
\begin_layout LyX-Code
room "Kitchen";
\end_layout
\begin_layout Standard
Now you're in the kitchen.
Suppose, if this were a real game, that you first went south to explore
the garage.
That can be added to the map like this:
\end_layout
\begin_layout LyX-Code
room "Garage" dir south;
\end_layout
\begin_layout Standard
Now you've said which way you went to get to the garage, and since you were
in the kitchen, IFM knows that the garage is south of the kitchen.
By the way,
\family typewriter
south
\family default
can be abbreviated
\family typewriter
s
\family default
(and similarly for all other directions), just like in the games.
\end_layout
\begin_layout Standard
Ok, you're in the garage.
Unfortunately, that's a dead end and you have to retrace your steps to
the kitchen.
You've already mapped that, so there's no need to do anything.
Now you head off east to the lounge.
Now, you're moving from the kitchen again but IFM thinks you're in the
garage (IFM's idea of
\begin_inset Quotes sld
\end_inset
where you are
\begin_inset Quotes srd
\end_inset
is always the last room mentioned).
You need a way of referring to the kitchen again---to do that, you add
a
\begin_inset Quotes sld
\end_inset
tag
\begin_inset Quotes srd
\end_inset
to it by changing the
\begin_inset Quotes sld
\end_inset
kitchen
\begin_inset Quotes srd
\end_inset
line like this:
\end_layout
\begin_layout LyX-Code
room "Kitchen" tag Kitchen;
\end_layout
\begin_layout Standard
The tag name can be any name you like.
You might think that you could refer to the kitchen by using the name in
quotes, but that would mean you could never have two distinct rooms with
the same name.
Another advantage of tags is that they can be much shorter than the real
room names.
The tag
\family typewriter
K
\family default
would be just as valid in the example above (though not as readable).
\end_layout
\begin_layout Standard
Now you can refer to the kitchen by its tag, so you can move east from it
into the lounge like this:
\end_layout
\begin_layout LyX-Code
room "Lounge" dir e from Kitchen;
\end_layout
\begin_layout Standard
The
\family typewriter
from
\family default
clause tells IFM where you're moving from.
If it's omitted, it assumes you're moving from the last room mentioned.
\end_layout
\begin_layout Standard
Continuing your exploration, you move south into the dining room:
\end_layout
\begin_layout LyX-Code
room "Dining Room" dir s;
\end_layout
\begin_layout Standard
You exit the dining room to the east, and turn a corner north before entering
the study.
How can you represent the corner faithfully on the map? Like this:
\end_layout
\begin_layout LyX-Code
room "Study" dir e n;
\end_layout
\begin_layout Standard
This says that you move east, then north, to get to the study.
Now, what if someone locked the study door behind you and the only way
out was through the window? That's a one-way trip into the study, which
you can indicate using the
\family typewriter
oneway
\family default
attribute like this:
\end_layout
\begin_layout LyX-Code
room "Study" dir e n oneway;
\end_layout
\begin_layout Standard
This is indicated on the map by an arrow.
\end_layout
\begin_layout Subsection
Adding Links
\end_layout
\begin_layout Standard
The map as it stands is not complete---the diagonal link between the kitchen
and the dining room is missing (because you didn't go that way in visiting
the kitchen or the dining room).
To add it, you need to modify the dining room command like this:
\end_layout
\begin_layout LyX-Code
room "Dining Room" dir s link Kitchen;
\end_layout
\begin_layout Standard
The
\family typewriter
link
\family default
clause creates a straight-line link between the current room and the room
with the specified tag name (in this case, the kitchen).
\end_layout
\begin_layout Standard
Note that if this link needed to turn corners, as in the study example above,
then that method of linking the rooms wouldn't have worked.
In that case, you'd have to use the stand-alone
\family typewriter
link
\family default
command.
For example:
\end_layout
\begin_layout LyX-Code
link Diner to Kitchen dir n nw;
\end_layout
\begin_layout Standard
This assumes you've given the dining room the tag name
\family typewriter
Diner
\family default
.
The link starts off going north, then turns northwest, and finally goes
toward the kitchen.
Note that in a
\family typewriter
link
\family default
command, if you omit the final direction which leads to the linked room,
it is added automatically.
\end_layout
\begin_layout Subsection
Other Directions
\end_layout
\begin_layout Standard
Suppose that there were steps down from the kitchen into the garage, and
that you wanted to indicate that you could up or down as well.
You could do that using the
\family typewriter
go
\family default
clause, like this:
\end_layout
\begin_layout LyX-Code
room "Garage" dir s go down;
\end_layout
\begin_layout Standard
This indicates that the actual direction travelled is downwards, but it
is still represented as south on the map.
The
\family typewriter
go
\family default
clause accepts
\family typewriter
up
\family default
,
\family typewriter
down
\family default
,
\family typewriter
in
\family default
and
\family typewriter
out
\family default
.
As with compass directions,
\family typewriter
up
\family default
and
\family typewriter
down
\family default
may be abbreviated as
\family typewriter
u
\family default
and
\family typewriter
d
\family default
.
\end_layout
\begin_layout Subsection
Room Exits
\end_layout
\begin_layout Standard
At various points in a game, you arrive in a room with many directions to
explore.
It is useful to be able to mark some of these directions as unexplored,
so that you can come back and explore them later.
You could mark these by creating dummy rooms in those directions, but this
is tedious.
Alternatively, you can use the
\family typewriter
exit
\family default
clause, like this:
\end_layout
\begin_layout LyX-Code
room "Dining Room" dir s exit nw e;
\end_layout
\begin_layout Standard
This says that there are two unexplored exits from this room, in the northwest
and east directions.
When a map is drawn, this fact will be displayed by a small line poking
out of the room in those directions.
\end_layout
\begin_layout Standard
When you come to actually explore those directions, and add links to new
rooms, the corresponding room exit markers will no longer be drawn.
So you can leave the exit clauses in if you want.
\end_layout
\begin_layout Subsection
Map Sections
\end_layout
\begin_layout Standard
In IFM, rooms are divided into groups called
\begin_inset Quotes eld
\end_inset
map sections
\begin_inset Quotes srd
\end_inset
.
Each room in a map section has an explicit spatial relationship to all
the other rooms in that section.
A room which is obtained by moving via a
\family typewriter
dir
\family default
clause from a previous room is on the same map section as the previous
room, since its co-ordinates can be calculated relative to it.
\end_layout
\begin_layout Standard
There are several reasons why it might be a good idea to split a game map
into different sections:
\end_layout
\begin_layout Itemize
Some maps can be very large, and may not look good on a single piece of
paper.
\end_layout
\begin_layout Itemize
It might be awkward to put rooms in relation to each other because of, say,
a lot of up/down connections which have to be
\begin_inset Quotes eld
\end_inset
flattened out
\begin_inset Quotes srd
\end_inset
.
\end_layout
\begin_layout Itemize
The game might naturally divide into sections---a prologue, middle-game
and end-game, for example.
\end_layout
\begin_layout Standard
IFM manages independent map sections automatically, by deciding which rooms
are on which section.
No special command is needed to start a new map section---simply define
a room which has no connection to any previous room, by leaving out the
\family typewriter
dir
\family default
clause (note that that's how the kitchen starts out, in the example).
\end_layout
\begin_layout Standard
Rooms on different map sections are completely separate, and you may not
link them via the
\family typewriter
link
\family default
command.
However, you can indicate where a room on one section is connected to a
room on another, using the
\family typewriter
join
\family default
command:
\end_layout
\begin_layout LyX-Code
join Room1 to Room2;
\end_layout
\begin_layout Standard
As usual,
\family typewriter
Room1
\family default
and
\family typewriter
Room2
\family default
are tag names.
You can also use
\family typewriter
join
\family default
as a clause in a room command (usually done with the room starting in a
new section):
\end_layout
\begin_layout LyX-Code
room "Basement" join Ground_Floor;
\end_layout
\begin_layout Standard
The
\begin_inset Quotes eld
\end_inset
joined
\begin_inset Quotes srd
\end_inset
status of the two rooms is indicated after their description text; the
default is to use an increasing number.
\end_layout
\begin_layout Standard
Each map section can be given a title using the
\family typewriter
map
\family default
command, like this:
\end_layout
\begin_layout LyX-Code
map "Kensington Gardens";
\end_layout
\begin_layout Standard
This names the next map section that hasn't been named.
Note that you should have as many
\family typewriter
map
\family default
commands as you have map sections, although this isn't enforced---any names
that are missing will be assigned default names, and extra names will be
ignored.
It's conventional to give a
\family typewriter
map
\family default
command just before starting a new map section.
\end_layout
\begin_layout Standard
In rare circumstances (e.g., a three-dimensional maze) you may need to have
rooms on the same map section which are not connected to each other.
The room
\family typewriter
dir
\family default
clause creates an implicit link from the previous room by default, but
you can stop this from happening by using the
\family typewriter
nolink
\family default
attribute.
As a trivial example:
\end_layout
\begin_layout LyX-Code
room "One Side of Wall" tag this_side;
\end_layout
\begin_layout LyX-Code
room "Other Side of Wall" dir e nolink tag other_side;
\end_layout
\begin_layout LyX-Code
room "Underground Passage" tag passage_1;
\end_layout
\begin_layout LyX-Code
room "Underground Passage" tag passage_2 dir e;
\end_layout
\begin_layout LyX-Code
join this_side to passage_1 go down;
\end_layout
\begin_layout LyX-Code
join passage_2 to other_side go up;
\end_layout
\begin_layout Standard
In this example, there are two map sections: above ground, and below ground.
But the two above-ground rooms are not connected directly.
\end_layout
\begin_layout Subsection
Adding Items
\end_layout
\begin_layout Standard
As well as rooms, IFM can indicate the initial rooms of various items found
in the game.
To add an item, use the
\family typewriter
item
\family default
command like this:
\end_layout
\begin_layout LyX-Code
item "Spoon" in Kitchen;
\end_layout
\begin_layout Standard
The
\family typewriter
in
\family default
clause can be omitted, and then the room defaults to the last room mentioned.
You can also add an arbitrary note to each item (e.g., to remind you what
it's for) using the
\family typewriter
note
\family default
attribute:
\end_layout
\begin_layout LyX-Code
item "Spoon" in Kitchen note "Stirs tea";
\end_layout
\begin_layout Standard
Here's the completed map description for the above example, with a few other
items thrown in:
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{../demos/example.ifm}
preview false
\end_inset
\end_layout
\begin_layout Standard
See Section
\begin_inset LatexCommand \ref{sec:using-ifm}
\end_inset
for how to display it.
\end_layout
\begin_layout Subsection
Conflicts
\end_layout
\begin_layout Standard
After creating a map from a real game and sending the results through IFM,
you may get warnings which talk about things overlapping.
This is due to two rooms, or a room and a link, wanting to occupy the same
space on the map.
There are several ways that this could occur:
\end_layout
\begin_layout Itemize
The game designer made some room links longer than others, and you haven't
taken that into account.
To extend the length of a link, just add a length indicator after the direction
in the
\family typewriter
dir
\family default
clause (e.g.,
\family typewriter
dir\InsetSpace ~
e\InsetSpace ~
2
\family default
instead of
\family typewriter
dir\InsetSpace ~
e
\family default
).
\end_layout
\begin_layout Itemize
One of the links turned a corner, so that the direction you use to go back
isn't the opposite of the one you used to get here.
In that case, you need to add the corner-turn in the link (e.g.,
\family typewriter
dir\InsetSpace ~
e\InsetSpace ~
s
\family default
instead of
\family typewriter
dir\InsetSpace ~
e
\family default
).
\end_layout
\begin_layout Itemize
The map is multi-level, in which case it's probably best to split it into
different map sections.
\end_layout
\begin_layout Itemize
The map is just weird.
Colossal Cave is a good example, particularly the above-ground section
and the mazes.
There seems to be no logic tying the rooms together.
You're on your own.
\end_layout
\begin_layout Standard
\newpage
\end_layout
\begin_layout Section
Solving the Game
\begin_inset LatexCommand \label{sec:solving-game}
\end_inset
\end_layout
\begin_layout Standard
As well as making a map of your game, you can record the steps you took
to solve it.
IFM can then calculate a (fairly) optimal solution.
This section is a guide to how to do it.
Again, it's not a complete specification---see Section
\begin_inset LatexCommand \ref{sec:language}
\end_inset
for that.
\end_layout
\begin_layout Subsection
Introduction to Tasks
\end_layout
\begin_layout Standard
The basic game-solving action is called a
\begin_inset Quotes eld
\end_inset
task
\begin_inset Quotes erd
\end_inset
in IFM-speak.
To introduce a task, you use the
\family typewriter
task
\family default
command, like this:
\end_layout
\begin_layout LyX-Code
task "Put the fluffy bunny in the incinerator";
\end_layout
\begin_layout Standard
Most tasks need to be done in a certain room.
The default is that a task must be done in the last room mentioned.
You can change that by using the
\family typewriter
in
\family default
clause, just as for items.
Some tasks can be done anywhere---you can say
\family typewriter
in\InsetSpace ~
any
\family default
to indicate that.
As usual, you can add tags to tasks in order to refer to them later.
\end_layout
\begin_layout Standard
The game solver in IFM divides tasks into two fundamental types:
\begin_inset Quotes eld
\end_inset
safe
\begin_inset Quotes srd
\end_inset
and
\begin_inset Quotes eld
\end_inset
unsafe
\begin_inset Quotes srd
\end_inset
.
An unsafe task is one that, if done, might get you into a position where
solving the game is impossible.
The game solver avoids doing unsafe tasks until it really has to.
\end_layout
\begin_layout Subsection
Task Dependencies
\end_layout
\begin_layout Subsubsection
Requiring Tasks
\end_layout
\begin_layout Standard
A lot of tasks require a previous task to be done first.
To say this, you use the
\family typewriter
after
\family default
clause:
\end_layout
\begin_layout LyX-Code
task "Press incinerator start switch" tag press_switch;
\end_layout
\begin_layout LyX-Code
...
\end_layout
\begin_layout LyX-Code
task "Put the fluffy bunny in the incinerator" after press_switch;
\end_layout
\begin_layout Standard
As a shortcut, to avoid having to tag many tasks, you can say
\family typewriter
after\InsetSpace ~
last
\family default
to indicate the last task mentioned.
For example, if the two tasks above could be done in the same room, you
could say
\end_layout
\begin_layout LyX-Code
task "Press incinerator start switch" tag press_switch;
\end_layout
\begin_layout LyX-Code
task "Put the fluffy bunny in the incinerator" after last;
\end_layout
\begin_layout Standard
Alternatively, you could merge the two into a single task---the simplicity
or complexity of tasks is up to you.
\end_layout
\begin_layout Standard
The
\family typewriter
after
\family default
clause only says that a task will come after another---it doesn't specify
how soon after.
But in some situations it is essential that a task immediately follows
a specific previous task, without deviation.
You can use the task
\family typewriter
follow
\family default
clause to specify this.
For example:
\end_layout
\begin_layout LyX-Code
room "Mission Control" ...;
\end_layout
\begin_layout LyX-Code
task "Activate launch sequence" tag activate;
\end_layout
\begin_layout LyX-Code
\end_layout
\begin_layout LyX-Code
...
\end_layout
\begin_layout LyX-Code
\end_layout
\begin_layout LyX-Code
room "Rocket Cabin" ...;
\end_layout
\begin_layout LyX-Code
task "Fasten seat belt" follow activate;
\end_layout
\begin_layout Standard
The
\family typewriter
follow
\family default
clause creates a chain of tasks that must be done one after the other.
The game solver will not attempt the first task in the chain until it knows
that all the tasks are possible (i.e., all the prerequisites for each task
in the chain are satisfied).
Also, if one of the tasks in the chain is unsafe, then all previous tasks
in the chain are also marked unsafe.
\end_layout
\begin_layout Standard
Of course, you can only have a single task in a
\family typewriter
follow
\family default
clause---the immediately preceding task.
It is an error for two or more tasks to try to immediately follow the same
task.
\end_layout
\begin_layout Subsubsection
Requiring Items
\end_layout
\begin_layout Standard
For a lot of tasks, you need to have one or more items in your possession.
You can indicate this by using the
\family typewriter
need
\family default
clause, like this:
\end_layout
\begin_layout LyX-Code
task "Put the fluffy bunny in the incinerator" need bunny;
\end_layout
\begin_layout Standard
Here,
\family typewriter
bunny
\family default
is the tag name of the corresponding item.
You can list more than one item tag---e.g.,
\family typewriter
need bunny asbestos_gloves
\family default
.
\end_layout
\begin_layout Standard
Note that you don't need to add tasks to get required items yourself---the
game solver does that automatically.
It knows it has to get all the items which appear in
\family typewriter
need
\family default
clauses.
\end_layout
\begin_layout Subsubsection
Obtaining Items
\end_layout
\begin_layout Standard
Sometimes a task need to be done before you can get an item.
One way to indicate this is with the task
\family typewriter
get
\family default
clause:
\end_layout
\begin_layout LyX-Code
task "Put money in drinks machine" need coin get lemonade;
\end_layout
\begin_layout Standard
This naturally implies that all tasks which supply an item (via the
\family typewriter
get
\family default
clause) must be done before any task which needs that item.
\end_layout
\begin_layout Standard
An alternate way to phrase this is with the item
\family typewriter
after
\family default
clause, which says that the item can't be picked up until a specified task
is done.
This is a common combination in IFM:
\end_layout
\begin_layout LyX-Code
task "Put money in drinks machine" need coin;
\end_layout
\begin_layout LyX-Code
item "lemonade" hidden after last;
\end_layout
\begin_layout Standard
Some items are only available
\emph on
before
\emph default
doing a certain task.
You can use the
\family typewriter
before
\family default
clause to say that:
\end_layout
\begin_layout LyX-Code
item "precious diamond" before trigger_alarm;
\end_layout
\begin_layout Standard
Some items can only be picked up if you're already carrying another---use
the
\family typewriter
need
\family default
clause for that:
\end_layout
\begin_layout LyX-Code
item "hot coal" need tongs;
\end_layout
\begin_layout Standard
Sometimes doing a task not only allows you to get an item, but also puts
it in your inventory.
You can say that using the
\family typewriter
give
\family default
clause:
\end_layout
\begin_layout LyX-Code
task "Buy beer" need money give beer_mug;
\end_layout
\begin_layout Standard
The
\family typewriter
give
\family default
clause overrides all other restrictions placed on getting items; the item
is just teleported into your possession.
\end_layout
\begin_layout Subsubsection
Ignoring Tasks
\end_layout
\begin_layout Standard
In some circumstances, all the effects of doing a task occur before the
task is done.
If this happens, the task will be ignored.
For example, if a task A gives an item, but that item is first given by
task B, then task A will be ignored (provided it doesn't do anything else
of importance).
\end_layout
\begin_layout Standard
If a task has no effect, it is
\emph on
not
\emph default
ignored---it's assumed that you've recorded that you did something but
don't know why yet.
Also, tasks which finish the game or score points are never ignored.
\end_layout
\begin_layout Standard
You can explicitly ignore a task using the
\family typewriter
ignore
\family default
attribute.
This is useful while you're solving the game (see Section
\begin_inset LatexCommand \ref{sec:tweaking}
\end_inset
) and when the task can be done by other tasks (see the next section).
\end_layout
\begin_layout Subsubsection
Doing Other Tasks
\end_layout
\begin_layout Standard
You can arrange for a task to automatically do other tasks after it is done,
using the
\family typewriter
do
\family default
clause.
For example:
\end_layout
\begin_layout LyX-Code
room "Control Room";
\end_layout
\begin_layout LyX-Code
task "Press airlock button" do open_airlock;
\end_layout
\begin_layout LyX-Code
\end_layout
\begin_layout LyX-Code
...
\end_layout
\begin_layout LyX-Code
\end_layout
\begin_layout LyX-Code
room "Outer Airlock";
\end_layout
\begin_layout LyX-Code
task "Open airlock" tag open_airlock;
\end_layout
\begin_layout LyX-Code
\end_layout
\begin_layout LyX-Code
room "Inner Airlock" dir s after last;
\end_layout
\begin_layout Standard
In this example, the airlock can be opened in one of two ways: manually,
when in the Outer Airlock, or via the button in the Control Room.
Pressing the button will cause the
\begin_inset Quotes eld
\end_inset
open airlock
\begin_inset Quotes erd
\end_inset
task to be done immediately afterwards.
Note that if the manual method is used first, the press-button task will
be ignored.
\end_layout
\begin_layout Standard
The
\family typewriter
do
\family default
clause causes
\emph on
any
\emph default
task to be done---even tasks that have prerequisites, and explicitly ignored
ones.
This is useful in that you can create special ignored tasks that can be
done by any of a set of other tasks, whichever gets there first.
The
\family typewriter
do
\family default
clause is also recursive: a task can do another task which in turn does
another, and so on.
\begin_inset Foot
status collapsed
\begin_layout Standard
However, you can't create an infinite loop since each task can only be done
once.
\end_layout
\end_inset
\end_layout
\begin_layout Standard
Note that any task which does an unsafe task in this way is itself marked
unsafe.
\end_layout
\begin_layout Subsection
Handling Items
\end_layout
\begin_layout Subsubsection
Inventory Items
\begin_inset LatexCommand \label{sec:inventory}
\end_inset
\end_layout
\begin_layout Standard
Items can be split into two types: useful and useless.
A useful item one that is needed by at least one task, or is required in
order to be able to move somewhere; all other items are useless.
The game solver will try to go and get all useful items, and will ignore
the useless ones.
It keeps track of the items it's carrying, and knows when a useful item
is no longer needed.
\begin_inset Foot
status collapsed
\begin_layout Standard
It has a magic crystal ball that can see into the future.
\end_layout
\end_inset
At that point, it will be dropped.
\end_layout
\begin_layout Standard
If the solver obtains a useless item (via a task
\family typewriter
get
\family default
or
\family typewriter
give
\family default
clause, or an item
\family typewriter
need
\family default
clause) it will never drop it.
This is just a default; you can change it by setting the variable
\family typewriter
keep_unused_items
\family default
to zero.
In that case, useless items will be dropped as soon as possible.
\begin_inset Foot
status collapsed
\begin_layout Standard
The reason for the default is that useless items obtained in this way probably
\emph on
do
\emph default
have a purpose---you just don't know what it is yet.
This is relevant when you're creating a recording from a partially-played
game; see Section
\begin_inset LatexCommand \ref{sec:recording}
\end_inset
for details.
\end_layout
\end_inset
\end_layout
\begin_layout Standard
If you want to make sure that an item is never dropped in any circumstance,
you can mark it with the
\family typewriter
keep
\family default
attribute.
This is handy for items that act as general containers for other items.
\end_layout
\begin_layout Standard
Sometimes a useful item needs to be kept for longer than usual.
In the hot coal example above, the tongs would be dropped as soon as the
coal was picked up, leaving you with a burnt hand.
What's needed here is to carry the tongs for as long as you have the coal.
You can use the
\family typewriter
keep\InsetSpace ~
with
\family default
clause to say that:
\end_layout
\begin_layout LyX-Code
item "hot coal" tag coal need tongs;
\end_layout
\begin_layout LyX-Code
item "tongs" tag tongs keep with coal;
\end_layout
\begin_layout Standard
Now the tongs won't be dropped until after the coal is, even if they have
no other use.
Similarly, there's also a
\family typewriter
keep\InsetSpace ~
until
\family default
clause, which keeps an item until a specific task is done.
\end_layout
\begin_layout Standard
Finally, if a room has the attribute
\family typewriter
nodrop
\family default
set, no items will be voluntarily dropped in that room.
Any items which need to be dropped will then be dropped after the next
task that happens in a room where dropping is allowed.
\end_layout
\begin_layout Subsubsection
Losing Items
\end_layout
\begin_layout Standard
Sometimes, doing a task causes items to be destroyed.
You can say that with the
\family typewriter
lose
\family default
clause:
\end_layout
\begin_layout LyX-Code
task "Light bonfire" need match lose match;
\end_layout
\begin_layout Standard
This naturally implies that all other tasks which need the item must be
done before the task that destroys it.
A
\begin_inset Quotes eld
\end_inset
drop
\begin_inset Quotes srd
\end_inset
task is never generated for items that are lost in this way.
\end_layout
\begin_layout Standard
Incidentally, you can use the special tag
\family typewriter
it
\family default
to refer to the last room, item or task tag name within a command.
So the previous example could also have been written
\end_layout
\begin_layout LyX-Code
task "Light bonfire" need match lose it;
\end_layout
\begin_layout Subsubsection
Dropping Items
\end_layout
\begin_layout Standard
As mentioned in Section
\begin_inset LatexCommand \ref{sec:inventory}
\end_inset
, IFM knows when a useful item is no longer needed, and drops it automatically.
But sometimes items need to be dropped temporarily, even though they're
needed later.
You can do that using the
\family typewriter
drop
\family default
clause:
\end_layout
\begin_layout LyX-Code
task "Throw spear at tree stump" need spear drop it;
\end_layout
\begin_layout Standard
In this example, the spear is dropped in the same room that the task was
done in.
If you ever need the spear for anything else, it will be picked up again
by the game solver.
Note that an item will only be dropped if it is being carried---mentioning
an item in a
\family typewriter
drop
\family default
clause does not imply that it's needed to do the task.
\end_layout
\begin_layout Standard
Sometimes items must be dropped in a different room to the one you're in.
You can use the
\family typewriter
in
\family default
clause to modify things:
\end_layout
\begin_layout LyX-Code
room "Top of Chute";
\end_layout
\begin_layout LyX-Code
task "Put laundry in chute" need laundry drop it in Bottom_of_Chute;
\end_layout
\begin_layout Standard
In other cases, you need to drop all the items you're carrying, or all except
certain items.
You can use
\family typewriter
drop\InsetSpace ~
all
\family default
and
\family typewriter
drop\InsetSpace ~
all\InsetSpace ~
except
\family default
to say that.
\end_layout
\begin_layout Standard
Normally, if an item is dropped but is needed again for some other task,
there is nothing to stop the game solver picking it up again (provided
there's a path to the room the item was dropped in).
But sometimes you need to drop an item and not pick it up again until you've
done something else.
You can use the
\family typewriter
until
\family default
clause to say that:
\end_layout
\begin_layout LyX-Code
task "Put coin in slot" give chocolate drop coin until open_machine;
\end_layout
\begin_layout Standard
A task which drops items will be marked unsafe if there is no path back
to the dropped items.
\end_layout
\begin_layout Subsubsection
Leaving Items
\end_layout
\begin_layout Standard
There are some situations where your movement is blocked if you are carrying
particular items.
You can use the
\family typewriter
leave
\family default
attribute of rooms, links and joins to specify a list of items that must
be left behind before using them.
For example:
\end_layout
\begin_layout LyX-Code
room "Bottom of Canyon";
\end_layout
\begin_layout LyX-Code
item "heavy boulder" tag boulder;
\end_layout
\begin_layout LyX-Code
room "Top of Canyon" dir n go up leave boulder;
\end_layout
\begin_layout Standard
If the
\family typewriter
leave
\family default
clause appears before the
\family typewriter
dir
\family default
clause, that means the items must be dropped before entering the room (from
any direction).
It is generally the case that, if an attribute could apply to a room or
its implicit link with the previous one, its position relative to the
\family typewriter
dir
\family default
clause is what decides it.
\end_layout
\begin_layout Standard
You can also say
\family typewriter
leave\InsetSpace ~
all
\family default
, which means that you must leave all the items you're currently carrying,
and
\family typewriter
leave\InsetSpace ~
all\InsetSpace ~
except
\family default
, which omits certain items from being left behind.
\end_layout
\begin_layout Standard
When finding a solution, the game solver will carry items until it is forced
to drop them.
If the dropped items are needed later, the game solver will try to come
back and get them.
If it is trying to do a task which requires items, it will choose a route
to get to the task room which doesn't involve dropping any of the needed
items.
\end_layout
\begin_layout Standard
Note that the
\family typewriter
leave
\family default
clause overrides the room
\family typewriter
nodrop
\family default
attribute; items will be dropped even in those rooms.
\end_layout
\begin_layout Subsection
Moving Around
\end_layout
\begin_layout Subsubsection
Limiting Movement
\end_layout
\begin_layout Standard
Sometimes an item is required, or a task needs to be done, before movement
in a certain direction is possible.
To represent this, you can give
\family typewriter
need
\family default
and
\family typewriter
after
\family default
clauses to rooms, links and joins.
For example:
\end_layout
\begin_layout LyX-Code
room "Cemetery" dir s from winding_path;
\end_layout
\begin_layout LyX-Code
task "Unlock the iron door" need rusty_key;
\end_layout
\begin_layout LyX-Code
room "Crypt" dir s go down after last;
\end_layout
\begin_layout Standard
Here's another example:
\end_layout
\begin_layout LyX-Code
room "Dimly-lit Passage" dir e;
\end_layout
\begin_layout LyX-Code
room "Dark Passage" dir e need candle;
\end_layout
\begin_layout Standard
In this case it is the link between the two rooms that is blocked off until
the candle is obtained.
If the
\family typewriter
need
\family default
clause had appeared before the
\family typewriter
dir
\family default
clause, the restriction would apply to the room itself (i.e.\InsetSpace ~
no entering the
room from
\emph on
any
\emph default
direction without the candle).
\end_layout
\begin_layout Standard
In some cases, doing a task closes off a room, link or join so that it can't
be used any more.
You can use the
\family typewriter
before
\family default
clause to indicate this:
\end_layout
\begin_layout LyX-Code
room "Bank Vault" tag Vault;
\end_layout
\begin_layout LyX-Code
room "Bank Entrance" tag Entrance dir e before trigger_alarm;
\end_layout
\begin_layout Standard
All tasks which close things off like this are marked unsafe, since they
could block off a crucial path through the game.
\end_layout
\begin_layout Standard
Sometimes in a game there is the situation where a path is closed off and,
later on in the game, reopened again.
A single link or join can't represent this.
However, there's nothing to stop you from using two or more joins between
the same rooms.
If you mark them with the
\family typewriter
hidden
\family default
attribute, they won't appear on the map either.
For example, this line could be added to the previous example to provide
an escape route:
\end_layout
\begin_layout LyX-Code
join Vault to Entrance go e after disable_alarm hidden;
\end_layout
\begin_layout Subsubsection
Movement Tasks
\end_layout
\begin_layout Standard
There are several different ways of moving around in a game.
The usual way is to say the direction you want to go in.
Another way is to do something else which results in movement.
A good example is the magic word
\family typewriter
XYZZY
\family default
from Colossal Cave.
It acts exactly like a movement command, in that you can use it again and
again and it moves you somewhere predictable.
The best way to represent this in IFM is to use a join to connect the two
rooms, and specify the command used to do the movement via the
\family typewriter
cmd
\family default
clause, like this:
\end_layout
\begin_layout LyX-Code
join Debris_Room to Building after examine_wall cmd "XYZZY";
\end_layout
\begin_layout Standard
Yet another way of moving around is a one-off event that
\begin_inset Quotes eld
\end_inset
teleports
\begin_inset Quotes srd
\end_inset
you to a different room.
You can indicate that this happens using the task
\family typewriter
goto
\family default
clause,
\begin_inset Foot
status collapsed
\begin_layout Standard
All the best languages have a
\family typewriter
goto
\family default
statement, you know.
\end_layout
\end_inset
and supplying the tag name of the destination room.
For example:
\end_layout
\begin_layout LyX-Code
task "Get captured by goblins" goto Dungeon;
\end_layout
\begin_layout Standard
As soon as the task is done, you teleport to the new location---no intervening
rooms are visited.
Note that because each task is only done once, this method of travel can
only be used once.
Note also that the
\family typewriter
drop
\family default
and
\family typewriter
leave
\family default
actions are done
\emph on
before
\emph default
teleporting you to the new location (so if you drop items in the
\begin_inset Quotes eld
\end_inset
current room
\begin_inset Quotes srd
\end_inset
, you will be teleported away from the dropped items).
\end_layout
\begin_layout Subsection
Other Game Features
\end_layout
\begin_layout Subsubsection
Scoring Points
\end_layout
\begin_layout Standard
Many games have some sort of scoring system, whereby you get points for
doing various things.
In IFM you can record this using the
\family typewriter
score
\family default
clause, which can apply to rooms, items or tasks.
It takes one integer argument---a score value.
For rooms, it's the score you get when visiting it for the first time.
For items, it's the score for first picking it up.
For tasks, it's the score for doing that task.
If an item has a score, but is given to the player via a task
\family typewriter
give
\family default
clause, then its score is added to the score for that task instead.
\end_layout
\begin_layout Subsubsection
Finishing the Game
\end_layout
\begin_layout Standard
Usually a game finishes when you complete some final task.
You can indicate which task this is using the
\family typewriter
finish
\family default
attribute.
This attribute can attach to rooms, items or tasks, giving three different
types of finish condition: entering a room, picking up an object or doing
a task.
If the game solver ever manages to do something which is flagged with the
\family typewriter
finish
\family default
attribute, it considers the game solved and stops.
Any extra things left to do will not be done, even if they score points.
\end_layout
\begin_layout Subsection
Finding a Solution
\end_layout
\begin_layout Standard
Here's what the game solver does in order to come up with a solution to
the game.
First, extra internal tasks are generated.
These are tasks to:
\end_layout
\begin_layout Itemize
get items which are required for explicitly-mentioned tasks to be done,
\end_layout
\begin_layout Itemize
get items which are required to get other items,
\end_layout
\begin_layout Itemize
get items which are needed to go in certain directions,
\end_layout
\begin_layout Itemize
get items which are scored,
\end_layout
\begin_layout Itemize
go to rooms which are scored.
\end_layout
\begin_layout Standard
Next, all the rooms are connected using their links and joins.
This means that for each room, a list is made of all other rooms reachable
in one move.
Note that it is possible for some rooms to be unreachable---for example,
all rooms in a section where there is no
\begin_inset Quotes eld
\end_inset
join
\begin_inset Quotes srd
\end_inset
to rooms on other sections.
\end_layout
\begin_layout Standard
Then the task dependencies are calculated.
A dependency is where one task must be done before another.
The task dependencies are examined to see if there are any cycles---that
is, chains of tasks where each one must be done before the next, and the
last must be done before the first.
If there are any, then the game is unsolvable, since none of the tasks
in a cycle can be done.
\end_layout
\begin_layout Standard
If there are no cyclic dependencies, the task list is
\begin_inset Quotes eld
\end_inset
traversed
\begin_inset Quotes srd
\end_inset
to find a sequence which solves the game while satisfying the task dependencies.
The start room is the room which was first mentioned in the input (but
this can be changed---see Section
\begin_inset LatexCommand \ref{sec:language}
\end_inset
).
While there are tasks left in the task list, the following steps are performed:
\end_layout
\begin_layout Enumerate
The inventory is examined to see if there are any unwanted items; if so,
and dropping items in the current room is allowed, they are dropped.
An item is wanted if at least one of the following is true:
\end_layout
\begin_deeper
\begin_layout Enumerate
it's needed for movement,
\end_layout
\begin_layout Enumerate
it's needed for a task that hasn't been done yet,
\end_layout
\begin_layout Enumerate
it's being kept unconditionally,
\end_layout
\begin_layout Enumerate
it's being kept with another item that's carried,
\end_layout
\begin_layout Enumerate
it's being kept until a certain task is done.
\end_layout
\end_deeper
\begin_layout Enumerate
The map is traversed to find the distances of all rooms from the current
room.
Then the task list is sorted in order of ascending distance of the rooms
they must be done in.
Tasks which can be done in any room count as having distance zero.
\end_layout
\begin_layout Enumerate
The sorted task list is scanned to find the nearest possible task.
For a task to be possible, the player must:
\end_layout
\begin_deeper
\begin_layout Enumerate
have all required items,
\end_layout
\begin_layout Enumerate
have done all required previous tasks,
\end_layout
\begin_layout Enumerate
be able to get from the current room to the task room via a path which doesn't
require items not yet collected, or tasks not yet done, or which involves
dropping needed items on the way.
\end_layout
\begin_layout Standard
Priority is given to safe tasks.
For a task to be safe,
\end_layout
\begin_layout Enumerate
it must not have previously been marked unsafe (e.g., because it closes off
map connections),
\end_layout
\begin_layout Enumerate
there must be a return path from the task room back to the current one.
This is to avoid taking a one-way trip before preparing properly.
\end_layout
\begin_layout Standard
If there are any safe tasks, the nearest one will be done next regardless
of how close an unsafe task is.
If there are no safe task, the nearest unsafe task will be chosen.
\end_layout
\end_deeper
\begin_layout Enumerate
If there was a possible task, do it and remove it from the list.
Move to the room the task was done in (if any).
If not, then the game is unsolvable.
Give up.
\end_layout
\begin_layout Enumerate
Finally, examine the list of remaining tasks to see if any are now redundant
and can be removed.
A redundant task is one that only does something that's already been done
(e.g.\InsetSpace ~
go and get an item that you've already been given).
\end_layout
\begin_layout Subsection
Tweaking the Solution
\begin_inset LatexCommand \label{sec:tweaking}
\end_inset
\end_layout
\begin_layout Standard
There will be some situations (quite a few, actually) where the game solver
doesn't do things the way you want it to.
This section gives a few tips, and some new keywords, for modifying things.
\end_layout
\begin_layout Subsubsection
Making things safe
\end_layout
\begin_layout Standard
Firstly, the game solver is completely paranoid.
It has to be, because it doesn't do any lookahead past the current task.
It won't do anything unsafe (e.g., go to a room to do a task when there's
no immediate return journey) unless there's nothing safe left to do.
It will quite happily plod halfway across the map to pick something up
rather than do something a bit scary in the next room.
\end_layout
\begin_layout Standard
However, you can reassure it with the task
\family typewriter
safe
\family default
attribute.
Adding this to a task tells the solver that this task is safe, regardless
of what it thinks.
So if you
\emph on
know
\emph default
that a one-way trip can eventually be returned from, by doing other tasks,
you can stop the solver from avoiding it.
But bear in mind that by doing this you are taking full responsibility
if the solver gets stuck.
\end_layout
\begin_layout Standard
If you want to be seriously reckless, you can set the variable
\family typewriter
all_tasks_safe
\family default
to a nonzero value.
Then,
\emph on
all
\emph default
tasks will be considered safe.
\end_layout
\begin_layout Subsubsection
Changing path lengths
\end_layout
\begin_layout Standard
Another thing the solver doesn't know about is how easy or difficult it
is to get from place to place on the map.
Suppose you're in a game which is on two levels separated by a tiresome
set of access doors with ID cards.
The connection between the levels may only be two rooms on the map, but
it's a lot more in terms of typing.
You can avoid unnecessary trips through these doors by artificially changing
the
\begin_inset Quotes eld
\end_inset
length
\begin_inset Quotes srd
\end_inset
of the connection between levels, by using the
\family typewriter
length
\family default
attribute of links and joins:
\end_layout
\begin_layout LyX-Code
room "Level A" tag LA ...;
\end_layout
\begin_layout LyX-Code
room "Level B" tag LB dir e length 50;
\end_layout
\begin_layout Standard
In this way, by choosing an appropriate number for the length, you make
it appear to the solver that all the rooms in level A are closer to each
other than any of the rooms in level B.
This means that priority will be given to tasks in rooms in the same level
as you are now, (hopefully) minimizing the number of level changes.
Note that the
\family typewriter
length
\family default
attribute doesn't affect map drawing at all.
\end_layout
\begin_layout Subsubsection
Closing off paths
\end_layout
\begin_layout Standard
There may be times when you want a map connection to appear on the map,
but not be used in solving the game---for example, it may be certain death
to go that way.
You can use the
\family typewriter
nopath
\family default
attribute of rooms, links and joins to indicate this.
It doesn't affect map output in any way.
\end_layout
\begin_layout Standard
Another use for this attribute is to force the game solver to do things
in a different order.
This might be preferable to adding fake task dependencies.
\end_layout
\begin_layout Subsubsection
Ignoring parts of the solution
\end_layout
\begin_layout Standard
Sometimes it's useful to be able to ignore certain parts of the solution---for
example, if you want to generate a sequence of game commands that get you
to a particular position as quickly as possible.
To that end, you can mark tasks and items with the
\family typewriter
ignore
\family default
attribute.
An ignored task will never be attempted, and an ignored item will never
be picked up.
This means that anything dependent on those tasks or items will not be
done either.
The game will very probably be unsolvable as a result, unless you've ignored
an unused item, or ignored a task that's done elsewhere via a
\family typewriter
do
\family default
clause.
\end_layout
\begin_layout Subsubsection
Keeping fixes together
\end_layout
\begin_layout Standard
It's probably best to keep all your
\begin_inset Quotes eld
\end_inset
game tweaks
\begin_inset Quotes srd
\end_inset
together, separate from the
\begin_inset Quotes eld
\end_inset
pure
\begin_inset Quotes srd
\end_inset
game, and commented appropriately.
You can do this by using commands which just modify existing objects, instead
of creating new ones, by referring to their tags.
As an example, suppose you have the following situation:
\end_layout
\begin_layout LyX-Code
room "Top of Chute" ...;
\end_layout
\begin_layout LyX-Code
room "Bottom of Chute" dir s go down oneway;
\end_layout
\begin_layout LyX-Code
task "Do something weird" tag weird_task;
\end_layout
\begin_layout LyX-Code
...
\end_layout
\begin_layout Standard
Suppose you're at the top of the chute, and that there's some stuff to be
done at the bottom, but no immediate way back up.
As usual, the game solver balks at taking a one-way trip and will do anything
to avoid it.
But suppose you know that, as long as you have your giant inflatable cheeseburg
er, you can get back out again.
You can say:
\end_layout
\begin_layout LyX-Code
# Bottom of chute isn't that scary.
\end_layout
\begin_layout LyX-Code
task weird_task need burger safe;
\end_layout
\begin_layout Standard
which modifies the task at the bottom of the chute to (a) require the burger
(so that you won't go down there without it), and (b) be considered safe
by the game solver.
So it will happily slide down the chute without getting stuck at the bottom.
\end_layout
\begin_layout Standard
This way of modifying previous objects applies all types of object, even
links and joins---these can be tagged too, in the normal way.
The single exception is the implicit link created by the room
\family typewriter
dir
\family default
clause.
These links automatically get tagged when the room does, and with the same
name.
So the two-level example above could be split into:
\end_layout
\begin_layout LyX-Code
room "Level A" tag LA ...;
\end_layout
\begin_layout LyX-Code
room "Level B" tag LB dir e;
\end_layout
\begin_layout LyX-Code
...
\end_layout
\begin_layout LyX-Code
# Stop gratuitous travel between levels.
\end_layout
\begin_layout LyX-Code
link LB length 50;
\end_layout
\begin_layout Subsubsection
Displaying solver messages
\end_layout
\begin_layout Standard
Finally, you can gain an insight into what the game solver's up to by setting
the
\family typewriter
solver_messages
\family default
variable (either in one of the input files, or via the
\family typewriter
-set
\family default
command-line option).
This produces reams of output giving details of the game solver's thoughts
before it does anything.
It's supposed to be self-explanatory, but my view is slightly biased.
Detailed documentation may follow (a) if enough people ask for it, and
(b) if I ever get around to it.
\end_layout
\begin_layout Subsection
Limitations
\end_layout
\begin_layout Standard
Given the wild imaginations of today's IF authors, there are bound to be
some game solving situations that can't easily be dealt with using IFM.
Some of the things that IFM ignores are:
\end_layout
\begin_layout Itemize
Random events.
For example, the Carousel room in Zork, and all the NPCs in Colossal Cave.
There's no way to address this problem, but then again, hand-written walkthroug
hs have the same difficulty.
However, if you're trying to tailor recording output so that it will play
back properly in an interpreter, there is a workaround---see Section
\begin_inset LatexCommand \ref{sec:recording}
\end_inset
.
\end_layout
\begin_layout Itemize
Carrying capacity.
A solution may require you to carry more than you're allowed.
This might be addressed in a future version, but inventory-juggling puzzles
are out of fashion these days (if they were ever in) so this is not much
of a problem.
Some games provide you with an item that can carry stuff for you---if so,
a workaround is to add some special tasks that periodically put everything
you're carrying into it.
\end_layout
\begin_layout Standard
There are some other limitations that are the result of certain keyword
combinations in the current implementation of IFM.
These are fixable, and hopefully will be in a later version.
They are:
\end_layout
\begin_layout Itemize
If you have more than one link or join which connects the same two rooms,
then if any of them set the
\family typewriter
length
\family default
attribute, they must
\emph on
all
\emph default
set it---and to the same value.
Otherwise IFM will give an error.
\end_layout
\begin_layout Itemize
Unsafe tasks in a
\begin_inset Quotes eld
\end_inset
follow
\begin_inset Quotes srd
\end_inset
task chain normally cause all the previous tasks in the chain to be marked
unsafe too (so the solver will avoid trying the first, knowing it'll be
forced to do something distasteful later).
However, some tasks are not known to be unsafe until just before they might
be done---specifically, those for which there is no return path.
This is because whether there's a return path depends on where you are
now.
So a
\begin_inset Quotes eld
\end_inset
follow
\begin_inset Quotes srd
\end_inset
chain could possibly lead to a game-solving dead end.
\end_layout
\begin_layout Itemize
There's a problem with the
\family typewriter
leave
\family default
/
\family typewriter
need
\family default
attribute combination.
The game solver could select a path from one room to another in which an
item must be left behind at one point, but is needed for movement later
on in the path.
This sort of path should be invalid, but isn't.
\end_layout
\begin_layout Standard
\newpage
\end_layout
\begin_layout Section
Using IFM
\begin_inset LatexCommand \label{sec:using-ifm}
\end_inset
\end_layout
\begin_layout Subsection
Running the Program
\end_layout
\begin_layout Standard
IFM is run from the command line.
The general form of the command is:
\end_layout
\begin_layout LyX-Code
ifm [options] [file...]
\end_layout
\begin_layout Standard
On startup, IFM does the following.
Firstly, the system initialization file is read.
This sets defaults used by everyone.
This file is called
\family typewriter
ifm-init.ifm
\family default
, and is found by searching a standard set of directories.
You can prepend to this search path by setting the environment variable
\family typewriter
IFMPATH
\family default
to be a colon-separated list of directories.
\end_layout
\begin_layout Standard
Then, if you have a personal initialization file, that is read.
This file is found in the directory specified by your
\family typewriter
HOME
\family default
environment variable.
On Unix-like systems it is called
\family typewriter
.ifmrc
\family default
, and on Win32 systems it is called
\family typewriter
ifm.ini
\family default
.
You can use this file to customize the default variable settings for different
types of output.
\end_layout
\begin_layout Standard
Then input from the file(s) on the command-line is read.
If no files were specified,
\family typewriter
stdin
\family default
is read.
A filename equal to
\family typewriter
-
\family default
also indicates that
\family typewriter
stdin
\family default
should be read at that point.
\end_layout
\begin_layout Standard
If any of the
\family typewriter
-map
\family default
,
\family typewriter
-items
\family default
,
\family typewriter
-tasks
\family default
or
\family typewriter
-show
\family default
options was specified, the appropriate output is produced.
If not, only a syntax check of the input is done.
\end_layout
\begin_layout Standard
When producing output, the output format specified by the
\family typewriter
-format
\family default
option is used.
If this was not specified, the first format in the list which supports
this type of output is chosen.
\end_layout
\begin_layout Standard
Some of the output formats use additional library files to do their work.
For example, the PostScript output format prepends a standard
\begin_inset Quotes eld
\end_inset
prologue
\begin_inset Quotes srd
\end_inset
file to all output.
These files are found using the same search path as the system initialization
file (see above).
\end_layout
\begin_layout Standard
Here's a summary of the command-line options (which can be abbreviated),
starting with the output options:
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-m,\InsetSpace ~
-map[=SECTIONS]
\family default
\InsetSpace ~
\newline
Draw a map of the game.
You can optionally specify a list of the map sections to print.
The list is a comma-separated set of map section numbers (starting from
1) and can include ranges.
For example, the argument
\family typewriter
1,3-5
\family default
would print map sections 1, 3, 4 and 5.
If the list isn't specified, all sections are printed.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-i,\InsetSpace ~
-items
\family default
Print a list of items which appear in the game.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-t,\InsetSpace ~
-tasks
\family default
Print a list of tasks required to solve the game.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-f,\InsetSpace ~
-format
\family default
\InsetSpace ~
\family typewriter
FORMAT
\family default
\InsetSpace ~
\newline
Specify the output format.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-o,\InsetSpace ~
-output
\family default
\InsetSpace ~
\family typewriter
FILE
\family default
\InsetSpace ~
\newline
Write to the specified file, instead of stdout.
\end_layout
\begin_layout Standard
Next comes the auxiliary options:
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-I,\InsetSpace ~
-include\InsetSpace ~
DIR
\family default
\InsetSpace ~
\newline
Prepend the specified directory to the library and include file search
path.
This option may be repeated.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-S,\InsetSpace ~
-style\InsetSpace ~
STYLE
\family default
\InsetSpace ~
\newline
Set a global style.
See Section
\begin_inset LatexCommand \ref{sec:customization}
\end_inset
for more details.
This option may be repeated.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-s,\InsetSpace ~
-set\InsetSpace ~
VAR=VALUE
\family default
\InsetSpace ~
\newline
Set a customization variable.
This overrides any settings in the input files.
This option may be repeated.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-noinit
\family default
Don't read your personal init file.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-w,\InsetSpace ~
-nowarn
\family default
Don't print warnings.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMM
\family typewriter
-e,\InsetSpace ~
-errors\InsetSpace ~
NUM
\family default
\InsetSpace ~
\newline
Print this many errors before aborting (default: 10).
If set to zero, print all errors.
\end_layout
\begin_layout Standard
Finally, here are the information options:
\end_layout
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
-show
\family default
\InsetSpace ~
\family typewriter
TYPE
\family default
Show one of several types of information, and exit.
The
\family typewriter
TYPE
\family default
argument can be one of:
\end_layout
\begin_deeper
\begin_layout List
\labelwidthstring MMMM
\family typewriter
maps
\family default
Show a list of all the map sections defined in the input.
This is useful for finding the numbers of the map sections you want to
print.
\end_layout
\begin_layout List
\labelwidthstring MMMM
\family typewriter
path
\family default
Show the directories that are searched for library and include files.
\end_layout
\begin_layout List
\labelwidthstring MMMM
\family typewriter
vars
\family default
Show a complete list of defined variables, in a format suitable for feeding
back into IFM.
See Section
\begin_inset LatexCommand \ref{sec:output-variables}
\end_inset
.
\end_layout
\end_deeper
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
-version
\family default
Print the program version.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
-help
\family default
Just print some usage information.
\end_layout
\begin_layout Subsection
Types of Output
\end_layout
\begin_layout Standard
IFM has three different types of output (a map, a list of items, and a list
of tasks) and several different output formats, which are described in
the following sections.
Not all types of output are produced by each output format.
Table
\begin_inset LatexCommand \ref{tab:output-formats}
\end_inset
shows what's available for each format.
\begin_inset Float table
placement htbp
wide false
sideways false
status collapsed
\begin_layout Standard
\align center
\begin_inset Tabular
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
PostScript
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Fig
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Tk
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Text
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Rec
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Dot
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Raw
\end_layout
\end_inset
|
|
\begin_inset Text
\begin_layout Standard
Map
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
|
\begin_inset Text
\begin_layout Standard
Items
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
|
\begin_inset Text
\begin_layout Standard
Tasks
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Yes
\end_layout
\end_inset
|
\end_inset
\end_layout
\begin_layout Caption
IFM output formats
\begin_inset LatexCommand \label{tab:output-formats}
\end_inset
\end_layout
\end_inset
\end_layout
\begin_layout Standard
All the map output formats display map sections in the same way, so that
what you get with one format looks much the same as another.
\begin_inset Foot
status collapsed
\begin_layout Standard
Well, that's the goal anyway.
But there are still some very minor differences.
\end_layout
\end_inset
\end_layout
\begin_layout Subsubsection
PostScript Maps (
\family typewriter
ps
\family default
)
\end_layout
\begin_layout Standard
This produces a PostScript map suitable for printing.
Several map sections may be printed per page, and the maps are printed
over as many pages as it takes.
Automatic packing is done to try to get a good fit on the page.
Also, portrait or landscape is chosen depending on whichever gives the
best fit.
Fonts of room and item text are scaled to fit them in the room boxes, if
required.
\end_layout
\begin_layout Subsubsection
Fig Maps (
\family typewriter
fig
\family default
)
\end_layout
\begin_layout Standard
This produces a map which can be read (and edited) by Xfig, and any other
programs which understand Fig format.
The map sections are packed to get a best fit automatically, in a similar
manner to PostScript, but since Fig has no concept of pages, it is most
useful when you're printing each map section individually.
There's a utility program called
\family typewriter
ifm2dev
\family default
which automatically does this---see Section
\begin_inset LatexCommand \ref{sec:ifm2dev}
\end_inset
.
\end_layout
\begin_layout Standard
Fig format is also useful if you want to print poster-sized maps over several
pages.
The
\family typewriter
-M
\family default
option of
\family typewriter
fig2dev
\family default
(part of the
\family typewriter
transfig
\family default
package) will automatically do this.
\end_layout
\begin_layout Subsubsection
Tk Drawing Commands (
\family typewriter
tk)
\end_layout
\begin_layout Standard
This produces map commands for input to
\family typewriter
tkifm
\family default
, a simple graphical interface to IFM (see Section
\begin_inset LatexCommand \ref{sec:tkifm}
\end_inset
).
It isn't very useful to produce this output yourself---
\family typewriter
tkifm
\family default
does that internally to build its map pictures.
But you can control its display by setting variables in the usual way.
\end_layout
\begin_layout Subsubsection
ASCII Text (
\family typewriter
text
\family default
)
\end_layout
\begin_layout Standard
This produces human-readable output for items and tasks.
The output should be fairly self-explanatory.
\end_layout
\begin_layout Subsubsection
Recording Commands (
\family typewriter
rec
\family default
)
\begin_inset LatexCommand \label{sec:recording}
\end_inset
\end_layout
\begin_layout Standard
This output produces a list of commands suitable for feeding to IF interpreters
in playback mode.
All the commands in the output are converted to uppercase.
\end_layout
\begin_layout Standard
In order for this to work properly, you have to give commands that the game
will understand.
The
\family typewriter
cmd
\family default
attribute of rooms, links, joins and tasks can help with this.
Currently there's no item
\family typewriter
cmd
\family default
attribute, so you have to make sure that the item description is recognized
by the game (for
\family typewriter
get
\family default
and
\family typewriter
drop
\family default
commands).
Also, if a task is implicitly done in the game without you having to type
any commands (e.g., visiting a room), you can indicate this by using
\family typewriter
cmd\InsetSpace ~
none
\family default
.
\end_layout
\begin_layout Standard
Of course, a recording will only play back properly in an interpreter if
it provides correct game commands.
Random events can't be dealt with by IFM, and will probably cause playback
to fail.
But you can work around this with an interpreter that is able to fix the
random seed at startup (e.g.,
\family typewriter
frotz
\family default
).
This should eliminate most (but not all) of the problems of randomness.
\end_layout
\begin_layout Subsubsection
Task Dependencies (
\family typewriter
dot
\family default
)
\end_layout
\begin_layout Standard
This produces a graph of the dependencies of tasks on each other, in Graphviz
(dot) format.
You'll need to have Graphviz installed in order to display the graph; you
can get it from
\begin_inset LatexCommand \url{www.graphviz.org}
\end_inset
.
\end_layout
\begin_layout Subsubsection
Raw Data (
\family typewriter
raw
\family default
)
\end_layout
\begin_layout Standard
This produces raw data for all output formats, intended for use by other
programs (and the IFM regression test suite).
Each entry consists of a number of data lines, and is separated from other
entries by a blank line.
Each data line consists of an attribute, a colon, and its value.
The attributes should be self-explanatory.
\end_layout
\begin_layout Subsection
Customization
\begin_inset LatexCommand \label{sec:customization}
\end_inset
\end_layout
\begin_layout Standard
You can change the appearance of many output features according to your
taste.
You do this by setting the values of the variables that control those features.
This section tells you how to use variables---for a complete list of the
customization variables available, see Section
\begin_inset LatexCommand \ref{sec:output-variables}
\end_inset
.
\end_layout
\begin_layout Standard
As a first example, the background colour of rooms is determined by the
variable
\family typewriter
room_colour
\family default
.
Its default value is
\begin_inset Quotes eld
\end_inset
white
\begin_inset Quotes erd
\end_inset
.
It can be changed like this:
\end_layout
\begin_layout LyX-Code
room_colour = "beige";
\end_layout
\begin_layout Standard
Setting a variable like this will affect all output formats.
But in some cases you don't want to do that.
A good example is the one above---if you don't have a colour printer, you
may not want to have beige rooms printed (they'll come out greyish).
To get around that, you can set variables that are specific to a particular
output format:
\end_layout
\begin_layout LyX-Code
tk.room_colour = "beige";
\end_layout
\begin_layout Standard
This says to set the variable to
\begin_inset Quotes eld
\end_inset
beige
\begin_inset Quotes erd
\end_inset
only if producing Tk output.
The default for all other formats is still
\begin_inset Quotes eld
\end_inset
white
\begin_inset Quotes erd
\end_inset
.
\end_layout
\begin_layout Standard
You can also customize the appearance of individual rooms and links on the
map, by using different display styles.
A display style is just a group of variable settings with a given name.
For example, suppose you're making a map of Colossal Cave and want to mark
rooms where you can refill your water bottle.
You can define a style called, say, Water, like this:
\end_layout
\begin_layout LyX-Code
style Water;
\end_layout
\begin_layout LyX-Code
room_colour = "light blue";
\end_layout
\begin_layout LyX-Code
endstyle;
\end_layout
\begin_layout Standard
The values of variables that are set between the
\family typewriter
style
\family default
and
\family typewriter
endstyle
\family default
clauses only apply to things drawn in that style.
Now, if you declare rooms like this:
\end_layout
\begin_layout LyX-Code
room "At End Of Road";
\end_layout
\begin_layout LyX-Code
room "Inside Building" dir e go in style Water;
\end_layout
\begin_layout Standard
then the room
\begin_inset Quotes eld
\end_inset
Inside Building
\begin_inset Quotes erd
\end_inset
will be drawn with a light blue background.
You can customize individual links in a similar manner.
\end_layout
\begin_layout Standard
An alternative way to define a variable in a particular style is to use
the
\family typewriter
in\InsetSpace ~
style
\family default
clause, like this:
\end_layout
\begin_layout LyX-Code
room_colour = "light blue" in style Water;
\end_layout
\begin_layout Standard
If a style only changes a single variable, this may be more convenient.
\end_layout
\begin_layout Standard
If you assign a style (say, called
\begin_inset Quotes eld
\end_inset
newstyle
\begin_inset Quotes srd
\end_inset
) to an object, but don't define it anywhere in your input, then IFM will
look for a file called
\family typewriter
newstyle.ifm
\family default
using the standard search path.
If the file exists, it is expected to define style
\begin_inset Quotes eld
\end_inset
newstyle
\begin_inset Quotes srd
\end_inset
.
For example, you could put the
\begin_inset Quotes eld
\end_inset
Water
\begin_inset Quotes erd
\end_inset
style definition above into a file called
\family typewriter
Water.ifm
\family default
somewhere on the IFM search path, and it would be read automatically.
This is useful if, for example, you want to use the same style in several
different maps.
\end_layout
\begin_layout Standard
You can define global styles using the
\family typewriter
-style
\family default
command-line option; these apply to all IFM objects.
Global styles are most useful when setting variables that affect the overall
appearance of the output, in conjunction with the file search method described
above (e.g.\InsetSpace ~
a file containing general colour and font definitions).
\end_layout
\begin_layout Subsection
Output Variables
\begin_inset LatexCommand \label{sec:output-variables}
\end_inset
\end_layout
\begin_layout Standard
There are many variables available for customizing output.
Most of them are for customizing map output.
Their names, descriptions and default values are all contained in the IFM
initialization file.
You can change this file to set global defaults for everybody, or alternatively
set your own preferences in your personal init file.
\end_layout
\begin_layout Standard
Here's the original initialization file that came bundled with IFM.
\end_layout
\begin_layout LyX-Code
\size small
\begin_inset Include \verbatiminput{../lib/ifm-init.ifm}
preview false
\end_inset
\end_layout
\begin_layout Subsection
Predefined Styles
\begin_inset LatexCommand \label{sec:style-defs}
\end_inset
\end_layout
\begin_layout Standard
IFM comes with a few predefined style files, as shown in Table
\begin_inset LatexCommand \ref{tab:styles}
\end_inset
.
\begin_inset Foot
status collapsed
\begin_layout Standard
If you create any generally useful or nice-looking styles, you might want
to send me a copy so I can include them with the next version of IFM.
\end_layout
\end_inset
The
\begin_inset Quotes eld
\end_inset
scope
\begin_inset Quotes erd
\end_inset
field indicates which type of IFM object it applies to.
Styles that have global scope can meaningfully be used by the
\family typewriter
-style
\family default
command-line option.
\begin_inset Float table
placement htbp
wide false
sideways false
status collapsed
\begin_layout Standard
\align center
\begin_inset Tabular
|
\begin_inset Text
\begin_layout Standard
\series bold
Style
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\series bold
Scope
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\series bold
Description
\end_layout
\end_inset
|
|
\begin_inset Text
\begin_layout Standard
\family typewriter
helvetica
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Global
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Use Helvetica fonts everywhere in maps
\end_layout
\end_inset
|
|
\begin_inset Text
\begin_layout Standard
\family typewriter
puzzle
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Room
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Mark room as containing a puzzle
\end_layout
\end_inset
|
|
\begin_inset Text
\begin_layout Standard
\family typewriter
special
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
\family typewriter
Link
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Mark link as being special in some way
\end_layout
\end_inset
|
|
\begin_inset Text
\begin_layout Standard
\family typewriter
reckless
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Global
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Treat all tasks as safe when solving the game
\end_layout
\end_inset
|
|
\begin_inset Text
\begin_layout Standard
\family typewriter
verbose
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Global
\end_layout
\end_inset
|
\begin_inset Text
\begin_layout Standard
Print verbose solver messages
\end_layout
\end_inset
|
\end_inset
\end_layout
\begin_layout Caption
Predefined styles
\begin_inset LatexCommand \label{tab:styles}
\end_inset
\end_layout
\end_inset
\end_layout
\begin_layout Standard
\newpage
\end_layout
\begin_layout Section
Language
\begin_inset LatexCommand \label{sec:language}
\end_inset
\end_layout
\begin_layout Standard
This section gives a complete detailed description of the IFM language.
\end_layout
\begin_layout Subsection
Symbols
\begin_inset LatexCommand \label{sec:symbols}
\end_inset
\end_layout
\begin_layout Standard
In the following sections, these symbols are used:
\end_layout
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
ID
\family default
A name starting with a letter, followed by any combination of upper- and
lowercase letters or numbers or an underscore.
For example,
\family typewriter
Dense_Forest
\family default
.
IDs are not allowed to clash with reserved words (e.g.,
\family typewriter
room
\family default
, or
\family typewriter
tag
\family default
).
One way to avoid this is to capitalize all tags (reserved words are all
in lowercase).
\end_layout
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
STRING
\family default
Any sequence of characters, in double-quotes.
For example,
\family typewriter
"Black\InsetSpace ~
Rod"
\family default
.
To get a double-quote inside a string, quote it using a backslash, like
this:
\end_layout
\begin_deeper
\begin_layout LyX-Code
\align block
"Ground Floor,
\backslash
"A
\backslash
" Block"
\end_layout
\begin_layout Standard
You can continue strings on several lines---a newline-and-whitespace sequence
is translated into a single space, just like in TADS and Inform.
\end_layout
\end_deeper
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
NUMBER
\family default
A number.
If the context requires an integer, the number is silently rounded to the
larges integer not greater than this value.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
COMPASS
\family default
A compass direction, which can be abbreviated or in full (e.g.\InsetSpace ~
\family typewriter
n
\family default
,
\family typewriter
se
\family default
,
\family typewriter
northwest
\family default
, etc).
\end_layout
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
OTHERDIR
\family default
One of
\family typewriter
up
\family default
,
\family typewriter
down
\family default
,
\family typewriter
in
\family default
or
\family typewriter
out
\family default
.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
[\SpecialChar \ldots{}
]
\family default
An optional part.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMM
\family typewriter
A\InsetSpace ~
|\InsetSpace ~
B
\family default
Either
\family typewriter
A
\family default
or
\family typewriter
B
\family default
.
\end_layout
\begin_layout Subsection
Format
\end_layout
\begin_layout Standard
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 (
\family typewriter
#
\family default
) and continuing to the end of the line.
All commands are terminated with a semicolon.
\end_layout
\begin_layout Subsection
Control
\end_layout
\begin_layout Standard
The overall title of the map may be set using the command
\end_layout
\begin_layout LyX-Code
title STRING;
\end_layout
\begin_layout Standard
If a map has several sections, you can set the title of each section using
the command
\end_layout
\begin_layout LyX-Code
map STRING;
\end_layout
\begin_layout Standard
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
\family typewriter
map
\family default
command just before the room that starts a new map section.
\end_layout
\begin_layout Standard
If your map uses features that are only present in later versions of IFM,
you can indicate that up front by using the command
\end_layout
\begin_layout LyX-Code
require NUMBER;
\end_layout
\begin_layout Standard
Then, if the IFM version number is less than this number, parsing will abort
immediately, avoiding lots of potentially confusing syntax errors.
\begin_inset Foot
status collapsed
\begin_layout Standard
There's no point in requiring any version less than 5.0, since that's when
the
\family typewriter
require
\family default
syntax was added.
\end_layout
\end_inset
\end_layout
\begin_layout Subsection
Tags
\end_layout
\begin_layout Standard
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.
\end_layout
\begin_layout Standard
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
\family typewriter
from\InsetSpace ~
ID
\family default
clause (see Section
\begin_inset LatexCommand \ref{sec:rooms}
\end_inset
) and tags in commands that modify existing objects (see Section
\begin_inset LatexCommand \ref{sec:commands}
\end_inset
)---these tags must be defined before being used.
\end_layout
\begin_layout Standard
The special tag
\family typewriter
last
\family default
may be used to refer to the last object that was defined (depending on
the context).
Also, within an individual command, the special tag
\family typewriter
it
\family default
may be used to refer to the most recent object tag.
\end_layout
\begin_layout Subsection
Commands
\begin_inset LatexCommand \label{sec:commands}
\end_inset
\end_layout
\begin_layout Standard
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:
\end_layout
\begin_layout LyX-Code
[attribute-list];
\end_layout
\begin_layout Standard
For rooms, items and tasks,
\family typewriter
\family default
is just a string description.
For links and joins, it specifies two room tags to link or join together.
\end_layout
\begin_layout Standard
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.
\end_layout
\begin_layout Standard
Once an object as been declared with a tag name, its attributes can be modified
by later commands referring to that tag, like this:
\end_layout
\begin_layout LyX-Code
ID [attribute-list];
\end_layout
\begin_layout Standard
where
\family typewriter
ID
\family default
is the tag name of the object.
Note that the tag must be defined earlier in the file than it is used.
\end_layout
\begin_layout Subsubsection
Rooms
\begin_inset LatexCommand \label{sec:rooms}
\end_inset
\end_layout
\begin_layout Standard
A new room is added using the command
\end_layout
\begin_layout LyX-Code
room STRING [attribute-list];
\end_layout
\begin_layout Standard
where
\family typewriter
STRING
\family default
is a description of the room.
Room attributes can be:
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
tag\InsetSpace ~
ID
\family default
Give the room a tag name, so that you can refer to it elsewhere.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
dir\InsetSpace ~
COMPASS\InsetSpace ~
[NUMBER]\InsetSpace ~
[COMPASS\InsetSpace ~
[NUMBER]\SpecialChar \ldots{}
]\InsetSpace ~
[from ID] \InsetSpace ~
\newline
\family default
Specify the position of the room relative to the room with the given tag
ID (which must be defined before it is used).
If no
\family typewriter
from
\family default
clause is specified, the last defined room is used instead.
There can be more than one direction given---the new room is placed relative
to the previous one using them.
Following a direction with a number means to repeat it that many times.
\end_layout
\begin_deeper
\begin_layout Standard
The
\family typewriter
dir
\family default
clause creates an implicit link between this room and the previous one.
Some of the room attributes below behave differently depending on whether
they appear before or after the
\family typewriter
dir
\family default
clause in the attribute list.
\end_layout
\begin_layout Standard
If the room is given a tag name, then the implicit link will be given the
same tag.
\end_layout
\end_deeper
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
link\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
] \InsetSpace ~
\newline
\family default
Specify other rooms that this room links to.
Note that this creates a link with no special attributes---use the standalone
\family typewriter
link
\family default
command for that (see Section
\begin_inset LatexCommand \ref{sec:links}
\end_inset
).
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
join\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
] \InsetSpace ~
\newline
\family default
Specify rooms on other map sections that this room joins to.
Note that this creates a join with no special attributes---use the standalone
\family typewriter
join
\family default
command for that (see Section
\begin_inset LatexCommand \ref{sec:joins}
\end_inset
).
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
exit\InsetSpace ~
COMPASS\InsetSpace ~
[COMPASS\SpecialChar \ldots{}
] \InsetSpace ~
\newline
\family default
Indicate which other directions the room has exits in.
Room exits in a particular direction are marked on the map only if there
is no link going to or from the room in that direction.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
note\InsetSpace ~
STRING \InsetSpace ~
\newline
\family default
Append a note to the room's note list.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
score\InsetSpace ~
NUMBER \InsetSpace ~
\newline
\family default
Indicate that you score the specified number of points when visiting this
room for the first time.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
need\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
] \InsetSpace ~
\newline
\family default
If this appears before a
\family typewriter
dir
\family default
clause, indicate that you can only enter this room after getting the specified
items.
If it appears afterwards, it applies to the implicit link instead.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
after\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
] \InsetSpace ~
\newline
\family default
If this appears before a
\family typewriter
dir
\family default
clause, indicate that you can only enter this room after doing the specified
tasks.
If it appears afterwards, it applies to the implicit link instead.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
before\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
] \InsetSpace ~
\newline
\family default
If this appears before a
\family typewriter
dir
\family default
clause, indicate that you can only enter this room before doing the specified
tasks.
If it appears afterwards, it applies to the implicit link instead.
Those tasks are marked unsafe.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
leave\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
] \InsetSpace ~
\newline
\family default
If this appears before a
\family typewriter
dir
\family default
clause, indicate that the specified items, if carried, must be left behind
when entering the room.
If it appears afterwards, it applies to the implicit link instead.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
leave\InsetSpace ~
all\InsetSpace ~
[except\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]] \InsetSpace ~
\newline
\family default
As above, except indicate that
\emph on
all
\emph default
items must be left behind.
The
\family typewriter
except
\family default
clause can be used to omit specific items.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
go\InsetSpace ~
OTHERDIR \InsetSpace ~
\newline
\family default
Indicate that the link to this room is in the specified direction.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
STRING \InsetSpace ~
\newline
\family default
Specify the command you type to move to this room from the previous one.
If no
\family typewriter
cmd
\family default
clause is given, the command is deduced from the
\family typewriter
go
\family default
clause.
If that isn't specified, the command will be deduced from the
\family typewriter
dir
\family default
clause.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
from\InsetSpace ~
STRING \InsetSpace ~
\newline
\family default
As above, but this specifies the command to go in the other direction.
This defaults to the
\family typewriter
cmd\InsetSpace ~
to
\family default
command, if specified.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
to\InsetSpace ~
STRING \InsetSpace ~
\newline
\family default
This is identical to
\family typewriter
cmd
\family default
on its own, and only exists for symmetry.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
oneway
\family default
Indicate that the return journey from this room to the previous one is
not possible.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
length\InsetSpace ~
NUMBER \InsetSpace ~
\newline
\family default
Indicate that the direction link to this room has the specified length (default
1).
This only affects the calculation of the nearest task when solving the
game---see Section
\begin_inset LatexCommand \ref{sec:tasks}
\end_inset
.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
start
\family default
Indicate that this is the room the player starts in.
Default is for the first room mentioned to be the start room.
If more than one room has this attribute, the last one declared takes precedenc
e.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
finish
\family default
Indicate that entering this room finishes the game.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
nodrop
\family default
Indicate that no items should be voluntarily dropped in this room.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
nolink
\family default
Indicate that this room does not have an implicit link with the previous
one via the
\family typewriter
dir
\family default
clause.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
nopath
\family default
Indicate that the implicit link from this room should not be used by the
game solver.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
style\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
] \InsetSpace ~
\newline
\family default
Add a list of display styles to the room (and also the implicit link, if
any).
See Section
\begin_inset LatexCommand \ref{sec:styles}
\end_inset
.
\end_layout
\begin_layout Subsubsection
Items
\begin_inset LatexCommand \label{sec:items}
\end_inset
\end_layout
\begin_layout Standard
An item is introduced using the command
\end_layout
\begin_layout LyX-Code
item STRING [attribute-list];
\end_layout
\begin_layout Standard
where
\family typewriter
STRING
\family default
is the item description.
Item attributes can be:
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
tag\InsetSpace ~
ID
\family default
Give the item a tag name, so you can refer to it elsewhere.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
in\InsetSpace ~
ID
\family default
Set the initial location of this item.
Default is the last defined room.
If there is no last room (i.e.\InsetSpace ~
an item was declared before any room was declared),
then this item is initially carried by the player.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
note\InsetSpace ~
STRING
\family default
\InsetSpace ~
\newline
Append a note to the item's note list.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
score\InsetSpace ~
NUMBER
\family default
\InsetSpace ~
\newline
Indicate that you get points the first time you pick this item up.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
hidden
\family default
Indicate that this item is not immediately obvious when entering the room.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
keep
\family default
Indicate that this item shouldn't ever be dropped (no
\begin_inset Quotes eld
\end_inset
drop
\begin_inset Quotes erd
\end_inset
task should be generated).
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
keep\InsetSpace ~
with\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that the item shouldn't be dropped until all the other specified
items have left the inventory.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
keep\InsetSpace ~
until\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that the item shouldn't be dropped until all the other specified
tasks have been done.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
ignore
\family default
Indicate that this item should be ignored when trying to find a solution
(i.e., never go out of your way to pick it up).
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
given
\family default
Indicate that this item didn't have to be picked up when it entered the
inventory (no
\begin_inset Quotes eld
\end_inset
get
\begin_inset Quotes erd
\end_inset
task should be generated).
This attribute is obsolete---you should use the task
\family typewriter
give
\family default
clause instead (see Section
\begin_inset LatexCommand \ref{sec:tasks}
\end_inset
).
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
lost
\family default
Indicate that this item wasn't dropped when it left the inventory (no
\begin_inset Quotes eld
\end_inset
drop
\begin_inset Quotes erd
\end_inset
task should be generated).
Normally you should use the task
\family typewriter
drop
\family default
or
\family typewriter
lose
\family default
clauses instead (see Section
\begin_inset LatexCommand \ref{sec:tasks}
\end_inset
).
The only use for this attribute is for items that are left behind due to
a
\family typewriter
leave
\family default
clause.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
need\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that you can only pick this item up after getting the specified
items.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
after\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate you can only pick this item up after the specified tasks are done.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
before\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate you can only pick this item up before the specified tasks are
done.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
finish
\family default
Indicate that getting this item finishes the game.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
style\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Add a list of display styles to the item.
See Section
\begin_inset LatexCommand \ref{sec:styles}
\end_inset
.
\end_layout
\begin_layout Subsubsection
Links
\begin_inset LatexCommand \label{sec:links}
\end_inset
\end_layout
\begin_layout Standard
You can create extra room links using the command
\end_layout
\begin_layout LyX-Code
link ID to ID [attribute-list];
\end_layout
\begin_layout Standard
and the following attributes may be specified:
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
tag\InsetSpace ~
ID
\family default
Give the link a tag name, so you can refer to it elsewhere.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
dir\InsetSpace ~
COMPASS\InsetSpace ~
[COMPASS\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Set the intermediate directions that this link travels in, in the same
manner as for rooms.
Note that if you omit the final direction to the linked room, it is added
automatically.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
go\InsetSpace ~
OTHERDIR
\family default
\InsetSpace ~
\newline
Indicate that the link is in the specified direction.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
STRING
\family default
\InsetSpace ~
\newline
Specify the command you type to go in this direction.
If no
\family typewriter
cmd
\family default
clause is given, the command is deduced from the
\family typewriter
go
\family default
clause.
If that isn't specified, the command will be deduced from the
\family typewriter
dir
\family default
clause.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
from\InsetSpace ~
STRING
\family default
\InsetSpace ~
\newline
As above, but this specifies the command to go in the other direction.
This defaults to the
\family typewriter
cmd\InsetSpace ~
to
\family default
command, if specified.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
to\InsetSpace ~
STRING
\family default
\InsetSpace ~
\newline
This is identical to
\family typewriter
cmd
\family default
on its own, and only exists for symmetry.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
oneway
\family default
Indicate that this is a one-way link, in a similar manner to the room attribute
of the same name.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
hidden
\family default
Indicate that this link should not be drawn on the map.
Hidden links are still used when solving the game.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
nopath
\family default
Indicate that this link should not be used by the game solver.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
length\InsetSpace ~
NUMBER
\family default
\InsetSpace ~
\newline
Indicate that this link has the specified length (default 1).
This only affects the calculation of the nearest task when solving the
game---see Section
\begin_inset LatexCommand \ref{sec:tasks}
\end_inset
.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
need\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that you can only go in this direction after getting the specified
items.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
after\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that you can only go in this direction after doing the specified
tasks.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
before\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that you can only go in this direction before doing the specified
tasks.
These tasks are marked unsafe.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
leave\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that the specified items, if carried, must be left behind when
using this connection.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
leave\InsetSpace ~
all\InsetSpace ~
[except\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]]
\family default
\InsetSpace ~
\newline
As above, except indicate that
\emph on
all
\emph default
items must be left behind.
The
\family typewriter
except
\family default
clause can be used to omit specific items.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
style\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Add a list of display styles to the link.
See Section
\begin_inset LatexCommand \ref{sec:styles}
\end_inset
.
\end_layout
\begin_layout Subsubsection
Joins
\begin_inset LatexCommand \label{sec:joins}
\end_inset
\end_layout
\begin_layout Standard
There is a standalone
\family typewriter
join
\family default
command which joins two rooms on different map sections:
\end_layout
\begin_layout LyX-Code
join ID to ID [attribute-list];
\end_layout
\begin_layout Standard
The following attributes may be specified:
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
tag\InsetSpace ~
ID
\family default
Give the join a tag name, so you can refer to it elsewhere.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
go\InsetSpace ~
COMPASS\InsetSpace ~
|\InsetSpace ~
OTHERDIR
\family default
\InsetSpace ~
\newline
Indicate that the join to this room is in the specified direction.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
STRING
\family default
\InsetSpace ~
\newline
Specify the command you type to go in this direction.
If no
\family typewriter
cmd
\family default
clause is given, the command is deduced from the
\family typewriter
go
\family default
clause.
If that isn't specified, the command will be undefined.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
from\InsetSpace ~
STRING
\family default
\InsetSpace ~
\newline
As above, but this specifies the command to go in the other direction.
This defaults to the
\family typewriter
cmd\InsetSpace ~
to
\family default
command, if specified.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
to\InsetSpace ~
STRING
\family default
\InsetSpace ~
\newline
This is identical to
\family typewriter
cmd
\family default
on its own, and only exists for symmetry.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
oneway
\family default
Indicate that this is a one-way join, in a similar manner to the room attribute
of the same name.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
hidden
\family default
Indicate that this join should not be drawn on the map.
Hidden joins are still used when solving the game.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
nopath
\family default
Indicate that this join should not be used by the game solver.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
length\InsetSpace ~
NUMBER
\family default
\InsetSpace ~
\newline
Indicate that this join has the specified length (default 1).
This only affects the calculation of the nearest task when solving the
game---see Section
\begin_inset LatexCommand \ref{sec:tasks}
\end_inset
.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
need\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that you can only go in this direction after getting the specified
items.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
after\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that you can only go in this direction after doing the specified
tasks.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
before\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that you can only go in this direction before doing the specified
tasks.
These tasks are marked unsafe.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
leave\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that the specified items, if carried, must be left behind when
using this connection.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
leave\InsetSpace ~
all\InsetSpace ~
[except\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]]
\family default
\InsetSpace ~
\newline
As above, except indicate that
\emph on
all
\emph default
items must be left behind.
The
\family typewriter
except
\family default
clause can be used to omit specific items.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
style\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Add a list of display styles to the join.
See Section
\begin_inset LatexCommand \ref{sec:styles}
\end_inset
.
\end_layout
\begin_layout Subsubsection
Tasks
\begin_inset LatexCommand \label{sec:tasks}
\end_inset
\end_layout
\begin_layout Standard
You can indicate tasks which need to be done in order to solve the game
using the command
\end_layout
\begin_layout LyX-Code
task STRING [attribute-list];
\end_layout
\begin_layout Standard
and these are the available attributes:
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
tag\InsetSpace ~
ID
\family default
Give the task a tag name, so you can refer to it elsewhere.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
in\InsetSpace ~
ID
\family default
Specify the room the task must be done in.
If this clause is omitted, it defaults to the last defined room.
You can use the special word
\family typewriter
any
\family default
to indicate that the task may be performed anywhere.
A task declared before any room is equivalent to saying
\family typewriter
in\InsetSpace ~
any
\family default
.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
need\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that the specified items are required before you can do this task.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
after\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that this task can only be done after all the specified tasks
have been done.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
follow\InsetSpace ~
ID
\family default
\InsetSpace ~
\newline
Indicate that this task must be done immediately after the specified one.
Not even a
\begin_inset Quotes eld
\end_inset
drop item
\begin_inset Quotes erd
\end_inset
task is allowed in between.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
do\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that doing this task also causes the specified other tasks to
be done (if they aren't done already).
These other tasks are done immediately, without regard for any prerequisite
items or tasks they might need, and their effects are carried out---including
any
\begin_inset Quotes eld
\end_inset
do
\begin_inset Quotes erd
\end_inset
clauses they might have, recursively.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
get\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that doing this task enables you to get the specified items, and
must be done before you can get them.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
give\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that doing this task puts the specified items straight into your
inventory, wherever they happen to be.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
lose\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Indicate that doing this task causes the specified items to be lost.
This implies that all tasks which need these items must be done before
this one.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
drop\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]\InsetSpace ~
[in\InsetSpace ~
ID]\InsetSpace ~
[until\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]]
\family default
\InsetSpace ~
\newline
Indicate that doing this task drops the specified items in the current
room (or the room indicated by the
\family typewriter
in
\family default
clause) if you're carrying them.
No
\begin_inset Quotes eld
\end_inset
drop
\begin_inset Quotes erd
\end_inset
message is generated.
If there's an
\family typewriter
until
\family default
clause, you can't retrieve the items until the specified tasks have been
done.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
drop\InsetSpace ~
all\InsetSpace ~
[except\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]]\InsetSpace ~
[in\InsetSpace ~
ID]\InsetSpace ~
[until\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]]
\family default
\InsetSpace ~
\newline
As above, but drop everything you're carrying.
The
\family typewriter
except
\family default
clause can be used to omit specific items.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
goto\InsetSpace ~
ID
\family default
Indicate that you get
\begin_inset Quotes eld
\end_inset
teleported
\begin_inset Quotes erd
\end_inset
to the specified room when this task is done.
This happens after
\begin_inset Quotes eld
\end_inset
give
\begin_inset Quotes erd
\end_inset
and
\begin_inset Quotes eld
\end_inset
drop
\begin_inset Quotes erd
\end_inset
actions.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
safe
\family default
Mark this task as safe---i.e.\InsetSpace ~
one that can't cause the game solver to get
stuck.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
ignore
\family default
Don't ever do this task explicitly when solving the game.
The task may still be done via a
\begin_inset Quotes eld
\end_inset
do
\begin_inset Quotes erd
\end_inset
action.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
finish
\family default
Indicate that doing this task finishes the game.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
score\InsetSpace ~
NUMBER
\family default
\InsetSpace ~
\newline
Indicate that you get the specified score for doing this task.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
note\InsetSpace ~
STRING
\family default
\InsetSpace ~
\newline
Append a note to the task's note list.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
STRING\InsetSpace ~
[NUMBER]
\family default
\InsetSpace ~
\newline
Specify the exact command you type to do the task.
If a number follows the command, do the command that many times.
Multiple
\family typewriter
cmd
\family default
clauses concatenate into a list of commands.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
cmd\InsetSpace ~
none
\family default
\InsetSpace ~
\newline
Indicate that no command is required to do this task.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
style\InsetSpace ~
ID\InsetSpace ~
[ID\SpecialChar \ldots{}
]
\family default
\InsetSpace ~
\newline
Add a list of display styles to the task.
See Section
\begin_inset LatexCommand \ref{sec:styles}
\end_inset
.
\end_layout
\begin_layout Subsection
Variables
\begin_inset LatexCommand \label{sec:variables}
\end_inset
\end_layout
\begin_layout Standard
Various aspects of output are controlled by variables.
These are set using the following syntax:
\end_layout
\begin_layout LyX-Code
[FORMAT.]ID = NUMBER | STRING | undef [in style ID];
\end_layout
\begin_layout Standard
\family typewriter
FORMAT
\family default
, if specified, is the name of a specific output format---the variable then
applies only to that output format.
\family typewriter
ID
\family default
is the name of the variable, and it can take a numeric or string value.
Note that setting a variable to the value
\family typewriter
undef
\family default
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
\begin_inset LatexCommand \ref{sec:styles}
\end_inset
).
\end_layout
\begin_layout Subsection
Styles
\begin_inset LatexCommand \label{sec:styles}
\end_inset
\end_layout
\begin_layout Standard
A
\begin_inset Quotes eld
\end_inset
style
\begin_inset Quotes erd
\end_inset
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
\end_layout
\begin_layout LyX-Code
style ID;
\end_layout
\begin_layout Standard
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
\family typewriter
in\InsetSpace ~
style
\family default
clause---see Section
\begin_inset LatexCommand \ref{sec:variables}
\end_inset
).
\end_layout
\begin_layout Standard
The command
\end_layout
\begin_layout LyX-Code
endstyle [ID];
\end_layout
\begin_layout Standard
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
\family typewriter
style
\family default
command, or a warning is given.
\end_layout
\begin_layout Standard
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.
\end_layout
\begin_layout Standard
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
\family typewriter
.ifm
\family default
suffix to the style name.
If the file is not found, or it does not define the required style, a warning
is given.
\end_layout
\begin_layout Standard
\newpage
\end_layout
\begin_layout Section
Diagnostics
\end_layout
\begin_layout Standard
This section describes the possible error and warning messages which might
be produced by IFM, and what they mean.
Note that individual output formats may print their own errors and/or warnings.
These lists only cover the standard ones.
\end_layout
\begin_layout Subsection
Error Messages
\end_layout
\begin_layout Standard
Here's the list of error messages.
If any errors occur, no output is produced.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
invalid\InsetSpace ~
repeat\InsetSpace ~
count
\family default
\InsetSpace ~
\newline
You've given a repeat count of zero or less for a string or direction,
which doesn't make much sense.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
no\InsetSpace ~
last\InsetSpace ~
room
\family default
\InsetSpace ~
\newline
You've given the very first room a
\family typewriter
dir
\family default
clause.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
no\InsetSpace ~
[type]\InsetSpace ~
referred\InsetSpace ~
to\InsetSpace ~
by\InsetSpace ~
'last'
\family default
\InsetSpace ~
\newline
You've said
\family typewriter
last
\family default
to refer to the last room, item or task that was defined, but none of that
type of object have been defined yet.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
no\InsetSpace ~
[type]\InsetSpace ~
referred\InsetSpace ~
to\InsetSpace ~
by\InsetSpace ~
'it'
\family default
\InsetSpace ~
\newline
You've said
\family typewriter
it
\family default
to refer to the last room, item or task tag that was mentioned in the current
command, but no tags of that type of object have been mentioned.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
[type]\InsetSpace ~
tag\InsetSpace ~
[name]\InsetSpace ~
already\InsetSpace ~
defined
\family default
\InsetSpace ~
\newline
You've given two similar objects the same tag name.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
[type]\InsetSpace ~
tag\InsetSpace ~
[name]\InsetSpace ~
not\InsetSpace ~
defined
\family default
\InsetSpace ~
\newline
You've referred to a tag name that hasn't been defined anywhere in the
input.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
[type]\InsetSpace ~
tag\InsetSpace ~
[name]\InsetSpace ~
not\InsetSpace ~
yet\InsetSpace ~
defined
\family default
\InsetSpace ~
\newline
You're referring to a tag at a point where it hasn't yet been defined,
in a situation where it must be (e.g.\InsetSpace ~
the room
\family typewriter
from
\family default
clause, or a command that modifies attributes of a previously-defined object).
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
can't\InsetSpace ~
modify\InsetSpace ~
[name]\InsetSpace ~
attribute
\family default
\InsetSpace ~
\newline
You're attempting to modify an attribute of an object which can't be changed
once it's set (e.g.\InsetSpace ~
a tag name).
This is because it would create inconsistencies between objects.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
can't\InsetSpace ~
link\InsetSpace ~
[name1]\InsetSpace ~
and\InsetSpace ~
[name2]\InsetSpace ~
--\InsetSpace ~
different\InsetSpace ~
map\InsetSpace ~
sections
\family default
\InsetSpace ~
\newline
The rooms you're trying to link are on different sections of the map, and
have no spatial relation to one another.
You might have forgotten to link a previous room in the list.
Or you meant to use a
\family typewriter
join
\family default
.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
can't\InsetSpace ~
link\InsetSpace ~
[name]\InsetSpace ~
to\InsetSpace ~
itself\InsetSpace ~
without\InsetSpace ~
at\InsetSpace ~
least\InsetSpace ~
one\InsetSpace ~
direction
\family default
\InsetSpace ~
\newline
To link a room to itself, you need to specify at least one direction.
Otherwise, the link goes nowhere.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
links\InsetSpace ~
between\InsetSpace ~
[name1]\InsetSpace ~
and\InsetSpace ~
[name2]\InsetSpace ~
have\InsetSpace ~
differing\InsetSpace ~
lengths
\family default
\InsetSpace ~
\newline
You've defined more than one link or join between the given rooms, but
given them different values for the
\family typewriter
length
\family default
attribute.
This isn't allowed.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
more\InsetSpace ~
than\InsetSpace ~
one\InsetSpace ~
task\InsetSpace ~
needs\InsetSpace ~
to\InsetSpace ~
follow\InsetSpace ~
[task]\InsetSpace ~
immediately
\family default
\InsetSpace ~
\newline
You've given two or more tasks an identical
\family typewriter
follow
\family default
tag.
Only one task can
\begin_inset Quotes eld
\end_inset
follow
\begin_inset Quotes erd
\end_inset
a given task.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
[num]\InsetSpace ~
cyclic\InsetSpace ~
task\InsetSpace ~
dependencies
\family default
\InsetSpace ~
\newline
The game isn't solvable because there's one or more chains of tasks where
each must be done before the next, but the last must be done before the
first.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
error:\InsetSpace ~
variable\InsetSpace ~
[name]\InsetSpace ~
is\InsetSpace ~
not\InsetSpace ~
defined
\family default
\InsetSpace ~
\newline
A customization variable needed by an output format is not defined.
You should only see these errors if you have modified or overridden the
system initialization file.
The remedy is to define the variable somewhere.
\end_layout
\begin_layout Subsection
Warning Messages
\end_layout
\begin_layout Standard
Here's the list of warning messages.
If only warnings occur, then output is still produced.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
attribute\InsetSpace ~
[attr]\InsetSpace ~
ignored\InsetSpace ~
--\InsetSpace ~
no\InsetSpace ~
implicit\InsetSpace ~
link
\family default
\InsetSpace ~
\newline
You've given a room with no
\family typewriter
dir
\family default
clause an attribute that is associated with that link (e.g.
\family typewriter
\InsetSpace ~
oneway
\family default
).
Most likely you're putting the attribute in the wrong place---if you want,
say, a join to have one of these attributes, you must define it using the
standalone
\family typewriter
join
\family default
command instead.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
link\InsetSpace ~
from\InsetSpace ~
[name1]\InsetSpace ~
to\InsetSpace ~
[name2]\InsetSpace ~
outside\InsetSpace ~
grid
\family default
\InsetSpace ~
\newline
The destination room for a link is not in a compass direction from the
last specified position.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
rooms\InsetSpace ~
[name1]\InsetSpace ~
and\InsetSpace ~
[name2]\InsetSpace ~
overlap
\family default
\InsetSpace ~
\newline
The coordinates of the specified rooms are the same.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
room\InsetSpace ~
[name]\InsetSpace ~
crossed\InsetSpace ~
by\InsetSpace ~
link\InsetSpace ~
line\InsetSpace ~
between\InsetSpace ~
[name]\InsetSpace ~
and\InsetSpace ~
[name]
\family default
\InsetSpace ~
\newline
A link line passes through the coordinates of a room.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
room\InsetSpace ~
[name]\InsetSpace ~
has\InsetSpace ~
multiple\InsetSpace ~
[dir]\InsetSpace ~
links
\family default
\InsetSpace ~
\newline
More than one link connects to the specified room in a particular direction.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
can't\InsetSpace ~
solve\InsetSpace ~
game\InsetSpace ~
([num]\InsetSpace ~
tasks\InsetSpace ~
not\InsetSpace ~
done)
\family default
\InsetSpace ~
\newline
The game is unsolvable according to the current set of tasks.
This can be due to part of the map being inaccessible, or IFM stupidly
choosing the wrong order of doing things.
Hopefully the latter shouldn't happen very often.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
can't\InsetSpace ~
solve\InsetSpace ~
game\InsetSpace ~
([num]\InsetSpace ~
tasks\InsetSpace ~
ignored)
\family default
\InsetSpace ~
\newline
The game is unsolvable because you're explicitly ignoring tasks and/or
items, using the
\family typewriter
ignore
\family default
attribute.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
no\InsetSpace ~
matching\InsetSpace ~
style\InsetSpace ~
command
\family default
\InsetSpace ~
\newline
You've used
\family typewriter
endstyle
\family default
without a matching
\family typewriter
style
\family default
.
You probably have too many
\family typewriter
endstyle
\family default
commands.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
unexpected\InsetSpace ~
style:\InsetSpace ~
[name]\InsetSpace ~
(expected\InsetSpace ~
[name])
\family default
\InsetSpace ~
\newline
You've used
\family typewriter
endstyle
\family default
with an argument that doesn't match the argument of the corresponding
\family typewriter
style
\family default
.
You might have missed out another
\family typewriter
endstyle
\family default
somewhere, or have too many.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
style\InsetSpace ~
[name]\InsetSpace ~
referenced\InsetSpace ~
but\InsetSpace ~
not\InsetSpace ~
defined
\family default
\InsetSpace ~
\newline
An object in your input uses the specified style, but it isn't defined
anywhere and the style definition file
\family typewriter
name.ifm
\family default
doesn't exist in the search path (or if it does, it doesn't define the
required style).
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
warning:\InsetSpace ~
[syntax]\InsetSpace ~
is\InsetSpace ~
obsolete\InsetSpace ~
--\InsetSpace ~
use\InsetSpace ~
[phrase]\InsetSpace ~
instead
\family default
\InsetSpace ~
\newline
You've used an obsolete syntax.
Consult the documentation and then try the suggested alternative instead.
Note that multiple uses of the same obsolete syntax only result in a single
warning.
\end_layout
\begin_layout Standard
\newpage
\end_layout
\begin_layout Section
Other IFM Programs
\end_layout
\begin_layout Standard
There are several other programs bundled with IFM, which you might find
useful.
\end_layout
\begin_layout Subsection
\family typewriter
ifm2dev
\family default
---convert IFM maps to various other formats
\begin_inset LatexCommand \label{sec:ifm2dev}
\end_inset
\end_layout
\begin_layout Standard
\family typewriter
ifm2dev
\family default
is a front end to
\family typewriter
fig2dev
\family default
, which converts diagrams in Fig format to various other formats.
\family typewriter
ifm2dev
\family default
converts each map section and writes them to separate files.
The command format is:
\end_layout
\begin_layout LyX-Code
ifm2dev [-o template] [fig2dev-options] [-- ifm-options] file
\end_layout
\begin_layout Standard
The
\family typewriter
-o
\family default
option sets the file template for the output files.
It must contain an integer format indicator (e.g.\InsetSpace ~
\family typewriter
%d
\family default
); this is replaced with the map section number in filenames.
If not set, it defaults to
\family typewriter
prefix-%02d.suffix
\family default
, where
\family typewriter
prefix
\family default
is the file prefix of the input file (with
\family typewriter
.ifm
\family default
removed), and
\family typewriter
suffix
\family default
is the suffix appropriate for the type of output.
\end_layout
\begin_layout Standard
All
\family typewriter
fig2dev
\family default
output options are passed through without change.
You can use the
\family typewriter
-L
\family default
option of
\family typewriter
fig2dev
\family default
to set the output format.
See the
\family typewriter
fig2dev
\family default
manpage for details.
\end_layout
\begin_layout Standard
You can supply options to IFM by first giving the end-of-options indicator
(
\family typewriter
--
\family default
) and then the options.
\end_layout
\begin_layout Subsection
\family typewriter
ifm2tex
\family default
---convert IFM maps to LaTeX
\begin_inset LatexCommand \label{sec:ifm2tex}
\end_inset
\end_layout
\begin_layout Standard
\family typewriter
ifm2tex
\family default
is a program for creating a summary file in LaTeX format, suitable for
converting to PostScript and printing.
It uses
\family typewriter
ifm2dev
\family default
to create the maps.
The command format is:
\end_layout
\begin_layout LyX-Code
ifm2tex [-m] [-i] [-t] [-- ifm-options] file
\end_layout
\begin_layout Standard
The options indicate which combinations of things you want output (maps,
items or tasks).
Several files are written, whose names depend on the prefix of the input
file (i.e., minus its
\family typewriter
.ifm
\family default
suffix):
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMM
\family typewriter
prefix.tex
\family default
The main LaTeX input file, which includes all the others.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMM
\family typewriter
prefix-maps.tex
\family default
The maps, which include the EPS figures.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMM
\family typewriter
prefix-items.tex
\family default
The table of items.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMM
\family typewriter
prefix-tasks.tex
\family default
The table of tasks.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMM
\family typewriter
prefix-map-N.eps
\family default
An EPS figure for each map section.
\end_layout
\begin_layout Standard
At the moment, the program is very basic and doesn't have any options to
control anything.
But you can sort of customize things by using your own main LaTeX file
and doing your own including of the other files.
\end_layout
\begin_layout Subsection
\family typewriter
tkifm
\family default
---create maps interactively
\begin_inset LatexCommand \label{sec:tkifm}
\end_inset
\end_layout
\begin_layout Standard
\family typewriter
tkifm
\family default
is a graphical front end to IFM.
It provides a text editing window in which you can map out your game using
IFM commands, and a set of menus to view things.
The various features are as follows:
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMM
Text\InsetSpace ~
editing\InsetSpace ~
window This is the main window, where you type IFM commands.
It provides all the usual text editing command bindings that come with
the Tcl/Tk text widget, as well as syntax highlighting.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMM
File\InsetSpace ~
menu The standard set of file commands: New, Open, Save, Save-As, Export
(to PostScript or Fig), Quit.
There's also a command called Redraw, which invokes IFM on the current
file again.
Normally you don't have to use this (it's done whenever you open a new
file or save the current one), but if you change your initialization file
(see below) the changes won't be noticed unless you do a Redraw.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMM
Map\InsetSpace ~
menu For each map section in your map, a menu entry appears here.
Selecting it will draw the appropriate map in another window.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMM
Item\InsetSpace ~
menu This contains a single menu item, which displays a list of items
in another window.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMM
Task\InsetSpace ~
menu This contains two menu items:
\begin_inset Quotes eld
\end_inset
Task list (brief)
\begin_inset Quotes erd
\end_inset
, which displays a high-level walkthrough of the game in another window,
and
\begin_inset Quotes eld
\end_inset
Task list (verbose)
\begin_inset Quotes erd
\end_inset
which does the same but gives detailed information about what the game
solver is up to.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMM
Show\InsetSpace ~
menu This contains two menu items:
\begin_inset Quotes eld
\end_inset
Variables
\begin_inset Quotes erd
\end_inset
, which shows all the currently defined variables and their values, and
\begin_inset Quotes eld
\end_inset
Paths
\begin_inset Quotes erd
\end_inset
, which shows the file search path.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMM
Help\InsetSpace ~
menu This displays a small info panel about the current IFM version,
including copying restrictions.
\end_layout
\begin_layout Subsubsection
Using Your Own Editor
\end_layout
\begin_layout Standard
If you'd like to use your own editor to edit IFM files, but still view results
with
\family typewriter
tkifm
\family default
, you can.
\family typewriter
tkifm
\family default
recognizes when the file it is visiting gets modified, and rereads it if
so.
If you like, you can also disable all
\family typewriter
tkifm
\family default
file modification commands by setting the
\family typewriter
ifm(edit)
\family default
variable to zero (see below).
This is probably a good idea if using another editor, or else you might
accidentally save from
\family typewriter
tkifm
\family default
and lose all your changes.
\end_layout
\begin_layout Subsubsection
Customization
\end_layout
\begin_layout Standard
On startup,
\family typewriter
tkifm
\family default
reads an initialization file in your home directory (the one pointed at
by the
\family typewriter
HOME
\family default
environment variable).
On Unix systems it is called
\family typewriter
.tkifmrc
\family default
, and on Win32 systems it is called
\family typewriter
tkifm.ini
\family default
.
From there, using Tcl commands, you can set various things that affect
the appearance of the program.
Here's an example file showing the valid variables, their format and defaults.
\end_layout
\begin_layout LyX-Code
\size small
\begin_inset Include \verbatiminput{tkifm.txt}
preview false
\end_inset
\end_layout
\begin_layout Subsubsection
Errors and Warnings
\end_layout
\begin_layout Standard
Any errors or warnings that occur when invoking IFM will be displayed in
a dialog.
The current line of the text window will be changed to point at the error
or warning line (if appropriate).
\end_layout
\begin_layout Subsection
\family typewriter
scr2ifm
\family default
---convert transcripts to IFM map
\begin_inset LatexCommand \label{sec:scr2ifm}
\end_inset
\end_layout
\begin_layout Standard
\family typewriter
scr2ifm
\family default
reads one or more transcripts of an Interactive Fiction game and produces
a map of it in IFM format.
It works on Infocom-style transcripts---those produced by Inform- and TADS-gene
rated games (and of course Infocom games themselves).
The idea is that you play your game in a carefree manner, without worrying
about mapping anything, and after the session use
\family typewriter
scr2ifm
\family default
to get a map.
Well, that's the theory anyway.
\end_layout
\begin_layout Standard
\family typewriter
scr2ifm
\family default
offers two basic ways of mapping: you can create an initial (incomplete)
map from your first transcript and then add the rest
\begin_inset Quotes eld
\end_inset
by hand
\begin_inset Quotes erd
\end_inset
, or you can create a set of transcripts, each exploring different parts
of the game, and then merge them all into a final map.
Which you choose is up to you.
\end_layout
\begin_layout Subsubsection
Options
\end_layout
\begin_layout Standard
These are the command-line options for
\family typewriter
scr2ifm
\family default
:
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
-c\InsetSpace ~
file
\family default
Append the given file of IFM and parameter commands to the end of the map.
This allows you to fix various problems in the resulting map.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
-o\InsetSpace ~
file
\family default
Write output to the given file instead of stdout.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
-i
\family default
Indent the output nicely (according to
\emph on
my
\emph default
definition, anyway).
This makes things look better if you've added
\family typewriter
item
\family default
and
\family typewriter
task
\family default
commands.
Default is no indentation at all.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
-l
\family default
Add a comment to each IFM command indicating the file and line number of
the transcript command that generated it.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
-w
\family default
Don't print warnings.
\end_layout
\begin_layout List
\labelwidthstring 00.00.0000
\family typewriter
-h
\family default
Print a short usage message and exit.
\end_layout
\begin_layout Subsubsection
Operation
\end_layout
\begin_layout Standard
\family typewriter
scr2ifm
\family default
works by recognizing several key things in the transcript:
\end_layout
\begin_layout Itemize
The commands you type.
These are easy to spot, because they are preceded by a prompt (usually
\family typewriter
>
\family default
).
\end_layout
\begin_layout Itemize
When the current room changes.
This is not quite so easy, but still fairly simple.
When you enter a new room, a short room title is printed (for example,
\begin_inset Quotes eld
\end_inset
West of House
\begin_inset Quotes erd
\end_inset
).
The program looks for these short titles in the text that follows a command.
First, a line is checked for an invalid format---things that never appear
in a title (e.g.,
\begin_inset Quotes eld
\end_inset
?
\begin_inset Quotes erd
\end_inset
or
\begin_inset Quotes eld
\end_inset
!
\begin_inset Quotes erd
\end_inset
).
Then the word count is checked---titles are hardly ever more than 7 or
8 words long.
Finally the maximum length of an uncapitalized word is examined---this
is almost always 3 or less in titles (the length of
\begin_inset Quotes eld
\end_inset
the
\begin_inset Quotes erd
\end_inset
).
\end_layout
\begin_layout Itemize
When a previously-visited room is visited again.
This is the most difficult thing to determine, since anything might have
changed in the room since the last visit.
If there is a description, an exact description match is tried.
If that fails, a substring match is attempted.
If
\emph on
that
\emph default
fails, the first few words are examined to see if they match.
If there's no description, an exact room name match is tried.
This isn't as reliable, which is why you should always create a transcript
in
\begin_inset Quotes eld
\end_inset
verbose
\begin_inset Quotes erd
\end_inset
mode.
\end_layout
\begin_layout Itemize
Special IFM commands that are (hopefully) ignored completely by the game.
\end_layout
\begin_layout Standard
Some of these checks can be tailored to a particular transcript.
\end_layout
\begin_layout Subsubsection
Making Transcripts
\end_layout
\begin_layout Standard
For best results with
\family typewriter
scr2ifm
\family default
, you should follow these guidelines when making a transcript:
\end_layout
\begin_layout Itemize
Always use
\begin_inset Quotes eld
\end_inset
verbose
\begin_inset Quotes erd
\end_inset
mode.
If you don't, then when you revisit a room you've been in before, no descriptio
n will be printed.
In that case,
\family typewriter
scr2ifm
\family default
will have to rely on the room name to tell where it is.
If there's more than one room with that name, it'll get confused (and so
will you when you look at the map!).
\end_layout
\begin_layout Itemize
After starting the script, look around.
Otherwise your starting room may not be included on the map, since the
room description may not get printed.
\end_layout
\begin_layout Itemize
If there's a bend in a link (e.g., if you leave a room by going east, and
enter the next room from the south) make sure you do the return journey.
Otherwise,
\family typewriter
scr2ifm
\family default
won't know about the bend.
\end_layout
\begin_layout Itemize
Avoid places where different rooms have the same room description (i.e., mazes).
\family typewriter
scr2ifm
\family default
can't resolve cases like this, and will assume there's just a single room.
Note that this doesn't exclude
\emph on
all
\emph default
mazes---the
\begin_inset Quotes eld
\end_inset
twisty passages, all different
\begin_inset Quotes erd
\end_inset
maze from Colossal Cave would still work, since the descriptions are different.
\end_layout
\begin_layout Itemize
If you play the game over several sessions, and create several separate
transcripts, pay attention to the starting rooms.
If a transcript starts in a room already visited in the previous transcript,
then its rooms will be added to the same map section.
If not, a new map section will be created (and you should use the
\family typewriter
map
\family default
command to give it a name).
\end_layout
\begin_layout Standard
Some games will be more amenable to
\family typewriter
scr2ifm
\family default
than others---in general the ones with reasonable map connections, where
each connection makes sense in relation to the others.
For these games, the order in which rooms are visited will probably make
no difference to the resulting map.
But for perverse games (e.g.\InsetSpace ~
Colossal Cave, above ground) the order of visiting
makes a big difference.
In these cases, it's probably best to avoid trying to get all the connections
on the map---you'll spew forth lots of IFM warnings otherwise, and the
map will look awful.
Sometimes it's worth having a second attempt at a transcript, choosing
different directions to go in, to see if it improves things.
\end_layout
\begin_layout Standard
Another problem with mapping is that some games have these inconvenient
things called puzzles, which sometimes block you from exploring everywhere
so you can map it properly.
Come on, IF authors, let's get our priorities right!
\end_layout
\begin_layout Subsubsection
IFM Commands
\end_layout
\begin_layout Standard
While you're making your transcript, you can use a subset of IFM commands
to add extra things that
\family typewriter
scr2ifm
\family default
will recognize.
(Of course, the game almost certainly won't understand these commands,
and will print a suitable indignant reply.
But that shouldn't affect the state of things.) The commands recognized
are:
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
title\InsetSpace ~
\family default
Give the map a title.
The name must be in double-quotes.
This command can appear anywhere, and has the same effect each time.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
map\InsetSpace ~
\family default
Indicate that the current room starts a new map section with the given
name.
The name must be in double-quotes.
This is useful if it seems like the map divides into different sections
(e.g., the floors of a house).
\end_layout
\begin_deeper
\begin_layout Standard
If you use the
\family typewriter
map
\family default
command, you'll end up with two or more map sections.
The first map section is the one that contains the very first room, and
will have a default name unless you give it one using another
\family typewriter
map
\family default
command.
\end_layout
\end_deeper
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
item\InsetSpace ~
\InsetSpace ~
[attrs]
\family default
Declare an item in the current room.
The name must be in double-quotes.
If you don't give it a tag attribute, one is generated automatically by
changing all invalid tag characters in the name to underscores.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
item\InsetSpace ~
[attrs]
\family default
Add the given attributes to the last declared item, if any.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
item\InsetSpace ~
delete
\family default
Delete the last declared item, if any.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
task\InsetSpace ~
\InsetSpace ~
[attrs]
\family default
Declare a task in the current room in a similar manner to items.
The name must be in double-quotes.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
task\InsetSpace ~
[attrs]
\family default
Add the given attributes to the last declared task, if any.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
task\InsetSpace ~
delete
\family default
Delete the last declared task, if any.
\end_layout
\begin_layout Standard
Note that
\family typewriter
scr2ifm
\family default
knows almost nothing about IFM command syntax.
If there's a syntax error in a command, you'll have to manually edit the
resulting transcript (or delete the item/task and do it again).
\end_layout
\begin_layout Subsubsection
Fixing Problems
\end_layout
\begin_layout Standard
The map produced by
\family typewriter
scr2ifm
\family default
will not be perfect in a lot of cases.
When running it through IFM you might get warnings about overlapping rooms,
or crossed link lines.
These problems are usually fixed by stretching the link lines of some of
the rooms.
Some overlapping-room problems are caused by the program making a bad choice
of direction to put an up/down/in/out connection in.
Another problem might be not recognizing when a room is the same as a previousl
y-visited room, because the room description changed too much between visits.
\end_layout
\begin_layout Standard
You can fix most of these problems by creating a command file and specifying
it with the
\family typewriter
-c
\family default
option.
There are two types of entry:
\family typewriter
scr2ifm
\family default
commands and IFM commands.
In a command file, blank lines and comment lines (those starting with a
\family typewriter
#
\family default
) are ignored.
If a command isn't recognized as a
\family typewriter
scr2ifm
\family default
command, it's assumed to be an IFM command, and is passed straight into
the output verbatim.
You can use these to resolve conflicts in the generated map, by stretching
certain links or hiding them altogether.
\end_layout
\begin_layout Standard
Here's a list of the commands available:
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
is_room\InsetSpace ~
TEXT
\family default
Declare a line of text that is actually the name of a room.
Normally room names get recognized properly, but there may be some special
cases that aren't.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
not_room\InsetSpace ~
TEXT
\family default
Declare a line of text that definitely isn't the name of a room.
This is for opposite cases to the above.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
use_name\InsetSpace ~
TEXT
\family default
Use only the room name to decide whether a room has been previously visited.
This is for cases where a room description changes too much between visits
to be called the same room.
Note that this implies that there can only ever be one room with this name.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
set_option\InsetSpace ~
LETTER
\family default
This is a convenience that lets you specify
\family typewriter
scr2ifm
\family default
command-line options in the command file instead.
E.g.
\family typewriter
set_option\InsetSpace ~
i
\family default
will indent output nicely.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMMMMM
\family typewriter
set_param\InsetSpace ~
VAR
\family default
\InsetSpace ~
=\InsetSpace ~
\family typewriter
VALUE
\family default
This evaluates the given perl expression.
You can use this to set various parameters that control how the transcript
is parsed (see below).
Setting a value of
\family typewriter
undef
\family default
will remove that parameter (so that it won't be used).
\end_layout
\begin_layout Standard
Here's a list of the parameters that control how the transcript is parsed,
and their defaults.
You can use the
\family typewriter
scr2ifm
\family default
\family typewriter
set_param
\family default
command to set them in the command file.
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMM
\family typewriter
$name_remove
\family default
Matched text to remove before seeing if a line of text is a room name.
This is for getting rid of stuff like
\begin_inset Quotes eld
\end_inset
(in the dodgem car)
\begin_inset Quotes erd
\end_inset
.
Default:
\family typewriter
\backslash
s+
\backslash
(.+
\backslash
)
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMM
\family typewriter
$name_maxwords
\family default
Maximum no.
of words in a room name.
Default: 8
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMM
\family typewriter
$name_maxuncap
\family default
Maximum length of an uncapitalized word in a room name.
Default: 3
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMM
\family typewriter
$name_invalid
\family default
Regexp which, if matched, signals an invalid room name.
Default:
\family typewriter
[.!?"]
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMM
\family typewriter
$desc_minwords
\family default
Minimum no.
of matching words required to match a room description.
Default: 20
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMM
\family typewriter
$cmd_prompt
\family default
Regexp matching a command prompt.
Default:
\family typewriter
^>
\backslash
s*
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMM
\family typewriter
$cmd_look
\family default
Regexp matching a 'look' command (case-insensitive).
Default:
\family typewriter
^l(ook)?$
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMM
\family typewriter
$cmd_undo
\family default
Regexp matching an UNDO command (case-insensitive).
It's assumed that only a single level of UNDO is available.
Default:
\family typewriter
^undo$
\end_layout
\begin_layout List
\labelwidthstring MMMMMMMMMMM
\family typewriter
$cmd_teleport
\family default
Regexp matching commands that are known to cause a teleport to an arbitrary
room (case-insensitive).
Default:
\family typewriter
^(restart|restore)$
\end_layout
\begin_layout Subsubsection
Writing the Map
\end_layout
\begin_layout Standard
Output from
\family typewriter
scr2ifm
\family default
is as follows.
First, if the title of the map was specified with the
\family typewriter
title
\family default
command, it is printed.
Then, if there's more than one map section, a list of map section titles
is printed.
\end_layout
\begin_layout Standard
Next, there's a list of IFM commands derived from the transcript.
Each time a new room is seen, a room command is output for it.
Each room is given a tag name formed by the initials of each capitalized
word in its name.
To make tags unique, the second and subsequent occurrences of a tag name
have that number appended.
For example, room
\begin_inset Quotes eld
\end_inset
West of House
\begin_inset Quotes erd
\end_inset
would get tag
\family typewriter
WH
\family default
.
\end_layout
\begin_layout Standard
If a movement command was up, down, in or out, then a compass direction
is chosen for it that doesn't clash with other rooms (if possible) and
the
\family typewriter
go
\family default
attribute is used to mark its real direction.
If a movement command isn't recognized, the same is done except this time
the
\family typewriter
cmd
\family default
attribute is used to record the command instead.
\end_layout
\begin_layout Standard
If movement is seen between two already-visited rooms, a link command is
output (or a join, if the rooms appear to be on different map sections).
Link tags are built by concatenating the room tags of the linked rooms
with an underscore in between.
Link movement is dealt with in the same manner as for rooms.
\end_layout
\begin_layout Standard
If the special
\family typewriter
item
\family default
or
\family typewriter
task
\family default
commands are seen, then an item or task command is output following the
room that it appears in.
If an item or task hasn't been given a tag, it is assigned one.
The tag is made by translating all invalid tag characters in the name to
underscores, capitalizing (to avoid clashes with IFM commands) and, if
the tag clashes with a previously-defined tag, adding a numerical suffix
to make it unique.
For example,
\begin_inset Quotes eld
\end_inset
black rod
\begin_inset Quotes erd
\end_inset
might get a tag
\family typewriter
Black_rod_2
\family default
.
\end_layout
\begin_layout Standard
Finally, the IFM commands from the file indicated by the
\family typewriter
-c
\family default
option are echoed (if any).
\end_layout
\begin_layout Subsubsection
Example Session
\end_layout
\begin_layout Standard
Here's a simple example of
\family typewriter
scr2ifm
\family default
in action on Colossal Cave.
First, the transcript in file
\family typewriter
advent.scr
\family default
(with annotation):
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{advent1.scr}
preview false
\end_inset
\end_layout
\begin_layout Standard
The previous two commands are recommended after starting the transcript.
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{advent2.scr}
preview false
\end_inset
\end_layout
\begin_layout Standard
The previous four commands declare the given items to the program.
You don't have to bother with this if you don't want item locations on
your map.
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{advent3.scr}
preview false
\end_inset
\end_layout
\begin_layout Standard
Note that in this game we don't go in all possible directions---there's
no logic to the connections, and it'd just make a complete mess on the
map.
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{advent4.scr}
preview false
\end_inset
\end_layout
\begin_layout LyX-Code
\end_layout
\begin_layout Standard
That last command declared a task---again, you don't have to bother with
this if you don't want to.
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{advent5.scr}
preview false
\end_inset
\end_layout
\begin_layout Standard
Oops! Stumbled into the dark by mistake.
Without the UNDO, that would have meant 'Darkness' appeared on the map
as a room.
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{advent6.scr}
preview false
\end_inset
\end_layout
\begin_layout Standard
Goodness me! That was unexpected---we've been teleported.
The link almost certainly won't look good on the map.
We have the option of UNDOing, right now, or fixing the map later.
Let's do the latter.
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{advent7.scr}
preview false
\end_inset
\end_layout
\begin_layout Standard
Ok, now to create a map.
To do that, use this command:
\end_layout
\begin_layout LyX-Code
scr2ifm -o advent.ifm advent.scr
\end_layout
\begin_layout Standard
To check for problems, just type:
\end_layout
\begin_layout LyX-Code
ifm advent.ifm
\end_layout
\begin_layout Standard
On the first run through, there are complaints about an overlapping room,
due to a bad choice of direction for the
\begin_inset Quotes eld
\end_inset
down
\begin_inset Quotes erd
\end_inset
link from Outside Grate, and the expected problems with the link between
the Debris Room and the Building.
A command file,
\family typewriter
advent.cmd
\family default
, will fix these problems:
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{advent.cmd}
preview false
\end_inset
\end_layout
\begin_layout Standard
Now, if we invoke
\end_layout
\begin_layout LyX-Code
scr2ifm -o advent.ifm -i -c advent.cmd advent.scr
\end_layout
\begin_layout Standard
we get the following map:
\end_layout
\begin_layout LyX-Code
\begin_inset Include \verbatiminput{advent.ifm}
preview false
\end_inset
\end_layout
\begin_layout Standard
Printed, it looks like Figure\InsetSpace ~
\begin_inset LatexCommand \ref{fig:scr2ifm-map}
\end_inset
.
\begin_inset Float figure
placement htbp
wide false
sideways false
status collapsed
\begin_layout Standard
\align center
\begin_inset Graphics
filename advent.eps
lyxscale 70
scale 70
rotateOrigin center
\end_inset
\end_layout
\begin_layout Caption
Map produced by
\family typewriter
scr2ifm
\begin_inset LatexCommand \label{fig:scr2ifm-map}
\end_inset
\end_layout
\end_inset
\end_layout
\begin_layout Subsubsection
Limitations
\end_layout
\begin_layout Standard
Here's a list of things that
\family typewriter
scr2ifm
\family default
doesn't currently deal with:
\end_layout
\begin_layout Itemize
Mazes.
Different maze rooms that look identical (i.e., have identical names
\emph on
and
\emph default
descriptions) will simply appear as a single room.
\end_layout
\begin_layout Itemize
One-way links.
These aren't detected, so you'll have to add the appropriate IFM attribute
yourself (in a command file, or by fixing the map directly).
\end_layout
\begin_layout Standard
\start_of_appendix
\newpage
\begin_inset Include \include{gfdl.lyx}
preview false
\end_inset
\end_layout
\end_body
\end_document