Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Participants: Derya Akbaba * Ben Allen * Natalia-Rozalia Avlona * Kirill Azernyi * Erin Kathleen Bahl * Natasha Bajc * Lucas Bang * Tully Barnett * Ivette Bayo * Eamonn Bell * John Bell * kiki benzon * Liat Berdugo * Kathi Berens * David Berry * Jeffrey Binder * Philip Borenstein * Gregory Bringman * Sophia Brueckner * Iris Bull * Zara Burton * Evan Buswell * Ashleigh Cassemere-Stanfield * Brooke Cheng* Alm Chung * Jordan Clapper * Lia Coleman * Imani Cooper * David Cuartielles * Edward de Jong * Pierre Depaz * James Dobson * Quinn Dombrowski * Amanda Du Preez * Tristan Espinoza * Emily Esten * Meredith Finkelstein * Caitlin Fisher * Luke Fischbeck * Leonardo Flores * Laura Foster * Federica Frabetti * Jorge Franco * Dargan Frierson * Arianna Gass * Marshall Gillson * Jan Grant * Rosi Grillmair * Ben Grosser * E.L. (Eloisa) Guerrero * Yan Guo * Saksham Gupta * Juan Gutierrez * Gottfried Haider * Nabil Hassein * Chengbo He * Brian Heim * Alexis Herrera * Paul Hertz * shawné michaelain holloway * Stefka Hristova * Simon Hutchinson * Mai Ibrahim * Bryce Jackson * Matt James * Joey Jones * Masood Kamandy * Steve Klabnik * Goda Klumbyte * Rebecca Koeser * achim koh * Julia Kott * James Larkby-Lahet * Milton Laufer * Ryan Leach * Clarissa Lee * Zizi Li * Lilian Liang * Keara Lightning * Chris Lindgren * Xiao Liu * Paloma Lopez * Tina Lumbis * Ana Malagon * Allie Martin * Angelica Martinez * Alex McLean * Chandler McWilliams * Sedaghat Payam Mehdy * Chelsea Miya * Uttamasha Monjoree * Nick Montfort * Stephanie Morillo * Ronald Morrison * Anna Nacher * Maxwell Neely-Cohen * Gutierrez Nicholaus * David Nunez * Jooyoung Oh * Mace Ojala * Alexi Orchard * Steven Oscherwitz * Bomani Oseni McClendon * Kirsten Ostherr * Julia Polyck-O'Neill * Andrew Plotkin * Preeti Raghunath * Nupoor Ranade * Neha Ravella * Amit Ray * David Rieder * Omar Rizwan * Barry Rountree * Jamal Russell * Andy Rutkowski * samara sallam * Mark Sample * Zehra Sayed * Kalila Shapiro * Renee Shelby * Po-Jen Shih * Nick Silcox * Patricia Silva * Lyle Skains * Winnie Soon * Claire Stanford * Samara Hayley Steele * Morillo Stephanie * Brasanac Tea * Denise Thwaites * Yiyu Tian * Lesia Tkacz * Fereshteh Toosi * Alejandra Trejo Rodriguez * Álvaro Triana * Job van der Zwan * Frances Van Scoy * Dan Verständig * Roshan Vid * Yohanna Waliya * Sam Walkow * Kuan Wang * Laurie Waxman * Jacque Wernimont * Jessica Westbrook * Zach Whalen * Shelby Wilson * Avery J. Wiscomb * Grant Wythoff * Cy X * Hamed Yaghoobian * Katherine Ye * Jia Yu * Nikoleta Zampaki * Bret Zawilski * Jared Zeiders * Kevin Zhang * Jessica Zhou * Shuxuan Zhou

Guests: Kayla Adams * Sophia Beall * Daisy Bell * Hope Carpenter * Dimitrios Chavouzis * Esha Chekuri * Tucker Craig * Alec Fisher * Abigail Floyd * Thomas Forman * Emily Fuesler * Luke Greenwood * Jose Guaraco * Angelina Gurrola * Chandler Guzman * Max Li * Dede Louis * Caroline Macaulay * Natasha Mandi * Joseph Masters * Madeleine Page * Mahira Raihan * Emily Redler * Samuel Slattery * Lucy Smith * Tim Smith * Danielle Takahashi * Jarman Taylor * Alto Tutar * Savanna Vest * Ariana Wasret * Kristin Wong * Helen Yang * Katherine Yang * Renee Ye * Kris Yuan * Mei Zhang
Coordinated by Mark Marino (USC), Jeremy Douglass (UCSB), and Zach Mann (USC). Sponsored by the Humanities and Critical Code Studies Lab (USC), and the Digital Arts and Humanities Commons (UCSB).

Code Critique: Hitchhiker's Guide to the Galaxy

Software: Hitchhiker's Guide to the Galaxy (Game)
Authors: Steve Meretzky and Douglas Adams
Language: ZIL: Zork Implementation Language
Year: 1984
Source file:
Code repository:
Zil Code Manual:

The Hitchhiker's Guide to the Galaxy was a text adventure game based on the book/radio/television series that was known in the universe for serving puzzles that made you want to smash your brain with a brick wrapped in a lemon. See this discussion for some common reactions. In this puzzle, and this is a spoiler, you need to have previously removed your common sense so that you can at once have "tea" and "no tea" in your inventory.

I wanted to start a thread to invite you all on a sidequest to explore the code of this game that I encountered at a very formative time of my life. Pretty much influenced everything I do as an e-lit artist. But I do recognize (especially having tried to teach it) that this game goes beyond the usual level of frustration-inducing puzzles that @jeremydouglass has written about. Some argue that the difficulty of the puzzles was tied to a profit motive -- selling more hint books, increasing gameplay time. A later game from Adams, Bureaucracy, would make frustrating puzzles its main theme. I'm not sure this is the best passage to start with, but I'd like to use this to open a code exploration of this game and perhaps also The Restaurant at the End of the Universe code, which I am just learning exists!

                <PRSO? ,ME>>
              (<VERB? HELLO>
              (<AND <VERB? WHAT>
                <PRSO? ,OBJECT-OF-GAME>>
"\"Unless you're here to show me some clear sign of your intelligence, please
leave me alone. I'm a very busy door.\"" CR>
             <VERB? SHOW GIVE KNOCK OPEN>>
        <TELL "You already induced the door to open." CR>)
             <VERB? CLOSE>>
"The door snaps, \"Hey! I'm resting. I've had a very busy day.\"" CR>)
           (<VERB? KICK>
"\"I suppose you think that since you have legs and I have not, you can get
away with that sort of thing. Well,\" the door continues stiffly, \"maybe you
can and maybe you can't.\"" CR>)
           (<VERB? SHOW GIVE>
        <COND (<AND <PRSO? ,TEA ,NO-TEA>
                <HELD? ,TEA>
                <NOT <PRSO? ,TEA-SHOWN>>>
               <COND (<PRSO? ,TEA ,NO-TEA>
                  <SETG TEA-SHOWN ,PRSO>)>
               <COND (<PROB 50>
"The door says \"Big deal. Anyone can have">
                  <ARTICLE ,PRSO>
                  <TELL ".\"" CR>)
                  <TELL "The door yawns." CR>)>)>)
           (<VERB? OPEN KNOCK>
        <COND (<AND <HELD? ,TEA>
"The door is almost speechless with admiration. \"Wow. Simultaneous tea
and no tea. My apologies. You are clearly a heavy-duty philosopher.\" It
opens respectfully." CR>)
"The door explains, in a haughty tone, that the room is occupied by a
super-intelligent robot and that lesser beings (by which it means you)
are not to be admitted. \"Show me some tiny example of your intelligence,\"
it says, \"and maybe, just maybe, I might reconsider.\"" CR>)>)
           (<AND <VERB? ASK-ABOUT>
             <PRSI? ,OBJECT-OF-GAME>>
        <TELL "\"To keep out sub-intelligent beings.\"" CR>)
           (<VERB? THROUGH>
               <DO-WALK ,P?EAST>)
               <DO-WALK ,P?WEST>)>)
           (<VERB? EXAMINE>

A few questions:
How does this code speak to the frustration-inducing nature of the game?
What does this code reveal about ZIL as a language?
Or does this code show that the game is just terribly misunderstood?
Is this a representative passage from the game?
How does this compare with puzzles of other Infocom games of the time?
What other passages of the HGTTG code should we explore?


  • I'm not sure what on line 24 does, but I like how it reflects a programmer's or user's actual language in use; after all, who hasn't periodically sworn at their machine?

    I did peek into the source code for ZIL verbs, and happened to find HO-HUM. While it "doesn't do anything", it does make me laugh and reflect on 'ho-hum-ness' and ineptness on a planetary scale:

         " doesn't do anything."
         " accomplishes nothing."
         " has no desirable effect.">>  

    link to source code:

  • @Lesia.Tkacz said:
    I'm not sure what on line 24 does, but I like how it reflects a programmer's or user's actual language in use; after all, who hasn't periodically sworn at their machine?

    Yeah, my first thought is that there was a CLEAR command that didn't quite work and someone finally added FUCKING-CLEAR out of frustration. I bet this sort of thing was way more common before the expectation that everyone's code would eventually end up in public on github!

  • I have never seen this -cool! At first I thought - LISP (but not lisp). Then I thought is screening door only set to the winner within the conditional (so you can never access this block of code).

    As I started reading this I realized that I don't want to read this. I want to see this represented as a graph. I started reading the ZIL manual, which I found more interesting than this code. Why? The ideas and metaphysical assumptions that go into ZIL are perhaps richer than the implementation.

    The main conceit behind the hhg code seems more about playing with variable names, and playing up the fact that code is written in human readable language. There is a DSL aspect to to this program, enabled by ZIL, which provides x-ray vision into the world of hhg, and that is one of the things literature does, ie. create its own world.

    My main gripe with this work is that it has a punch line, the play with language makes it appear like a piece of work by Gertrude Stein or something, is open to a multiplicity of interpretations. Where as with this program, the puzzle nature of it, implies a right and wrong way of reading it. To read it in another way is to 'queer' the game (recommended reading

    I did have an inexplicable flashback to uni and writing a wumpus ai.

  • Hi! Mark invited me to drop in on this conversation.

    I have the advantage of having written a lot of text games in this format, although I didn't use ZIL. So I have a pretty good idea of what the code is doing.

    It's not exactly written in human-readable language. But given its genesis in the MIT community, maybe the developers didn't consider "human-readable" and "programming language" to be separate concepts!

    I agree that HO-HUM is a fine example of a well-named data structure. (It's an array of strings, not a verb per se.) Even better is the function that makes use of it: HACK-HACK, which is used to print a sentence of the pattern "XXX doesn't do anything" or "YYY accomplishes nothing." (See verbs.zil:2887.) The word "hack" has a dense cultural history in the MIT world; I really don't have a sense of what "HACK-HACK" would have meant to an MIT alum circa 1984.

    An even better example is the variable WINNER. In Infocom's parser code, this always refers to the character who is taking action at that point. It goes back to the earliest Infocom games -- you can see the same variable in Zork 1, where it essentially always referred to the player. In HHGG, WINNER switches around quite a bit. It can refer to the playable characters (Arthur, Trillian, Zaphod) or the active NPCs (Prosser, the Beast, etc).

    "Winner" was common MIT slang. The Jargon File ( says "often sarcastic" -- i.e., a euphemism for "loser". But not always. I sense that the ambiguity was part of the fun. Referring to the player as "WINNER" was some kind of joke, but cruel or kind?

  • HACK-HACK looks like a common routine (although implementations vary across games).

    There's a description in one of the infocom memoires (which I can't currently find, alas) of the way that a new game would be started: the source for something recent copied across to a new directory, the imp hacking out the game-specific stuff, and then building on that. So there are many common idioms that would grow and become the established way of expressing ideas, I think (even if the implementations behind those ideas became more sophisticated over time). This would be a rich source for analysis.

    Just out of curiosity, I've tabulated routine definitions across a bunch of infocom games for which source is available. You can see the result here. It's a pretty low-fidelity start [assembled using awk, so it's not even aware of the syntax of ZIL] to that kind of analysis, but it does indicate some things that shared common ancestry.

    (I was wondering if FUCKING-CLEAR was one of those inherited features - but it looks like it wasn't. I wonder if that was a contribution directly from Adams?)

  • (I was wondering if FUCKING-CLEAR was one of those inherited features - but it looks like it wasn't. I wonder if that was a contribution directly from Adams?)

    So, in perhaps my most juvenile bit of research and no doubt a shining moment in CCS, I just checked the repository for the other Meretzky games and did not find it in any of them.

    However, it does appear in the unreleased code for the Restaurant at the End of the Universe game in the files people.zap and people.zil, code attributed to Stu Galley and others. Seems to point to that coming from Adams.

  • Jimmy Maher's writeup ( is pretty clear that Adams was not involved in the coding of the game. Meretzky did all the implementation.

    The definition of FUCKING-CLEAR in Restaurant is identical to that in HHGG, except that one line is commented out. (The routine clears two parser flags, P-CONT and QUOTE-FLAG. But all use of QUOTE-FLAG in the Restaurant code is commented out.) So I figure that the Restaurant project was started by cloning the HHGG code, and then rearranging, tidying up, and removing features that wouldn't be used in the new game.

    The function name could still have been Adams' voice coming through, but it could equally well have been Meretzky. One can easily imagine the sort of day (or late night) where you spend two hours tracking down a bug, say "I forgot to fucking clear that fucking quote flag?!", and then write a function to fix it.

  • One of the things I was thinking about when posting this snippet was the way the frustration of the way this game is implemented is epitomized by a puzzle that requires the player/winner to possess tea and no tea at the same time. You need to possess not possessing tea, while not possessing your own common sense.

    Can you all help me out. Is "no tea" a flag? a variable state?

    How does that (whatever it is) change the way we read the scene with the puzzle or this code?

  • "No tea" is defined as an object just like any other object in the code. It's an 'object' in both the programming sense (as seen in object-oriented programming) and also, literally, an object manifest in the game- in this case an inventory item.

        <OBJECT NO-TEA
            (IN GLOBAL-OBJECTS)
            (DESC "no tea")
            (SYNONYM TEA)
            (ADJECTIVE NO)
            (ACTION NO-TEA-F)>

    Having the absence of something as an inventory item (a felt absence) is a good joke in itself, and the joke is really committed to by giving the standard dropping and taking messages for the "no tea":

     <ROUTINE TEA-F ()
         <COND (<AND <VERB? TAKE>
                 <PRSO? ,TEA>>
            <MOVE ,TEA ,PROTAGONIST>
            <SETG HOLDING-NO-TEA <>>
            <TELL "no tea: Dropped." CR>)
               (<VERB? DROP>
            <MOVE ,TEA ,HERE>
                   <SETG HOLDING-NO-TEA T>
                   <TELL "Dropped." CR>)
                   <SETG HOLDING-NO-TEA T>
                   <TELL "no tea: Taken." CR>)>)

    Moreover, there is a text adventure convention that player will soon check their inventory on starting a game, and so placing a goal in the inventory is a fine way to begin motivating the player, especially as the goal can then be checked later at the player's convenience.

  • But note the existence of a global variable HOLDING-NO-TEA, which is set true or false in sync with the NO-TEA object.

    Well, let's verify that... it's set true when you TAKE the NO-TEA. It's set false when you TAKE the TEA. (This is in TEA-F and NO-TEA-F, the action handlers for those two objects.) Things get messier when you DROP the TEA, though! That's the end of the function quoted just above... it looks like it distinguishes the case of DROP TEA when you're holding the tea ("no tea: Taken") from the case when you're holding both ("Dropped.")

    Makes sense once you squint at it and count on your fingers.

    There are a few other places where the flag is set true. Turning on the Drive when it's running off the tea, and -- curiously -- when taking inventory. Perhaps they were worried about the flag getting set wrong, so they fix it up at INVENTORY time?

    The interesting question is why have a flag at all? It should be sufficient to test <HELD? ,TEA> at any time.

  • Greetings—Not sure if the group is already aware of these links, but in case there’s an interest in playing the game alongside the code, here are some running implementations.

    This one is a no-frills, pure-text implementation:

    And this one, commissioned by BBC, has a more elaborate graphical wrapper around the core game but I presume it's still the same game within:

    I wonder if there's an easy-to-start Z-machine implementation where one can load the code, play it, mess with it a bit, then play it again, just to see what happens (or if one can dodge/change certain puzzles in the game).

  • The interesting question is why have a flag at all? It should be sufficient to test <HELD? ,TEA> at any time.

    Perhaps flags are checked with a higher priority than objects and this was to ensure the correct line triggered somewhere. Or possibly they had it as a flag first, wrote some code for it, and then introduced it as a physical object in the inventory later and then never cleaned everything up again. I know from my own experience in authoring, it's very easy to end up with variables that have been made obsolete but may continue to be used. For instance, I might originally define a flag with a true/false boolean, and then later a third possibility is written and so a new numerical variable is created: if I'm lazy and it's relatively minor, both those variable might continue to persist in the code.

  • edited January 31

    Douglas Adams also comments on the "no tea" puzzle from Infocom's Hitchhiker's Guide to the Galaxy in this production note shared by Jess Morrissette:

    To provide some context for this code, here is a walkthrough narrating the gameplay by
    Lisa Fitzsimmons,[1] who describes the conclusion of the screening door puzzle in this way:

    War Chamber and Maze (hearing, "below")

    Hear the Dark, and go aft. Get the awl, then just wait until you arrive in the Maze. This maze (whose room descriptions may amuse players of Zork I) is actually inside your own brain. There's no pattern here; just wander around in any directions you like until you see a "large black particle". This particle is your common sense. Take it and you will once more be returned to the Dark. Wait four turns, hear the dark, and go aft, aft, and up to the Bridge.
    [....] take the tea. Then, take the "no tea" that you dropped when you got the tea - which will now not force you to drop the tea, since you've removed your common sense. Have a look at your inventory: tea, and no tea. Well, well, well!
    [...] Go down and aft to Corridor, Aft End. Try to go port and you will be told the "screening door" is closed, so open it. Since you are intelligent enough to have both tea and no tea, it will open for you.

    There is also a possibility of encountering minor bugs elsewhere related to the way that TEA / NO TEA work as objects. From Nathan Simpson's More bugs in Infocom games list:

    In all versions, if you DROP TEA in Maze, then it stays there instead of disappearing.

    1. Fitzsimmons is clearer on this point than the HHGTG Walkthrough by Jason Coxon on IGN. ↩︎

Sign In or Register to comment.