Inform Tutorial Part II by Doug Atkinson (datkinson@lisp.purdy.wayne.edu) This tutorial is intended as a followup to Gareth Rees', and if you haven't read that first, you should (you can find it at http://www.cl.cam.ac.uk/users/gdr11/inform/tutorial.html). I'm writing from a different perspective, however. Gareth has experience with Inform, enough to write a full game, while I'm just a beginner. I'm going to concentrate more on the difficulties I encountered in writing this, and on the process of adapting from the book. (Please bear in mind that this is as much a learning process for me as for the reader. You won't find so much in the way of general advice, but I do point out mistakes I made that a more experienced coder wouldn't.) Gareth took us halfway through the first chapter of _Through the Looking- Glass_, with Alice going through the Looking-glass. I'm going to extend it to the end of Chapter 2, when Alice is ready to take her first move as a pawn. The puzzle I have in mind is this: Alice must pick up the White King from the grating and put him on the table, where he will drop a pencil. Alice must take the pencil to the Red Queen, who's outside in the garden, and give it to her; the Queen will write a set of instructions, which enable her to enter the chess game, but she has to hold them to the mirror to read them. (This puzzle is a little thin by itself; it would work better in a larger game, where Alice would have other tasks in the Looking-Glass House, but this is only an example.) 1. The Looking-Glass House If Alice is going to pass through the mirror, we need to give her a place to go. Here are the basics: Object Gniward_Room "Looking-Glass Room" with description "This is like your drawing-room, but the parts \ that can't be seen from the old room are \ curiously different. The pictures on the wall \ seem to wink at you, and the view out the window \ is one of gardens in summer-time. There is no \ fire in the hearth, but a pile of cinders with \ chess-pieces crawling through the grate.", has light; 2. Entering the Looking-Glass House The previous section of the game ended like this: (as a "before" routine on the mirror) Enter: ! Really, move Alice to the looking-glass house. deadflag = 2; "Your hand goes right through the silvery mist, and in \ another moment the rest of you follows, and you are \ through the glass..."; ]; Obviously, we have to change this so Alice moves to the Looking-Glass Room instead of winning the game. We also have to stop the daemons for the kittens, or the rest of the game will be filled with messages like "The black kitten chases its tail," even when the kitten is nowhere nearby. Enter: print "Your hand goes right through the silvery mist, and in \ another moment the rest of you follows, and you are \ through the glass...^"; StopDaemon(white_kitten); StopDaemon(black_kitten); PlayerTo(Gniward_Room); rtrue; ], Note that the PlayerTo must go last, and the rtrue must be included, or it won't work right. If the PlayerTo goes before any of the elements, they won't run. If the rtrue is left out, you'll get the standard Enter message (either "You can't enter that," or, if you make the mirror Enterable, "You enter the mirror." If the "print" is left out, the message will print and send "rtrue" right away, so Alice won't go anywhere. The mirror is one of the items that we want in both rooms, so we add this to the end of the mirror code: found_in Drawing_Room Gniward_Room and remove the specification that it's found in the Drawing Room from the beginning of the description. The mantel is also found in both places, though it's only in the Looking- Glass Room as scenery. (Alice can't enter it, because we don't want her to go through the mirror again.) If we use the above found_in statement, anything placed on the mantel will also be in the Looking-Glass Room (since it's the same mantel in both places). This is appropriate, given the way the mirror works (anything on the mantel should reflect in the mirror, and therefore should be in the Looking-Glass Room), but it may not be desirable for Alice to have some of the Drawing Room objects in the Looking-glass world. (Specifically, having the red queen seems inappropriate, since we have the animate Queen later. The worsted and chess board shouldn't be a problem.) 3. The grate The grate exists as a container for the living chess-pieces, and nothing else, really. Since it's in the room description, it should be made scenery so it's not mentioned explicitly again. Object grate "grate" Gniward_Room with description "Your housekeeper would never tolerate such a \ mess in your grate. The cinders are heaped \ all about, and pose an obstacle for the chess-\ pieces walking about arm in arm.", name "hearth" "grate" "fireplace" "fire" "place", before [; PutOn: "That would only get it dirty."; Enter: "You would get ashes all over your dress."; ], has supporter scenery; The "before" routines are included to keep Alice from messing around with the grate too much, without actually coming right out and saying "that's not important." The White King is among the chess-pieces in the grate, but we don't want to mention him explicitly. We'll modify the description when we code him. If the grate isn't made a supporter, the things found there simply won't be in the room. 4. The chess-pieces In the book, Alice looks into the grate and sees a bunch of chess-pieces walking around. Lily, a White Pawn who's on the table behind her, falls over, and the White Queen tries to get to her. Alice moves the White monarchs to the table. We don't need most of the chess-pieces at this point, and the material with Lily and the White Queen doesn't advance the game any. The White King will be coded separately, and the Red Queen won't be present because she's in the garden, but we need a general routine to handle the others. Fortunately, the first section of the game had a routine to handle this; we'll just snip it out and alter it a little. Object chessmen "chess pieces" grate with parse_name [ w colour n; w = NextWord(); if (w == 'white' or 'red') { n ++; colour = w; w = NextWord(); } if (w == 'pawn' or 'rook' or 'castle' || w == 'knight' or 'horse' or 'bishop' || (w == 'king' && (colour == 'red')) || (w == 'queen' && (colour == 'white'))) return n + 1; return 0; ], The name "chessmen," though inaccurate, is used to give them a different name than the (non-existent) pieces in the first room. description "Knights and bishops, castles and pawns, walking \ arm in arm through the grating.", I personally dislike the term "castle" for rooks, but that's the term Caroll used, and I'm trying to use his phrasing where possible. Unlike the first room, the pieces are actually present, but we don't want Alice to get them, so we add: before [; Take: "They seem content as they are."; ], has scenery; (Incidentally, in the first room it was possible to carry all the available objects, except the kittens, through the mirror by putting them on the mantel, climbing onto the mantel, picking them up again, and going through. We may not want this, as noted above; later we can make Alice drop things when she passes through, if necessary.) 5. The White King If you recall the puzzle outlined at the beginning, we wanted the King to drop a pencil if placed on the table. We'll just sketch out the basics of his code right now, and fill him out later. Object white_king "White King" grate with description "A miniature monarch in white, about as long as \ your hand.", name "white" "king", has concealed; We conceal him so he won't appear in the initial description, assuming that the player will look for him among the chessmen. However, we need to mention that he's there, so add this to the grate code: after [; Examine: if (white_king in grate) print "The White King is crawling very slowly from bar to bar." ], We need to clue in the player about where the King is going: after [; Examine: if (white_king in grate) print "He seems to be crawling towards the table, but makes \ little progress."; This is the first "after" for the King. We need two more for the puzzle: Take: "You take up the king between thumb and forefinger. \ He seems startled, and looks towards the table \ yearningly."; PutOn: if (second==table) move pencil to table; "He looks about to see who moved him to the table, \ but seems unable to see you. He collects his \ thoughts for a moment, then pulls a stub of pencil \ from his robes and writes a memorandum to himself. \ He places the memorandum beneath his robes, dropping \ the pencil as he does so."; We now have all we need for the puzzle to work, once we code the table and the pencil, but the King is pretty lifeless. Not being animate, he's treated as an ordinary object, not a living being, and the library responses will reflect this. Later we'll make him more interesting, but this will do to see if the puzzle works or not. 6. The table The table is mentioned briefly in Carroll's descriptions; it's where Alice puts the King and Queen, and finds the book of poetry (which we'll get to soon). There wasn't a table in the Drawing Room, but part of the premise is that only the areas seen through the mirror are identical, so we have free reign in the areas in front of the hearth. The table's here instead of the chair. It's mostly scenery, but we can give it one important function; Alice can climb on it to reflect things in the mirror, but she can't reach the mantel from there. Add the table to the list in ReflectSub, but not the list of items from which she can enter the mantel. We have to put things on it, of course, so it's enterable and a supporter. Object table "table" Gniward_Room with description "This mahogany table isn't in your old room. It \ is long and low, and sits before the hearth.", name "table" "low" "mahogany", has enterable supporter; To save the worry of the table's position in the room, we make it "static" and add the following: before [; Push, Pull: "But if you did that, someone in your old room \ would be able to see it, and there isn't a \ table like this in your old room to reflect. \ It makes you quite confused to consider what \ might happen then."; Take: "It's too heavy and awkward."; ], The following "before" message is just a little more situation-specific than the standard message, but works just as well. Climb, Enter: move player to table; "You clamber onto the table."; 7. The pencil A very simple piece of code by itself: Object pencil "pencil" with description "A tiny nubbin of a pencil.", name "pencil" "nubbin"; We have to deal with the player attempting to write on things with it, however. "Write" has to be recognized, since there's a writing implement, but we don't actually have to let the player write anything. Add this to the beginning of the game: Verb "write" * noun -> Write * "on" noun -> Write * "on" noun "with" noun -> Write; And this to the verb subroutines: [ WriteSub; "You've spent the last week in lessons, and have written quite \ enough compositions for a while, thank you."; ]; Writing a general "you can't do that" message is much easier than either a) letting Alice scribble graffiti over everything, and having to keep the writing in place, or b) having different reasons why Alice can't write on different objects. (The table isn't a good writing surface, but she could write on the pages of the book, and these situations would require different messages.) If we want Alice to write something later, we can add exceptions using "before." (This is a basic problem in modelling the real world; even in the limited sphere of actions in IF, the interaction of every object with every object must be considered. The classic example: when the implementors of ZORK allowed the players to take the axe for the first time, one of the players responded, "Great! I'm going up to the forest to chop down some trees!") 8. The book In the novel, Alice finds a book on the table that contains the poem "Jabberwocky." We don't need to include the poem for its own sake, but we can include it as an important clue. Alice isn't reversed by passing through the mirror, and this will cause her trouble later (including the need to read the Red Queen's note in the mirror). Putting in the book, and making it only legible in the mirror, will give that clue. I wanted to change the way reading objects works somewhat. Ordinarily, the grammar file treats "read" as a synonym of "Examine," with the result that one can type "READ GRATE" and get the description. This works for items like signs, where there's not much difference between the actions of looking at it and reading it, but it doesn't allow the player to look at a written object (to find out what it looks like, say) without actually reading it. To do this, we need to modify the verbs. Extend "read" replace * noun -> Read * noun "in" noun" -> Reflect; !To allow Alice to type "read book in !mirror" Using "replace" puts ReadSub in place of the old routine. Unless a reference book appears in the game, there's no need for the old version (which also refers to the consultation routine, when the player types "read about grues in encyclopedia" or the like). If we did want to keep the old "read" routine, we could replace "replace" with "first." Having set up the verb, we need to define what it does: [ ReadSub; "There's nothing written on that."; ]; Note that, having done this, we have to be aware of the results this has for the rest of the game, because everything with writing on it will have to have its writing defined separately. If implementing, say, a sign that says "TO THE HOUSE OF TWEEDLEDEE," we would need to be sure that a Read routine was defined, or the player reading the sign would be told that there was nothing written on it. (A situation like this occurs later in the tutorial.) The book reads backwards when read normally: Object book "book" table with description "It seems to be a book of poetry, but there's no \ title or author.", before [; Read: "It's written in some language you don't know. The first \ verse looks like this:^^ \ .YKCOWREBBAJ^^ \ sevot yhtils eht dna ,gillirb sawT'^ \ ;ebaw eht ni elbmig dna eryg diD^ \ ,sevogorob eht erew ysmim llA^ \ .ebargtuo shtar emom eth dnA"; name "book" "poetry"; but reads normally in the mirror: (this is a "before" routine) Reflect: "The book is reversed in the mirror; you can read it \ now! The first verse of the poem reads:^^ \ JABBERWOCKY.^^ \ 'Twas brilling, and the slithy toves^ \ Did gyre and gimble in the wabe^ \ All mimsy were the borogoves,^ \ And the mome raths outgrabe.^^\ It goes on for a while, but you can't seem \ to make it out at all."; ], The spaces between the linefeed characters (^) and continued-on-next-line characters (\) are necessary to indent the lines properly. Spaces to the left of the words don't work; I just put them there for my own benefit. (An alternative, and probably better, way to space it would be to move the ^'s to the beginning of the line, but the results are the same either way.) While it would be possible to include the whole poem, it would be a waste of space; anyone who wants to read it can just read the book, and the first stanza is sufficient to convey the hint. 9. Leaving the room Unlike Gareth's tutorial, this part of the game includes multiple rooms. Alice needs to be able to reach the garden, so add this to the Gniward_Room code: ^^There \ is a staircase leading south to the outdoors; \ after spending all day indoors, an afternoon in \ in the gardens seems inviting.", s_to Back_door, d_to Back_door and this code for the Back_door: Object Back_door "Back Door" with description "You can see a bit of the gardens out the \ doorway. You'd get a better view from the top \ of the hill to your east.", e_to Flowers, n_to Gniward_Room, u_to Gniward_Room has light; The reason for the Back Door is to provide a stopping-place before Alice attempts to negotiate the gardens. In the novel she's unable to, at first, because she hasn't caught on to the Looking-glass principle of motion (one heads away from one's target). I'm choosing a slightly different principle here; east and west are reversed, so Alice can move south just fine but can't reach the hill to her east. (We could use the code from the Inform Designer's manual to reverse east and west, but the areas is too small for that to be worth the effort. Later sections of the game may do this.) Just to provide atmosphere, we should handle the transition between the two rooms, because they're not directly connected. Drawing on Carroll's description of the trip, we add this to the Back_door: after [; Go: if (noun == s_obj || noun == d_obj) print "You don't have to run down the stairs; you just keep your \ fingertips on the hand-rail, and float down the stairs and \ through the hall. You manage to catch yourself on the \ door-post of the ^"; ], This will appear every time the player enters the room from the Looking-Glass Room, but not from the garden. We don't want Alice to be able to carry the White King everywhere she goes. We'll add more fixes when we expand his code, but for now, this code should be added to the Looking-Glass Room: before [; Go: if (noun == s_obj || noun == d_obj && white_king in player) "The White King struggles in your hands as you approach the \ doorway. You can't bear to see the poor thing so unhappy."; ], This prevents Alice from leaving while carrying him. 10. The garden The novel includes a section where Alice speaks with some talking flowers and learns how to travel, which is how she reaches the Red Queen. For game purposes we'll just turn the flowers into scenery: Object Flowers "Flower Garden" with description "A tiger-lily towers over this flower-bed, which \ is filled with roses and daisies.", has light; We need an explanation of why Alice didn't make it to the hill, so we add: after [; Go: if (noun==e_obj) print "It's the most frustrating thing! You start out for the \ hill-top, but the path seems to twist in and out like a \ corkscrew, and you keep returning to the house. Finally, \ you find yourself in a...^"; ], We need to convey to the player that normal travel won't work, but we also have to let her return to the house. w_to Back_door, cant_go "You start to head in that direction, but the \ path gives itself a little shake and you find \ yourself back where you started.", This should make it clear to the player that Alice can't travel normally, and has to find another way out of here. 11. The Red Queen First, the basics: Nearby redqueen "Red Queen" with description "Quite unlike the chess-piece you handled \ earlier, Her Red Majesty stands a head taller \ than you, haughty and imperious. She stares at the \ horizon, and pays you little attention.", name "red" "queen", has animate female; Having her here is a good reason for not allowing Alice to bring objects through the mirror, if for no other reason than not forcing the game to decide which queen is being referred to. The Queen is a rather haughty character, and she won't pay attention to Alice at first. We'll need some way for Alice to get her attention. She should be set up to answer questions; but, since we want her to have a reason to give Alice the note, we don't want her to be too chatty. For the Queen's mood, we'll make her unwilling to talk unless Alice shows her a proper sign of respect (she is Alice's elder, after all). We'll make Alice curtsey to her. This will require a simple new verb: Verb "curtsy" "curtsey" * -> Curtsey * noun -> Curtsey * "at" noun -> Curtsey * "to" noun -> Curtsey; [ CurtseySub; "You bob up and down in place."; ]; (I believe this is a British/American spelling difference, though it may be a Victorianism. My dictionary spells it without the "e", but Carroll spelled it with, and I'm following his usage. Either will work fine.) To represent the mood, we'll create the following property: Property pleased; !0=not pleased, 1=pleased (Since this is currently a two-valued property, we could use "general" to represent it; however, making it a property allows us to expand it later if we want. We may wish to make someone partially pleased at some point.) Let's add this material to the Queen's code: pleased 0, before [; Curtsey: print "The Queen smiles. She seems pleased at your \ display of respect. ^^ ~So, you'd like to be a Queen, \ would you?~ (In fact, the thought hadn't crossed your \ mind, but it does hold a certain appeal.) ~I'd like to \ advise you, but--~ ^^You wait for her to complete her \ sentence, but she doesn't."; redqueen.pleased = 1; rtrue; ], life [; Ask: if (redqueen.pleased==0) "The Queen seems displeased. Evidently you haven't \ shown her the proper courtesy."; The Queen begins displeased (pleased 0), but curtseying to her makes her pleased, and she offers Alice some information, but won't fill her in all the way. She won't tell Alice anything if she's not pleased. (Incidentally, the choice of the word "courtesy" is a clue--"curtsey" derives from it. I don't want to make this a "guess the verb" puzzle, but I think curtseying is well- enough known as a gesture of respect that the above clues are sufficient. This is the sort of detail the implementor must be willing to change after playtesting.) To fill her out the rest of the way, and to finish off the puzzle, give her this code: if (second == 'pencil' && pencil notin player) "~Perhaps one of the other royalty can help you. I'm sure \ I don't know anything about it.~"; "~I make it a policy never to speak of such things. I \ find those of your age tend to forget things that aren't \ written down. Why, you'd need a book to keep track of \ everything I know, and anything that's not on a note would \ leave your head at once.~ You feel somewhat offended; after \ all, you are seven and a half years old."; (The last message will be the default.) Give: if (redqueen.pleased == 1 && noun == pencil) print "~Aha! Just the thing!~ The Queen takes the pencil and \ rapidly scribbles out a note; curiously, the pencil seems \ to get longer as she writes.^^When she finishes, she hands \ you the note. Without a word or a good-bye, she vanishes, \ though whether into thin air or just by running you ca'n't \ make out."; move note to player; move pencil to redqueen; rtrue; If Alice asks about anything but the pencil, she'll be told that she needs to write it; this is the implied continuation of the Queen's "but--". If she gives the Queen the pencil, she'll get the note. (The clues in this section may be a bit thin; I'll expand them later, but these are the bare bones necessary for the puzzle to work.) 12. The note Having mentioned the note above, we need to create it. Object note "note" with description "It's all written in some language you can't \ understand. If your father were here, he could \ translate it, but he's not, and you are on your own.", name "note" "paper", If you remember the puzzle, we want the note to be only readable in the mirror. (We *could* write it reversed, but that's too easy for the player and too much of a pain, and we're assuming Alice can't read it on her own. before [; Reflect: "You hold the note up to the mirror; it's now readable. \ It says: ^\ ^ 1. To move about in the Looking-glass world, \ move away from your destination. ^\ ^ 2. Remember that a Pawn may move two squares in \ its first move. ^\ ^ 3. When you reach the Eighth Square, you shall \ become a Queen. ^\ ^ 4. Speak in French when you ca'n't think of the \ English for a thing--turn out your toes when you walk\ --and always remember who you are."; ]; Since reading the note is equivalent to looking at it in this case, we need to give a Read routine. This is easy: Read: <>; After reading these directions, Alice should be able to travel normally in the Looking-glass world--but that's outside the scope of this section. (The rest fills in the player on chess, and serves as a reference to the original book, of course.) (By the way: Kudos to anyone who gets the significance of the reference to Alice's father.) 13. Filling in the cracks a. The White King To bring him to life, add "animate" to his attributes, and he'll be treated as a living thing instead of an object. In the book, Alice doesn't interact much with him, and he can't actually see or hear her. He's not going to be a very exciting character, for this reason, but we can at least cover that behavior: life [; Ask,Answer,Order,Give,Show: "The White King doesn't seem to be able \ to see or hear you."; Kiss: "The King looks around in astonishment at being kissed by a \ giant pair of invisible lips."; ThrowAt, Attack: "Attacking an adult is rude. Attacking royalty \ is treason."; ], After we move him to the table, he doesn't do anything. We could give him a lot of colorful behavior (in much the same way Gareth did with the kittens), or we could give him a reason for being inactive. Since we already have examples of coding random behavior from the first tutorial, and since we don't want Alice to bother with him once she has the pencil, let's do the latter. Change the PutOn routine to: PutOn: if (second==table) { print "He looks about to see who moved him to the table, \ but seems unable to see you. After collecting his \ thoughts for a moment, he pulls a stub of pencil \ from his robes and writes a memorandum to himself. \ He places the memorandum beneath his robes, dropping \ the pencil as he does so. A feeling of exhaustion seems \ to overcome him, for he lies down and immediately falls \ asleep."; move pencil to table; move white_king to table; rtrue; } We also don't want Alice to put him on just any object (the mantel or the grate), so add: "He doesn't seem to want to go there."; After putting him on the table, we want him to stay there: Take: if (white_king in table) "Don't disturb him, he's asleep."; and to mention it in the Examine "after" routine: if (white_king in table) print "He's on his back with his crown pulled over his face, \ snoring gently."; Finally, we have to handle Alice dropping the King. We've already railroaded her into putting him on the table, so putting him on the floor seems out of place; also, since he's "concealed," he wouldn't show up in the room description if dropped, making it seem that he's vanished completely. The simplest thing to do is to stop her from dropping him at all, so make this a "before": Drop: "What, on the floor? That would be rude!"; b. Looking-glass Room The drawing room had a window, so this one should too. We can steal the code from the old window and change it as necessary. Object wodniw "window" Gniward_Room has scenery with name "window" "pane", description "Outside it's warm and sunny, and you're eager to \ explore the gardens.", before [; Open: "Unfortunately, it's stuck"; Search: <>; ]; We mention the pictures in the room description, so we really ought to code them as well: Object pictures "pictures" Gniward_Room with description "When you look away from them, the eyes seem to move; \ but when you turn directly at them, they're still. \ No matter how quick you are, you ca'n't seem to catch \ them in motion.", name "pictures" "picture" "frame" "photo" "photos" "photographs", has scenery; Also, the message about floating down the stairs could get monotonous. Change the Back Door "after" routine to this: after [; Go: if ((noun == s_obj || noun == d_obj) && Back_door hasnt visited) print "You don't have to run down the stairs; you just keep your \ fingertips on the hand-rail, and float down the stairs and \ through the hall. You manage to catch yourself on the \ door-post of the ^"; so it will only print the first time the room's entered. (However, the message about the twisting paths in the garden will be kept, because it's more important. The above message is mostly for atmosphere; the message in the garden explains why Alice can't travel at will.) c. The Red Queen Right now the Queen is awfully limited. I'm not going to try making her a full-fledged character, because that doesn't seem necessary, but she should have more responses to questions than she does right now (and give better hints). Add these responses to her Ask routine: if (second == 'pencil && pencil in player) "~It's right there in your hand, child.~"; if (second == 'pencil' && pencil in Flowers) "~It's at your feet. Such an untidy child!~"; if (second == 'king') "~Meek and timid.~"; if (second == 'note') "~Do you see a writing implement anywhere about me?~ Now that \ she mentions it, you don't."; if (second == 'book') "~I haven't the means to write one, and I've already \ read six before dinner.~"; The first was added to account for Alice asking about the pencil while she has it (which is a fairly likely occurence); the second allows the Queen to recognize that the pencil is under her nose, even if Alice doesn't have it. Adding this, we also need to change if (second == 'pencil' && pencil notin player) to if (second == 'pencil' && pencil notin player && pencil notin Flowers) The third adds a bit of flavor. The fourth and fifth account for her comments in the default reply about notes and books. (Her comment about dinner refers to the practice of eating dinner at noon-time, by the way.) They also give a hint about needing the pencil. Incidentally, this is the proper grammar of Ask routines. (This is one aspect of Inform that Gareth didn't cover in the first tutorial, since his only NPCs were mute.) Ask is a good way to round out a character--the more they know about their world, the more they're a part of it. I'm not doing it here, because the Queen is supposed to be uncommunicative, but she could conceivably comment on everything in the game. d. Rounding out the adaptation There are a few minor things to be changed in Gareth's code in order to make the game a closer adaptation of the novel. These are *extremely* minor changes, but the little intangibles are what makes the game. First, although the game uses the modern term "mantel," Carroll referred to Alice climbing up on the "chimney-piece." Add "chimney" and "chimneypiece" to the list of synonyms for the mantel. (I doubt anyone will try it, but it's nice to be covered.) Second, Caroll indicated changes of scene with rows of asterisks, like so: * * * * * * * * * * * * * * only more spread-out, and so I've added them to the transition between the Drawing Room and the Looking-Glass Room. (I hope everyone appreciates that I spent more time getting the asterisks to look right than on any other single problem; and they probably won't work on a display that doesn't have 80 columns. Such is Human Perversity.) Finally, Carroll was a fiend for using apostrophes to indicate letters removed in abbreviations. He wrote "ca'n't" instead of "can't," because two letters are cut out. Using Carroll's spelling adds a period feel without actually confusing the player, so I've adopted it. (I've also made one of the changes that Gareth suggested at the end of the last tutorial--the change in finding the Red Queen, which began to bug me during playtesting.) To provide a reasonable endpoint, I've added "deadflag = 2" after Alice reads the note; in other words, successfully reading the note is currently the winning condition for this game. 14. Playtesting Look for a moment at the code for reading the note and the book in the mirror. What's wrong with it? (It will work, but not as intended.) Answer: We want Alice to need to stand on the table to see anything in the mirror, and we added that to the standard Reflect routine. However, by handling the note and book with a "before" routine, it never reaches the standard routine, and so many of the important elements don't run. It doesn't check if Alice is on the table, and it doesn't even check if she's reflecting it in the mirror. She could stand on the floor and reflect the book in the grate, and it would give the same message. To fix the table problem, add this to the Reflect routine for both the note and book: if (player notin table) "You ca'n't see that in the looking-glass."; and to fix the other problem, add this (as the first element): if (second ~= mirror) "What a strange idea!"; Both these are taken directly from ReflectSub. The lesson: if you want to subvert the standard verb process, be sure that you keep in mind what the verb is doing, and replace the elements you can't do without. (Also, playtest your game before you release it, so you can catch things like this and appear foresightful instead of forgetful.) I believe that's all there is to say at the moment. Send any bug reports (or suggestions for improving the code, or blatant Americanisms) on my section of the game to the above address. Incidentally, I think it would be interesting to expand this code into a full-fledged adaptation of the book, with every section written by a different author. This wouldn't lend itself to making a great work of IF (although the book's episodic nature makes it more appropriate than most) but, if every author included commentary as they went, it could be a useful learning tool. (I'd only make three requests: first, that every author include a tutorial of some sort; second, that the authors stick as close as possible to the book; and third, that the code remain freely donated.)