Infocom's language?

18 views
Skip to first unread message

Stefan Jokisch

unread,
Feb 8, 1996, 3:00:00 AM2/8/96
to
Douglas McNeil writes:

>What was the Infocom in-house compiler for the Z-machine like? As
>high-level as Inform, or closer to "Z-assembly"?

If I remember correctly, their compiler was even further away from
Z-code. It is said that they used a language similar to MDL, which
in turn is similar to Lisp. However, Infocom never had anything
comparable to Graham's Inform library, so writing games was probably
much harder those days.

-- Stefan


Andrew C. Plotkin

unread,
Feb 8, 1996, 3:00:00 AM2/8/96
to
jok...@euklid.informatik.uni-dortmund.de (Stefan Jokisch) writes:
> Douglas McNeil writes:
>
> >What was the Infocom in-house compiler for the Z-machine like? As
> >high-level as Inform, or closer to "Z-assembly"?
>
> If I remember correctly, their compiler was even further away from
> Z-code. It is said that they used a language similar to MDL, which
> in turn is similar to Lisp.

At this, Zarf smirks evilly. I'm working on my competition entry now,
see, and...

> However, Infocom never had anything
> comparable to Graham's Inform library, so writing games was probably
> much harder those days.

Well, that's an assumption. They must have had *some* kind of
library, and since its results were comparable to current Inform
games, the library was probably comparable to Graham's.

--Z

"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."

Commander Space Dog

unread,
Feb 8, 1996, 3:00:00 AM2/8/96
to
Douglas McNeil (94mc...@wave.scar.utoronto.ca) wrote:

: What was the Infocom in-house compiler for the Z-machine like? As


: high-level as Inform, or closer to "Z-assembly"?

They used a language called ZIL, for Zork Implementation Language. It
was supposedly more like LISP than C.
--
+-----------------------------------------------------------------------------+
| "No matter what happens, we'll still be able to enjoy cheese." |
| -The Hon. Dr. Bruce "Eddie" Zambini |
+-----------------------------------------------------------------------------+

Mark Howell

unread,
Feb 9, 1996, 3:00:00 AM2/9/96
to

>Douglas McNeil (94mc...@wave.scar.utoronto.ca) wrote:
>
>What was the Infocom in-house compiler for the Z-machine like? As
>high-level as Inform, or closer to "Z-assembly"?

Here's a few examples of the Zork Implementaton Language (ZIL) that Infocom
used to write their interactive fiction games. Included is the Zork Assembly
code that is produced.

Basically Infocom used a derivative if Muddle, a LISP like language.

ZIL examples V1.1
-----------------

Here are a few examples of Z source code from "Zork: A Computerized Fantasy
Simulation Game" by Lebling, Blank and Anderson, IEEE April 1979. Following them
is the annotated Z assembler code. This is give an idea of how the Z assembler
corresponded to the Z source code.

The BILL-OBJECT routine is 'as is', but the READER routine has been split in two
to match the Z assembler listing. The assembly listing is taken from ZorkII V48.
I have also corrected what appear to be mistakes made during typesetting the
article.

Needs to be viewed in 132 columns.

Z source statements:

Comment:
;"comment-line"

Routine definition:
<DEFINE routine-name ([parameters...]) routine-code>

Set global value:
<SETG global-variable value>

Condition:
<COND (condition action)
.
.
.
(condition action)
(ELSE action)>

Null object (== false)
<>

Print text followed by a new line:
<TELL text-expression [text-expression...]>
<TELL text-expression [text-expression...] CR>

Logical NOT:
<NOT condition>

Logical AND:
<AND condition-1 condition-2>

Test attribute:
<TRNN object attribute-number>

Test for equality:
<EQUAL? expression expression [expression...]>

Test verb:
<VERB? verb-name>

Test lit:
<LIT? location-number>

Plus:
<+ expression [expression...]>

Get an object:
<GET-OBJ object-name>

Test for null object:
<EMPTY? object>

Direct object:
<PRSO>

Indirect Object:
<PRSI>

Get proprty value:
<OREAD object property-number>

Get object description:
<ODESC2 object>

Return value TRUE:
<RTRUE>

Z routine source code

;"The object function for the Zorkmid bills. It is mostly to make a few sacrastic comments."

<DEFINE BILL-OBJECT ( )
<SETG BANK-SOLVE!-FLAG T>
<COND (<VERB? "BURN">
<TELL "Nothing like having money to burn!">
<>) ;"Prints sarcasm but doesn't handle the command (accomplished by returning the false object <>)."
;"This allows BURN to also deal with it."
(<VERB? "EAT">
<TELL "Talk about eating rich foods!">
) ;"Doesn't allow EAT to run by returning non-false."
>
>

Annotated Z assembler code

Routine bd42, 0 locals () ; <DEFINE BILL-OBJECT ( )

bd43: STORE G35,#01 ; <SETG BANK-SOLVE!-FLAG T>
bd46: JE G91,#1d -> [FALSE] bd5f ; <COND (<VERB? "BURN">
;"Prints sarcasm but doesn't handle the command (accomplished by returning the false object <>)."
;"This allows BURN to also deal with it."
bd4a: PRINT "Nothing like having money to burn!"
; <TELL "Nothing like having money to burn!">
bd5d: NEW_LINE
bd5e: RET #FALSE ; <> )
bd5f: JE G91,#34 -> [FALSE] RET #FALSE ; (<VERB? "EAT">
;"Doesn't allow EAT to run by returning non-false."
bd63: PRINTLN_RET "Talk about eating rich foods!" ; <TELL "Talk about eating rich foods!"> ) >>

Z routine source code

;"READER is the general reading function."

<DEFINE READER1 ( )
<COND (<NOT <LIT? ,HERE>> ;"There must be light to read."
<TELL "It is impossible to read in the dark.">)
(<AND <NOT <EMPTY? <PRSI>>> ;"<PRSI> is the indirect object."
;"If there is one, the player is trying to use something as a magnifying glass."
<NOT <TRNN <PRSI> ,TRANSBIT>>> ;"If so, it better be transparent."
<TELL "How does one look through a " 1 <ODESC2 <PRSI>> "?">) ;"It failed the test, so print sarcasm."
>
>

Annotated Z assembler code

Routine 855e, 0 locals () ; <DEFINE READER1 ( )

;"There must be light to read."
855f: JZ G5b -> [FALSE] 8579 ; <COND (<NOT <LIT? ,HERE>>
8562: PRINTLN_RET "It is impossible to read in the dark."
; <TELL "It is impossible to read in the dark.">)
;"<PRSI> is the indirect object."
;"If there is one, the player is trying to use something as a magnifying glass."
8579: JZ G90 -> [TRUE] RET #FALSE ; (<AND <NOT <EMPTY? <PRSI>>>
;"If so, it better be transparent."
857c: TEST_ATTR G90,#07 -> [TRUE] RET #FALSE ; <NOT <TRNN <PRSI> ,TRANSBIT>>>
;"It failed the test, so print sarcasm."
8580: PRINT "How does one look through a " ; <TELL "How does one look through a " 1 <ODESC2 <PRSI>> "?">)
8591: PRINT_OBJ G90
8593: PRINTLN_RET "?" ; >>

Z routine source code

<DEFINE READER2 ( )
<COND (<NOT <TRNN <PRSO> ,READBIT>> ;"The direct object should be readable."
<TELL "How can one read a " 1 <ODESC2 <PRSO>> "?">) ;"It's not."
(<OBJECT-ACTION>) ;"Now the object read gets a chance."
(ELSE ;"It didn't handle it, so print long text."
<TELL <OREAD <PRSO> ,LONG-TELL1>>)
>
>

Annotated Z assembler code

Routine 8596, 0 locals () ; <DEFINE READER2 ( )

;"The direct object should be readable."
8597: TEST_ATTR G8f,#10 -> [TRUE] 85af ; <COND (<NOT <TRNN <PRSO> ,READBIT>>
;"It's not."
859b: PRINT "How does one read a " ; <TELL "How can one read a " 1 <ODESC2 <PRSO>> "?">)
85aa: PRINT_OBJ G8f
85ac: PRINTLN_RET "?"
;"Now the object read gets a chance."
; (<OBJECT-ACTION>) [This seems to have been removed from the source.]
;"It didn't handle it, so print long text."
; (ELSE
85af: GET_PROP G8f,#07 -> -(SP) ; <TELL <OREAD <PRSO> ,LONG-TELL1>>)
85b3: PRINT_VIR (SP)+
85b5: NEW_LINE
85b6: RET #TRUE ; >>

Some more ZIL from Stu Galley to describe a room with the following properties:

1) The room's name was Gruble
2) The description was "this is a description"
3) North took you to room "Rumble"
4) West took you to room "Tumble"
5) If the user had foobared the barfoo then
5a) Add to description "hole in south wall"
5b) South leads to room "Arstol"
6) Item "nabble" is here
7) Item "krabble" is here, but can only be picked up if the player wasn't
carrying item "frabble"

<OBJECT GRUBLE
(IN ROOMS)
(DESC "Gruble")
(NORTH TO RUMBLE)
(WEST TO TUMBLE)
(SOUTH TO ARSTOL IF BARFOO-DONE)
(ACTION GRUBLE-F)>

<ROUTINE GRUBLE-F ("OPT" ARG)
<COND (<EQUAL? .ARG ,M-LOOK>
<TELL "this is a description" CR>
<COND (,BARFOO-DONE
<TELL "hole in south wall" CR>)>
<RTRUE>)>>

<GLOBAL BARFOO-DONE <>>

<OBJECT BARFOO
(DESC "barfoo")
(SYNONYM BARFOO)
(ACTION BARFOO-F)>

<ROUTINE BARFOO-F ()
<COND (<VERB? FOOBAR>
<SETG BARFOO-DONE T>
<TELL "You have foobared the barfoo." CR>)>>

<OBJECT NABBLE
(IN GRUBLE)
(DESC "nabble")
(SYNONYM NABBLE)>

<OBJECT KRABBLE
(IN GRUBLE)
(DESC "krabble")
(SYNONYM KRABBLE)
(ACTION KRABBLE-F)>

<ROUTINE KRABBLE-F ()
<COND (<AND <VERB? TAKE> <IN? ,FRABBLE ,PLAYER>>
<TELL "You can't pick up the krabble if you are carrying the frabble." CR>)>>

All the ZIL from "Zork: A Computerized Fantasy Simulation Game" by Lebling,
Blank and Anderson, IEEE April 1979.

Comments (as in the MDL language) are strings following a semicolon.

Thus ;"I am a comment."

;"The definition of the `verb' READ:"

<ADD-ACTION "READ"
"Read"
[(,READBIT REACH AOBJS ROBJS TRY)
;"Restrictions on characteristics and location of objects for defaulting - filling in an unadorned `READ' command.
The object must be readable and accessible."
["READ" READER] DRIVER]
;"READER is the function, and the form `READ object' is preferred (the `driver')"
[(,READBIT REACH AOBJS ROBJS TRY) "WITH" OBJ ["READ" READER]]
;"specification for `READ obj1 WITH obj2'"
[(,READBIT REACH AOBJS ROBJS TRY) "THROUGH" OBJ ["READ" READER]]
;"specification for `READ obj1 THROUGH obj2'">

;"Synonyms for READ:"

<VSYNONYM "READ" "SKIM">

;"READER is the general reading function:"

<DEFINE READER ()
<COND
(<NOT <LIT? ,HERE>>
;"There must be light to read."
<TELL "It is impossible to read in the dark.">)
(<AND <NOT <EMPTY? <PRSI>>>
;"<PRSI> is the indirect object. If there is one, the player is trying to use something as a magnifying glass."
<NOT <TRNN <PRSI> ,TRANSBIT>>
;"If so, it better be transparent!">
<TELL "How does one look through a " 1 <ODESC2 <PRSI>> "?"> ;"It failed the test, so print sarcasm")
(<NOT <TRNN <PRSO> ,READBIT>>
;"The direct object should be readable."
<TELL "How can I read a " 1 <ODESC2 <PRSO>> "?"> ;"It's not.")
(<OBJECT-ACTION>
;"Now the object read gets a chance.")
(ELSE
;"It didn't handle it, so print text."
<TELL <OREAD <PRSO>> ,LONG-TELL1>)>>

;"An object: A stack of Zorkmid bills (Zorkmids are the currency of Zork)"

<OBJECT ["BILLS" "STACK" "PILE"] ;"The object's name and synonyms."
["NEAT" "200" "ZORKM"] ;"Adjectives which refer to the object."
"stack of zorkmid bills"
<+ ,OVISON ,READBIT ,TAKEBIT ,BURNBIT> ;"Properties of the object: it's visible, readable, takeable, flammable"
BILLS-OBJECT
() ;"The contents of the object (always empty for this object)."
[ODESC1 "200 neatly stacked zorkmid bills are here." ;"The long description."
ODESCO "On the floor sit 200 neatly stacked zorkmid bills." ;"The initial long description (when first seen by the player)."
OSIZE 10 ;"The object's weight."
OTVAL 15 ;"The value of the object: points for finding it and saving it."
OFVAL 10
OREAD ,ZORKMID-FACE ;"What to print when the object is read."]
;"The elements of an object with tokens naming them are rare (few objects are readable and thus need OREAD slots).
The other slots are common to all objects.">

;"The object function for the Zorkmid bills. It is there mostly to make a few sarcastic comments."

<DEFINE BILLS-OBJECT ()
<SETG BANK-SOLVE!-FLAG T>
<COND
(<VERB? "BURN">
;"Prints sarcasm but doesn't handle the command (accomplished by returning the false object <>).
This allows BURN also to deal with it."
<TELL "Nothing like having money to burn!">
<>)
(<VERB? "EAT">
;"Doesn't allow EAT to run (by returning a non-false)."
<TELL "Talk about eating rich foods!">)>>

;"A room: the vault in which the Zorkmid bills are found"

<ROOM "BKVAU" ;"The internal name of the room."
"This is the Vault of the Bank of Zork, in which there are no doors."
"Vault"
,NULEXIT
;"There are no exits from this room."
(<GET-OBJ "BILLS">)
;"The bills are initially here."
<>
<+ ,RSACREDBIT ,RLANDBIT>
;"The room may not be entered by the thief, and is a land room."
[RGLOBAL <+ ,WALL-ESWBIT ,WALL-NBIT>]>
;"The walls of the room are/may be referenced."

Dave Lebling

unread,
Feb 9, 1996, 3:00:00 AM2/9/96
to
pdar...@rwd.goucher.edu (Commander Space Dog) wrote:

>They used a language called ZIL, for Zork Implementation Language. It
>was supposedly more like LISP than C.

You betcha. Here's a pseudo-sample (if my memory serves):

<OBJECT TROLL
(IN TROLL-ROOM)
(SYNONYM TROLL MONSTER)
(ADJECTIVE UGLY NASTY)
(DESC "troll")
(FDESC "An ugly troll brandishing a bloody axe appears in
front of you.")
(FUNC TROLL-F)>

<ROUTINE TROLL-F ()
<COND (<VERB? EXAMINE>
<TELL "He's even uglier than you thought." CR>)
(<VERB? ATTACK>
<TROLL-ATTACK-F>)
...
>>

and so on, ad nauseum. This sort of thing will look vaguely familiar
if you know Lisp.

We didn't have "libraries" in the Inform sense. What we had were all
the games that we had previously written, and these could be tweaked
for each new game.

The parser and general verb libraries were generally passed on from
game to game more-or-less unchanged, as were certain "globals" (such
as your hands, yourself, the sky, the ground, etc.) So we didn't have
to rewrite navigation, or parsing, or scoring, or handling taking,
dropping, inventory control, and so on unless we wanted to.

This method was chosen partly because of the incredible premium on
saving space in the early days. You really didn't want the code for
things you didn't absolutely need, because there was no room for it.

Dave Lebling


Dave Lebling

unread,
Feb 12, 1996, 3:00:00 AM2/12/96
to
howe...@movies.enet.dec.com (Mark Howell) wrote:
>Here's a few examples of the Zork Implementaton Language (ZIL) that Infocom
>used to write their interactive fiction games. Included is the Zork Assembly
>code that is produced.

The examples given are mostly from the "mainframe Zork," aka Dungeon.
That is to say, they are pretty straight MDL, rather than being ZIL.
The article referenced was written before Infocom.

By the time ZIL was a going concern, a lot of the details had changed.
Stu's GRABBLE/FRABBLE example is the only part of the posting that's
actually ZIL rather than MDL.

Evolution continued beyond that. For example, we eventually could do
input matching with a routine (actually a MDL macro) called P?. This
looked like

<P? verb-or-list-of-verbs
noun-or-list-of-nouns
second-noun-or-list-of-nouns>

So you could say

<P? ATTACK * SWORD>

to catch any "attack something with sword" input. This was an
evolution from having had VERB?, PRSO?, and PRSI? in the Zork I
timeframe.

Similarly, there was an output routine (also a MDL macro) called TELL
that handled most text output with fairly simple keywords for the verb
and nouns. These compiled into PRINTs and PRINTIs and PRINTRs.

The more-or-less incomprehensible verb definitions in the posting
(which are straight MDL) were replaced by somewhat more comprehensible
ones in ZIL. They went something like:

<SYNTAX ATTACK OBJ WITH OBJ = V-ATTACK>
<SYNONYM ATTACK HIT WHACK SMASH>

I've left out a lot of ill-recalled detail (you could specify
properties the objects needed to have, and which things to search to
find them, such as the room, yourself, open containers in your
possession or in the room, and so on). That's how you got the "(with
the sword)" comments from the parser.

Dave Lebling


Magnus Olsson

unread,
Feb 13, 1996, 3:00:00 AM2/13/96
to
In article <311bc56a...@nova.avid.com>,

Dave Lebling <david_...@avid.com> wrote:
>pdar...@rwd.goucher.edu (Commander Space Dog) wrote:
>
>>They used a language called ZIL, for Zork Implementation Language. It
>>was supposedly more like LISP than C.
>
>You betcha. Here's a pseudo-sample (if my memory serves):

(sample deleted)

How similar was the ZIL Zork code to the original Zork, which was
written in MDL (if I remember correctly)? Could you re-use code from the
mainframe Zork in the Trilogy, or did you have to do a total re-write?

Magnus Olsson (m...@df.lth.se)


Reply all
Reply to author
Forward
0 new messages