Zork I
Infocom's 1980 cave game, read through its ZIL source, released by Microsoft under the MIT license in 2025.
On this page
The atlas reads Zork I’s ZIL source as published in the Historical Source collection, under the MIT license Microsoft added in 2025. The files carry 1983 copyrights and call the game “Renovated ZORK I”, so they’re a later revision than the 1980 release, and the claims here are about that revision.
The parser takes a verb and up to two noun clauses, each with a preposition, and THEN starts a new command on the same line1. The brass lantern burns 200 turns, then dims in three steps and dies after 385 lit turns (computed)2. What the player carries is weighed against a load of 1003.
The score tops out at 350. Each treasure pays once when first taken and again while it sits in the trophy case4. In a fight the player’s strength grows with the score5, and each blow rolls 1–9 on a table picked by the defender’s strength6. At 0 points a sword blow at the troll kills 2 times in 9, while a knife blow at the thief can’t kill (computed)7.
Mechanics
| Mechanic | Kind | How |
|---|---|---|
| Text parser | Clauses with prepositions | a verb and up to two noun clauses with prepositions; THEN chains commands |
| Light-source timer | Staged dimming | 200 lit turns, then waits of 100, 70, and 15 with a warning each: 385 in all |
| Inventory limit | Weight | a load of 100 by size, and a growing chance to fumble a take past 7 objects |
| Treasure score | Take, then display | a treasure's value on the first take, its second value while in the trophy case; 350 in all |
| Hit chance | Strength picks a result table | the defender's strength picks a result table, and a 1–9 roll picks miss, stagger, wound, knockout, or kill |
Every claim about this game, by concept (7)
References
- ^Zork I's ZIL source (a 1983-headed revision) parses a command into one verb and up to two noun clauses, each of which a preposition can lead, and matches the result against the verb's syntaxes, such as PUT OBJECT IN OBJECT. A third noun clause draws “There were too many nouns in that sentence.” A clause can name several objects only where the syntax allows it, as TAKE's does. THEN or a period ends one command, and the parser keeps the rest of the line for the next.CodeZork I ZIL source
How we know
98<CONSTANT P-NC2 8>gparser.zil lines 90–99 at 97b7b3d · upstream ↗ There were too many nouns in that sentence.
gparser.zil#L326-L333 · upstream ↗ 384<SYNTAX PUT OBJECT (HELD MANY HAVE) IN OBJECT = V-PUT PRE-PUT>gsyntax.zil line 384 at 97b7b3d · upstream ↗ 469<SYNTAX TAKE OBJECT (FIND TAKEBIT) (ON-GROUND IN-ROOM MANY) = V-TAKE PRE-TAKE>gsyntax.zil line 469 at 97b7b3d · upstream ↗ 1302 <TELL "You can't use multiple ">gparser.zil lines 1294–1302 at 97b7b3d · upstream ↗ 273 <SETG P-CONT <+ .PTR ,P-LEXELEN>>>gparser.zil lines 267–275 at 97b7b3d · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In Zork I's ZIL source the brass lantern's timer starts at 200 and runs only while the lamp is on: turning it on enables the I-LANTERN event and turning it off disables it. The clock counts it down once per parsed command other than the verbs
TELL,BRIEF,SUPER-BRIEF,VERBOSE,SAVE,VERSION,QUIT,RESTART,SCORE,SCRIPT,UNSCRIPT, andRESTORE. Each time it runs out, the lamp table sets the next wait, 100, then 70, then 15, and prints “The lamp appears a bit dimmer.”, “The lamp is definitely dimmer now.”, and “The lamp is nearly out.” if the lamp is held or in the room. After the 15 the lamp burns out for good, 385 lit turns in all (computed).CodeZork I ZIL sourceHow we know
2642 <QUEUE I-LANTERN 200>1dungeon.zil line 2642 at 97b7b3d · upstream ↗ 2241 <ENABLE <INT I-LANTERN>>1actions.zil lines 2238–2242 at 97b7b3d · upstream ↗ 2247 <DISABLE <INT I-LANTERN>>1actions.zil lines 2243–2248 at 97b7b3d · upstream ↗ 172 (T <SET V <CLOCKER>>)>)>>gmain.zil lines 169–172 at 97b7b3d · upstream ↗ 56 <PUT .C ,C-TICK <- .TICK 1>>gclock.zil lines 52–58 at 97b7b3d · upstream ↗ 2223 "The lamp appears a bit dimmer."1actions.zil lines 2220–2228 at 97b7b3d · upstream ↗ 2316 <ENABLE <QUEUE I-LANTERN <SET TICK <GET .TBL 0>>>>1actions.zil lines 2315–2319 at 97b7b3d · upstream ↗ 2331 <FSET .OBJ ,RMUNGBIT>)>1actions.zil lines 2328–2337 at 97b7b3d · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^Zork I's ZIL source refuses a TAKE (“Your load is too heavy”) when the object's weight plus the player's would pass the load limit of 100, unless the object is inside something the player carries. A weight is an object's SIZE plus its contents' weights; worn items count 1 toward the player, and the player's own object sets no SIZE, so it takes the default of 5. A separate check makes a TAKE fail, “You're holding too many things already!”, when more than 7 objects not worn are in hand, at a chance of 8% per object held: 63% at 8 and certain from 13 (computed). In a fight, a light wound to the player lowers the limit by 10 and a serious wound by 20 while it's above 50; it recovers 10 every 30 turns and returns to 100 when the wounds heal.CodeZork I ZIL sourcerevised
How we know
94<GLOBAL LOAD-ALLOWED 100>gglobals.zil lines 92–94 at 97b7b3d · upstream ↗ 1932 <G? <+ <WEIGHT ,PRSO> <WEIGHT ,WINNER>> ,LOAD-ALLOWED>>gverbs.zil lines 1931–1940 at 97b7b3d · upstream ↗ 1997 <+ .WT <GETP .OBJ ,P?SIZE>>>gverbs.zil lines 1988–1997 at 97b7b3d · upstream ↗ 24<PROPDEF SIZE 5>zork1.zil line 24 at 97b7b3d · upstream ↗ 271 (STRENGTH 0)gglobals.zil lines 267–272 at 97b7b3d · upstream ↗ 1898<GLOBAL FUMBLE-PROB 8>gverbs.zil lines 1896–1898 at 97b7b3d · upstream ↗ 1943 <PROB <* .CNT ,FUMBLE-PROB>>>gverbs.zil lines 1941–1945 at 97b7b3d · upstream ↗ 1982 <COND (<NOT <FSET? .X ,WEARBIT>>gverbs.zil lines 1979–1986 at 97b7b3d · upstream ↗ 3466 <SETG LOAD-ALLOWED <- ,LOAD-ALLOWED 20>>)>)1actions.zil lines 3457–3466 at 97b7b3d · upstream ↗ 3598 <SETG LOAD-ALLOWED <+ ,LOAD-ALLOWED 10>>)>1actions.zil lines 3593–3602 at 97b7b3d · upstream ↗ 3325<CONSTANT CURE-WAIT 30>1actions.zil line 3325 at 97b7b3d · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^Zork I's ZIL source sets the maximum score at 350. An object or room with a VALUE pays it once, when first taken or entered, and the value is then cleared. A treasure's TVALUE counts while it lies in the trophy case: at the end of a turn in the living room in which the player takes anything or puts something in the case, the score is reset to the banked points plus the TVALUEs of what is in the case. Only objects directly in the case count, since the routine looks inside containers but discards what it finds there. Reaching 350 whispers “Look to your treasures for the final secret.”CodeZork I ZIL source
How we know
7<GLOBAL SCORE-MAX 350>1dungeon.zil line 7 at 97b7b3d · upstream ↗ 1870 <PUTP .OBJ ,P?VALUE 0>)>>gverbs.zil lines 1867–1870 at 97b7b3d · upstream ↗ 1961 '<SCORE-OBJ ,PRSO>)gverbs.zil lines 1959–1961 at 97b7b3d · upstream ↗ 2122 <SCORE-OBJ .RM>gverbs.zil line 2122 at 97b7b3d · upstream ↗ 483 <SETG SCORE <+ ,BASE-SCORE <OTVAL-FROB>>>1actions.zil lines 477–484 at 97b7b3d · upstream ↗ 501 <COND (<FIRST? .F> <OTVAL-FROB .F>)>1actions.zil lines 496–502 at 97b7b3d · upstream ↗ Look to your treasures for the final secret.
gverbs.zil#L1851-L1862 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^Zork I's ZIL source sets the player's fighting strength at 2 + score ÷ 70, rounded down (computed from 2 + score ÷ (350 ÷ (7 − 2))), from 2 at no points to 7 at 350, plus a wound modifier that is 0 when unhurt. A villain's strength is its STRENGTH: 2 for the troll and 5 for the thief. Attacked with its bane, the sword for the troll and the nasty knife for the thief, a villain counts 1 less, but no less than 1; a thief engrossed in a treasure counts at most 2.CodeZork I ZIL source
How we know
3323<CONSTANT STRENGTH-MAX 7>1actions.zil lines 3323–3324 at 97b7b3d · upstream ↗ 3377 <+ ,STRENGTH-MIN 3378 </ ,SCORE 3379 </ ,SCORE-MAX 3380 <- ,STRENGTH-MAX ,STRENGTH-MIN>>>>>
1actions.zil lines 3375–3381 at 97b7b3d · upstream ↗ 1046 (STRENGTH 2)>1dungeon.zil lines 1036–1046 at 97b7b3d · upstream ↗ 978 (STRENGTH 5)>1dungeon.zil lines 968–978 at 97b7b3d · upstream ↗ 3394 <SET TMP <- .OD <GET .OO ,V-BEST-ADV>>>1actions.zil lines 3383–3397 at 97b7b3d · upstream ↗ 3802 <LTABLE <TABLE TROLL SWORD 1 0 TROLL-MELEE>1actions.zil lines 3801–3803 at 97b7b3d · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In Zork I's ZIL source each blow, by the player or a villain, reads 9 entries of a result table picked by the defender's strength, and a roll of 1–9 picks one. A defender of strength 1 uses DEF1, starting 0, 1, or 2 entries in for an attacker of strength 1, 2, or 3 and up. A defender of 2 uses DEF2A for an attacker of 1, or DEF2B starting 0, 1, or 2 entries in for 2, 3, or 4 and up. A defender of 3 or more uses the attacker's strength less the defender's, clamped to −2..2: DEF3A starting 0 or 1 entries in for −2 or −1, DEF3B likewise for 0 or 1, and DEF3C for 2. The results are miss, stagger, light wound, serious wound, knockout, and kill; the DEF3 tables hold no knockout or kill, and an unarmed or unconscious villain dies to the player's blow outright.CodeZork I ZIL source
How we know
3250<CONSTANT SERIOUS-WOUND 5> ;"defender seriously wounded"1actions.zil lines 3246–3254 at 97b7b3d · upstream ↗ 3261 STAGGER STAGGER ⋮ 3268 STAGGER STAGGER 3269 LIGHT-WOUND LIGHT-WOUND ⋮ 3275 STAGGER STAGGER 3276 LIGHT-WOUND LIGHT-WOUND LIGHT-WOUND ⋮ 3283 STAGGER STAGGER 3284 LIGHT-WOUND LIGHT-WOUND ⋮ 3290 STAGGER STAGGER 3291 LIGHT-WOUND LIGHT-WOUND LIGHT-WOUND ⋮ 3296 MISSED 3297 STAGGER STAGGER 3298 LIGHT-WOUND LIGHT-WOUND LIGHT-WOUND LIGHT-WOUND
1actions.zil lines 3258–3299 at 97b7b3d · upstream ↗ 3313 <TABLE DEF3A1actions.zil lines 3301–3317 at 97b7b3d · upstream ↗ 2644 <PUT ,DEF1-RES 1 <REST ,DEF1 2>>1dungeon.zil lines 2644–2649 at 97b7b3d · upstream ↗ 3440 <SET RES <GET .TBL <- <RANDOM 9> 1>>>1actions.zil lines 3427–3440 at 97b7b3d · upstream ↗ cannot defend himself: He dies." CR>
1actions.zil#L3502-L3521 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^Computed from Zork I's ZIL source: at 0 points the player's strength is 2. Swinging the sword at the unhurt troll (2, less 1 for the sword) reads DEF1 from its second entry, so a blow misses 3 times in 9, staggers 2, knocks out 2, and kills 2. Swinging the nasty knife at the thief when he isn't engrossed (5, less 1) reads DEF3A from its start: 5 misses, 2 staggers, and 2 light wounds, and no kill.CodeZork I ZIL source
How we know
3260 MISSED MISSED MISSED MISSED 3261 STAGGER STAGGER 3262 UNCONSCIOUS UNCONSCIOUS 3263 KILLED KILLED KILLED KILLED KILLED>>
1actions.zil lines 3258–3263 at 97b7b3d · upstream ↗ 3282 MISSED MISSED MISSED MISSED MISSED 3283 STAGGER STAGGER 3284 LIGHT-WOUND LIGHT-WOUND 3285 SERIOUS-WOUND SERIOUS-WOUND>>
1actions.zil lines 3280–3285 at 97b7b3d · upstream ↗ 3491 <SET ATT <FIGHT-STRENGTH>>1actions.zil lines 3491–3495 at 97b7b3d · upstream ↗ 3520 <SET TBL <GET ,DEF3-RES <+ .ATT 2>>>)>1actions.zil lines 3510–3521 at 97b7b3d · upstream ↗ 3377 <+ ,STRENGTH-MIN 3378 </ ,SCORE 3379 </ ,SCORE-MAX 3380 <- ,STRENGTH-MAX ,STRENGTH-MIN>>>>>
1actions.zil lines 3375–3381 at 97b7b3d · upstream ↗ 3394 <SET TMP <- .OD <GET .OO ,V-BEST-ADV>>>1actions.zil lines 3383–3397 at 97b7b3d · upstream ↗ 2644 <PUT ,DEF1-RES 1 <REST ,DEF1 2>>1dungeon.zil lines 2644–2645 at 97b7b3d · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
Sources
Code
- Blank, Marc, Dave Lebling, Bruce Daniels, and Tim Anderson. 2025. “Zork I source code (Infocom ZIL).” Commit 97b7b3d. historicalsource/zork1 @ 97b7b3d · licence, all uses