### Navigation

- index
- next |
- previous |
- IFM v5.4 documentation »
- Mapping and solving example

# Mapping and solving example

Here’s a more detailed example of how to use IFM, using the example game Ruins to produce a full IFM map containing items and game-solving tasks.

Ruins originally existed only in snippets throughout Graham Nelson’s Inform Designer’s Manual until Roger Firth produced a playable version of it. It serves as a good demo of IFM capabilities, since it doesn’t give away any secrets from a “real” game. The source code for Ruins can be found bundled with the Inform 6 sources.

## Mapping the game

OK, let’s go. First, let’s set the title for the map, which gets printed out (for example) at the top of each PostScript output page:

    title "Ruins";

On starting the game, we see this:

    Days of searching, days of thirsty hacking through the briars of the
    forest, but at last your patience was rewarded. A discovery!

    RUINS
    An Interactive Worked Example
    Copyright (c) 1995 by Graham Nelson.
    Revisited 1998 by Roger Firth.
    Release 2 / Serial number 981117 / Inform v6.31 Library 6/11 S

    Dark Forest
    In this tiny clearing, the pine-needle carpet is broken by stone-cut steps
    leading down into the darkness. Dark olive trees crowd in on all sides, the
    air steams with warm recent rain, midges hang in the air.

    A speckled mushroom grows out of the sodden earth, on a long stalk.

Ooh, that mushroom looks interesting. Let’s map out what we have so far:

    room "Dark Forest" tag Dark_Forest;
    item "speckled mushroom" tag mushroom;

Let’s have a closer look at that mushroom:

    >GET SPECKLED MUSHROOM
    You stoop to pick the mushroom, neatly cleaving its thin stalk. As you
    straighten up, you notice what looks like a snake in the grass.

    You hear the distant drone of an aeroplane.

    >EXAMINE SNAKE
    A menacing, almost cartoon-like statuette of a pygmy spirit with an
    enormous snake around its neck.

    The plane is much louder, and seems to be flying very low. Terrified birds
    rise in screeching flocks.

    >GET STATUETTE
    Taken.

    You involuntarily crouch as the plane flies directly overhead, seemingly
    only inches above the treetops. With a loud thump, something drops heavily
    to the ground.

    >LOOK

    Dark Forest
    In this tiny clearing, the pine-needle carpet is broken by stone-cut steps
    leading down into the darkness. Dark olive trees crowd in on all sides, the
    air steams with warm recent rain, midges hang in the air.

    Your packing case rests here, ready for you to hold any important cultural
    finds you might make, for shipping back to civilisation.

    The roar dies away; calm returns to the forest.

We’ve found a statuette that was hidden until we picked the mushroom:

    item "statuette" tag statue hidden need mushroom;

And a packing crate just fell out of the sky! Looks like that was going to happen regardless, so nothing to do, map-wise. Let’s continue exploring:

    >D

    Square Chamber
    A sunken, gloomy stone chamber, ten yards across, whose floor is covered
    with fine sandy dust. A shaft of sunlight cuts in from the steps above,
    giving the chamber a diffuse light, but in the shadows low lintelled
    doorways to east and south lead into the deeper darkness of the Temple.

    Carved inscriptions crowd the walls and ceiling.

We went down to get here, and have to decide on a compass direction to represent this on the map; let’s choose south. This might clash with other rooms later, but we can always come back and change it if needed.

We can also see some exits to other rooms, and can indicate those too, for later reference:

    room "Square Chamber" tag Chamber dir s go down exit s e;
    item "carvings";

OK, let’s have a bit of a look around.

    >EXAMINE INSCRIPTIONS
    The carvings cut deep into the rocks from which the chamber is built,
    forming swirling sinuous patterns.

    >EXAMINE MUSHROOM
    The mushroom is capped with blotches, and you aren't at all sure it's not a
    toadstool.

    >EXAMINE SUNLIGHT
    The shaft of sunlight glimmers motes of dust in the air, making it seem
    almost solid.

Hmm... mushroom, sunlight. Sunlight, mushroom. Hey, let’s do it!

    >PUT MUSHROOM IN SUNLIGHT
    You drop the mushroom on the floor, in the glare of the shaft of sunlight.
    It bubbles obscenely, distends and then bursts into a hundred tiny insects
    which run for the darkness in every direction, leaving strange trails in
    the sandy floor. No trace of fungus remain.

Well, that was unexpected. Now what?

    >EXAMINE TRAILS
    The insect trails seem to resemble one particular group of carvings on the
    wall.

    >EXAMINE CARVINGS
    You stare at a group of carvings in the middle of one wall, uncannily
    resembling the insects' trail left in the sand, and feel your hand reaching
    out in that direction.

    >PRESS CARVINGS
    The carvings slide inwards, revealing a small cavity.

    >SEARCH CAVITY
    In the cavity among the carvings is a huge iron key.

    >GET IRON KEY
    Taken.

Aha! A key. I predict there’ll be at least one door in this game. But I hope we didn’t need that mushroom any more...

Recording what we just did:

    task "Put mushroom in sunlight" need mushroom lose it;
    task "Press carvings" after last;
    item "iron key" tag key hidden after last;

Let’s explore a bit more:

    >S

    Stooped Corridor
    A low, square-cut corridor, running north to south, stooping over you.
    Patches of moss emit a faint green fluorescent glow, just enough that you
    can see your surroundings.
    The passage is barred by a massive door of yellow stone.

    >EXAMINE MOSS
    The moss grows in rough clumps, surprisingly thick in places. Is that a
    hint of red hidden among all the greenery?

    >SEARCH MOSS
    Something rolls from the moss onto the ground.

    >LOOK

    Stooped Corridor
    A low, square-cut corridor, running north to south, stooping over you.
    Patches of moss emit a faint green fluorescent glow, just enough that you
    can see your surroundings.

    The passage is barred by a massive door of yellow stone.

    You can also see a blood-red ruby here.

    >GET BLOOD-RED RUBY
    Taken.

Haha, more not-very-well-hidden goodies. And look—a door! What a surprise. Let’s do some mapping:

    room "Stooped Corridor" dir s;
    item "moss";
    task "Search moss";
    item "blood-red ruby" tag ruby hidden after last;

OK, let’s use that key!

    >UNLOCK DOOR WITH KEY
    You unlock the stone door.

    >OPEN DOOR
    You open the stone door.

    >S

    Lofty Shrine
    For an underground chamber, the Shrine is remarkably high, though its upper
    half is hazy and difficult to see clearly. The craggy walls are polished
    natural rock, in which tiny flecks of quartz catch the light of the
    flickering candle.

    The massive yellow stone door is open.

    A great stone slab of a table dominates the Shrine.

    On the slab altar is a flickering candle.

    Behind the slab, a mummified priest stands waiting, barely alive at best,
    impossibly venerable.

How atmospheric. Continuing with mapping:

    task "Unlock door with key" need key;
    task "Open door" after last;

    room "Lofty Shrine" dir s after last;
    item "stone slab";
    item "mummified priest";

Let’s see what we have here:

    >EXAMINE SLAB
    It's big enough to lie on, though in the circumstances that might prove to
    be a A Really Bad Idea.

    >EXAMINE PRIEST
    He is dessicated and hangs together only by will-power. Though his first
    language is presumably local Mayan, you have the curious instinct that he
    will understand your speech.

Hmm... let’s press him for information, then:

    >ASK PRIEST ABOUT RUBY
    "That is one of my people's sacred relics."

    >ASK PRIEST ABOUT SLAB
    "The King (life! propserity! happiness!) is buried deep under this Shrine,
    where you will never go."

    >ASK PRIEST ABOUT KEY
    "That has been lost for generations. My gratitude to anyone who returns it
    will be overwhelming."

OK, er, let’s give it back:

    >PUT KEY ON SLAB
    His eyes dimly agleam with gratitude, the priest takes the key and conceals
    it among his rags. Then, lifting the candle, he carefully detaches a large
    lump of the mottled wax, and gives it to you.

    >EXAMINE WAX
    On closer examination, the lump appears to be an old honeycomb.

Looks like it might be worth something. Time for a bit of mapping:

    task "Put key on slab" need key lose it give wax;
    item "wax" tag wax hidden;

Right, let’s go back and try another direction we haven’t been yet:

    >N

    Stooped Corridor

    The massive yellow stone door is open.

    >N

    Square Chamber

    Carved inscriptions crowd the walls and ceiling.

    Strange trails swirl on the sandy floor.

    >E
    As you move into the eastern shadows, you seem to glimpse the word SENE
    scratched on the lintel, but before you can stop to inspect it more
    closely, you find yourself in...

    Darkness
    The darkness of ages presses in on you, and you feel claustrophobic.

    Somewhere, tiny claws are scuttling.

Crikey. Don’t like the sound of that.

    >E

    Darkness

    Somewhere, tiny claws are scuttling.

    The scuttling draws a little nearer, and your breathing grows load and
    hoarse.

    >S

    Darkness
    Somewhere, tiny claws are scuttling.

    The perspiration of terror runs off your brow. The creatures are almost
    here!

OK, this is bad. Think before acting. What did the word SENE mean? Hmm, maybe it’s two words...

    >SE

    Darkness

    Somewhere, tiny claws are scuttling.

    >NE
    Sensing a slight draught you move in that direction, stumbling over
    something lying on the ground in the dark. Almost inadvertently you grab it
    before gratefully emerging into the gloomy chamber.

    Square Chamber

    Carved inscriptions crowd the walls and ceiling.

    Strange trails swirl on the sandy floor.

Now that was close. But what have we grabbed?

    >I
    You are carrying:
      a silver bangle
      a lump of wax
      a blood-red ruby
      a pygmy statuette

Ooh, a silver bangle. Plus, we didn’t die!

Let’s map what we just did. We moved east from the Square Chamber into the Web of Darkness. There are essentially two of those rooms, corresponding to the two right directions to move in. Let’s give the Web rooms a `Dark` style to show they’re dark (we can define what `Dark` means, style-wise, later):

    room "Web of Darkness" style Dark dir e from Chamber oneway;
    item "scuttling claws";

    room "Web of Darkness" style Dark dir se oneway;
    item "scuttling claws";

The act of going northeast gave us a bangle (we tripped over it and picked it up). There are two ways of doing this: with an explicit movement task that puts you back in the Square Chamber, or a “dummy” task that hands you the bangle in this room without you doing anything (using `cmd none`). Let’s use the first method:

    item "silver bangle" hidden tag bangle;
    task "Stumble over bangle" give bangle cmd "NE" goto Chamber;

This second room is a one-way trip back to the Square Chamber. As it stands, that won’t be apparent on the map. Let’s add the connection in the most direct way:

    link last to Chamber dir ne n w 2 oneway;

Well, there doesn’t seem to be anywhere else to go. Let’s get all this stuff stashed!

    >U

    Dark Forest

    Your packing case rests here, ready for you to hold any important cultural
    finds you might make, for shipping back to civilisation.

    >PUT STATUETTE IN CASE
    Safely packed away.

    [Your score has just gone up by ten points.]

    >PUT BANGLE IN CASE
    Safely packed away.
    [Your score has just gone up by twenty points.]

    >PUT RUBY IN CASE
    Safely packed away.

    [Your score has just gone up by thirty points.]

    >PUT WAX IN CASE
    Safely packed away.

    The case is full, and you're feeling really homesick. Now, how to get out
    of here?

    A deep throbbing noise can be heard.

    [Your score has just gone up by forty points.]

OK, we’ve stashed all the loot we found. But what’s that noise?

    >WAIT
    Time passes.

    A helicopter appears, hovering overhead.

    >WAIT
    Time passes.

    The helicopter lowers a rope; you tie it around the packing case, which is
    hauled up into the air, then a rope ladder comes dangling down. With one
    last look around the clearing, you climb the ladder into the waiting craft.
    Back to civilisation, and a decent pint of Brakspear's!

        *** You have won ***

    In that game you scored 100 out of a possible 100, in 44 turns, earning you
    the rank of Master Archaeologist.

Huzzah! We found all the “cultural finds” and just need to get them to the museum. [1]

Let’s add some tasks that record storing all the treasure. This happens in the starting room, so we’ll just go back and put them just after the declaration for that room. We could just have a single task that requires all the treasure together and gets the full 100 points, but let’s spell out the points for each one:

    task "Put statuette in case" tag pack_statue need statue lose it score 10;
    task "Put bangle in case" tag pack_bangle need bangle lose it score 20;
    task "Put ruby in case" tag pack_ruby need ruby lose it score 30;
    task "Put wax in case" tag pack_wax need wax lose it score 40;

After the treasure is stashed, we just waited for the helicopter and won the game:

    task "Wait for helicopter" after pack_statue pack_bangle pack_ruby pack_wax cmd "WAIT" 2 finish;

The only thing remaining to do, map-wise, is to define the display style we’ve used for the dark rooms. Let’s just set the room background colour to be darker. Note that we could also define the `Dark` style by putting it in a file called `Dark.ifm`, and then putting that file in a directory which is searched by IFM. That way, many maps could use the same style definition. Here’s the definition:

    room_colour = "gray70" in style Dark;

Putting all these IFM snippets together (and indenting in my preferred style) the completed map looks like this:

    # IFM map of 'Ruins'

    title "Ruins";

    room "Dark Forest"                      tag Dark_Forest;
      item "speckled mushroom"              tag mushroom;
      item "statuette"                      tag statue hidden need mushroom;

      task "Put statuette in case"          tag pack_statue need statue lose it score 10;
      task "Put bangle in case"             tag pack_bangle need bangle lose it score 20;
      task "Put ruby in case"               tag pack_ruby need ruby lose it score 30;
      task "Put wax in case"                tag pack_wax need wax lose it score 40;

      task "Wait for helicopter"            after pack_statue pack_bangle pack_ruby pack_wax
                                            cmd "WAIT" 2 finish;

    room "Square Chamber"                   tag Chamber dir s go down exit s e;
      item "carvings";

      task "Put mushroom in sunlight"       need mushroom lose it;
      task "Press carvings"                 after last;

      item "iron key"                       tag key hidden after last;

    room "Stooped Corridor"                 dir s;
      item "moss";

      task "Search moss";
      item "blood-red ruby"                 tag ruby hidden after last;

      task "Unlock door with key"           need key;
      task "Open door"                      after last tag open_door;

    room "Lofty Shrine"                     dir s after open_door;
      item "stone slab";
      item "mummified priest";

      task "Put key on slab"                need key lose it give wax;
      item "wax"                            tag wax hidden;

    room "Web of Darkness"                  style Dark dir e from Chamber oneway;
      item "scuttling claws";

    room "Web of Darkness"                  style Dark dir se oneway;
      item "scuttling claws";
      item "silver bangle"                  hidden tag bangle;

      task "Stumble over bangle"            give bangle cmd "NE" goto Chamber;
      link last to Chamber                  dir ne n w 2 oneway;

    room_colour = "gray70" in style Dark;

## Drawing the map

At any point during the mapping of the game, we could run IFM and get a map of where we’ve been (and where to explore next, since we marked room exits with `exit`). We can do that, for example, like this:

    ifm -m -o ruins.ps ruins.ifm

and using our favourite PostScript viewer to view the map. Here’s what the completed Ruins map looks like:

## Listing items

We can see a complete item list using:

    ifm -i ruins.ifm

Here’s what gets output with the completed Ruins map:

    Item list for Ruins

    blood-red ruby:
       hidden in Stooped Corridor
       obtained after:
          Search moss (Stooped Corridor)
       needed for:
          Put ruby in case (Dark Forest)

    carvings:
       seen in Square Chamber

    iron key:
       hidden in Square Chamber
       obtained after:
          Press carvings (Square Chamber)
       needed for:
          Unlock door with key (Stooped Corridor)
          Put key on slab (Lofty Shrine)

    moss:
       seen in Stooped Corridor

    mummified priest:
       seen in Lofty Shrine

    scuttling claws:
       seen in Web of Darkness

    scuttling claws:
       seen in Web of Darkness

    silver bangle:
       hidden in Web of Darkness
       obtained after:
          Stumble over bangle (Web of Darkness)
       needed for:
          Put bangle in case (Dark Forest)

    speckled mushroom:
       seen in Dark Forest
       needed for:
          Get statuette (Dark Forest)
          Put mushroom in sunlight (Square Chamber)

    statuette:
       hidden in Dark Forest
       obtained after:
          Get speckled mushroom (Dark Forest)
       needed for:
          Put statuette in case (Dark Forest)

    stone slab:
       seen in Lofty Shrine

    wax:
       hidden in Lofty Shrine
       obtained after:
          Put key on slab (Lofty Shrine)
       needed for:
          Put wax in case (Dark Forest)

## Generating a solution

We can get a basic walkthrough of the game using:

    ifm -t ruins.ifm

and it looks like this:

    Task list for Ruins

    Dark Forest:
       Get speckled mushroom
       Get statuette
       Put statuette in case
          score: 10

    Move to Square Chamber (D)

    Square Chamber:
       Put mushroom in sunlight
       Press carvings
       Get iron key

    Move to Stooped Corridor (S)

    Stooped Corridor:
       Search moss
       Unlock door with key
       Open door
       Get blood-red ruby

    Move to Lofty Shrine (S)

    Lofty Shrine:
       Put key on slab
          note: Gives wax

    Move to Stooped Corridor (N)
    Move to Square Chamber (N)
    Move to Dark Forest (U)

    Dark Forest:
       Put ruby in case
          score: 30
       Put wax in case
          score: 40

    Move to Square Chamber (D)
    Move to Web of Darkness (E)
    Move to Web of Darkness (SE)

    Web of Darkness:
       Stumble over bangle
          cmd: NE
          note: Gives silver bangle
          note: Moves you to Square Chamber

    Move to Dark Forest (U)

    Dark Forest:
       Put bangle in case
          score: 20
       Wait for helicopter
          cmd: WAIT
          cmd: WAIT
          note: Finishes the game

    Total distance travelled: 10

    Total score: 100

As you can see, IFM’s solution is slightly different from the way we played it: it stashes the statue straight away. In the actual game, doing that this early wouldn’t work—the packing case hasn’t been dropped yet. Unless we’re trying to make a recording that will play back in Frotz or similar, this doesn’t really matter. If we did want to, we’d have to fix this and create a recording file using:

    ifm -t -f rec ruins.ifm

This produces:

    GET SPECKLED MUSHROOM
    GET STATUETTE
    PUT STATUETTE IN CASE
    D
    PUT MUSHROOM IN SUNLIGHT
    PRESS CARVINGS
    GET IRON KEY
    S
    SEARCH MOSS
    UNLOCK DOOR WITH KEY
    OPEN DOOR
    GET BLOOD-RED RUBY
    S
    PUT KEY ON SLAB
    N
    N
    U
    PUT RUBY IN CASE
    PUT WAX IN CASE
    D
    E
    SE
    NE
    U
    PUT BANGLE IN CASE
    WAIT
    WAIT

Another way to view the solution is using a task dependency graph. This uses IFM’s dot output format, like this:

    ifm -t -o ruins.dot -f dot ruins.ifm
    dot -Tps -o ruins-graph.ps ruins.dot

Here’s what Ruins looks like:

Yet another way to show this is by grouping tasks together according to the rooms they occur in, by setting the `task_graph_rooms` variable:

    ifm -t -o ruins.dot -f dot -s task_graph_rooms=true ruins.ifm
    dot -Tps -o ruins-graph.ps ruins.dot

This is what you get:

## Tweaking the solution

If we want to wait for the packing case to appear before trying to put the statue in it, we could do it like this:

    task "Wait for packing case" in Dark_Forest need statue cmd "WAIT" 2;

Also, The solution as it stands is not as short as it could be: the game solver takes a trip back up to the packing case to dump two treasures and only then goes to get the bangle. This is because the stashing-treasure tasks are marginally closer at that point.

What we’d like is for the solver to grab all the underground treasure before returning to the surface. This can be done by extending the length (i.e., movement cost) of the implicit link between above-ground and below-ground:

    link Chamber length 10;

After adding this line, the solver behaves the way we want.

Footnotes

[1] | Yeah, right. You can if you want. I’m off to Ebay.

### Navigation

- index
- next |
- previous |
- IFM v5.4 documentation »
- Mapping and solving example