Let's play Zork + Colossal Cave Adventure

That is correct. The thief traverses indoor rooms in the order they appear in the (offscreen) ROOMS container. This is approximately the (reversed) order they appear in the source code. It’s not necessarily adjacent rooms; he jumps around the map a lot.

2 Likes

As it turns out, giving a treasure to the thief evidently is intended to have a special effect—it just doesn’t work. There is code in the game to temporarily reduce the thief’s battle strength (making the thief’s attacks less effective and the player’s attacks more effective) when you give him a treasure. It’s in the “the thief is taken aback by your unexpected generosity” code path. But due to a bug, or oversight, it doesn’t work as intended. See:

We’re going to be looking at this in some detail soon, when we get to the source code episodes. It was a big surprise to me to find that the thief in Zork teleports through rooms in a fixed order—I was convinced, while playing, that he had to use the same passages that were available to the player. On the other hand, in Adventure, the pirate is a special case of the dwarves, and uses much the same logic. The pirate/dwarf movement uses the ordinary cave passages, and is essentially a random walk with some restrictions (like never returning to the room they just came from, unless there is no other option). If you want a sneak preview of the dwarf/pirate logic, see §§159–176 (“Dwarf stuff”) in the source code.

1 Like

Episode A11

We resumed attempts at the Perfect Run.

Attempt 3

We followed the same approximate plan as before, hoping for better luck. We decided to try carrying around at least one treasure while making our rounds, to give the pirate more opportunity to attack.

First trip: spices, chain, silver, diamonds, trident, magazine. (Depositing the trident was a mistake, as it is needed later for the pearl.)

Second trip: vase, eggs, emerald, rug.

Third trip: pyramid. We picked up the trident again to take back into the cave.

Fourth trip: trident, pearl, gold, jewelry, coins. But we held on to the coins, to give the pirate something to steal.

Fifth trip: we went out in search of the pirate. We checked the past game transcripts to see in what rooms we’ve encountered the pirate before:

Count Room
5 maze of twisty little passages, all alike
3 Hall of the Mountain King
2 unknown
1 N/S passage
1 soft room
1 south side chamber
1 steep incline above large room
1 Swiss cheese room

This time, we found the pirate in his maze, just one room away from the dead end where he hides the chest. We delivered the coins and the chest to the house. Our score was 276 points after delivering all the treasures and leaving the magazine at Witt’s End.

While waiting for the cave to close, we experimented more with the random exits from Bedquilt. Going north from Bedquilt has a chance to take you to a junction of three secret canyons, exiting to the north, south, and SE. North from the junction is a “window on pit”: the same one we’ve visited so often before? No—it’s the other side of the mirror canyon, at last! Southeast from the junction took us back to Bedquilt. We didn’t get a chance to try the south exit from the junction, as the cave closed and we were whisked to the endgame.

In the repository, we took the dynamite (the rod with the rusty mark) from the southwest end and dropped it there, at the southwest end. Then we moved to the northeast end and blasted. The result: the wall broke open and flooded the room with lava.

New personal best: 335/350 points, Master Adventurer Class A.

Topics mentioned:

2 Likes

There is one more minor bit of geography you haven’t seen, and this one isn’t wholely randomized like the Bedquilt thing. It does however, as you now know, have no real purpose in the game.

Episode Z12

Job one of this episode was to figure out what to do with the thief. We finally engaged in the scurrilous practice of save scumming, saving and reloading at a point just before the battle in order to try out different tactics.

As a side quest, we needed to find out how to open the jeweled egg. Our hunch was that we had to turn it over to an NPC (because we, the player, have “neither the tools nor the expertise”). But what NPC? The troll? The cyclops? The thief? The bat?

  • Give the egg to the troll: the troll eats it.
  • Give the rusty knife to the troll: the troll eats it.
  • Drop the rusty knife in front of a disarmed troll: nothing happens.
  • Give the egg to the cyclops: “The cyclops is not so stupid as to eat THAT!”

We staged every weapon imaginable in the Cyclops Room adjacent to the thief’s hideout. (We were missing the rusty knife, however.)

  • elven sword
  • bloody axe
  • nasty knife
  • crystal trident

During this setup, the thief stole the egg from us. Then commenced a sequence of battles:

Battle #1
"Trying to attack the thief with a crystal trident is suicidal."
Throw axe: the thief just accepts it.
Attack with sword: thief wins.
Battle #2
Automatically parry a turn-zero attack, losing knife.
Attack with axe, draw blood once, but eventually get disarmed.
Attack with sword, miss, thief wins.
Battle #3
Attack ineffectually with axe, get stunned and can't fight.
Retreat, give up.
Battle #4
Attack repeatedly with axe, lightly injure the thief once.
Automatically parry an attack with the nasty knife, losing it in the process.
Attack once more with axe, thief wins.
Battle #5
Attack with knife, temporarily disarm thief.
Attack with knife, miss, get knocked out.
Attack with knife, knock the thief unconscious!
Try to take the stiletto while he's out, but "the stiletto seems white-hot".
Then:
>dispatch thief with knife
The unconscious thief cannot defend himself: He dies.
Left behind were a chalice, a stiletto, and "a jewel-encrusted egg, with a golden clockwork canary".

The long-hoped-for victory stirs ambiguous emotions. Was fighting with the knife the key? In any case, the thief is the means by which you open the jeweled egg. You give the egg to the thief (or let it be stolen), the thief opens the egg offstage, and after you kill the thief you recover the now-open egg and the golden clockwork canary it contains.

The experience versus the thief was unsatisfying. It had really felt like it was meant to be a puzzle to solve, not brute-force randomness. The odds of victory in each attempt must be less than 50%. Are you meant to just go after the thief first thing every time, and keep restarting until you win by chance, before getting on with the rest of the game? It doesn’t jibe with our intuition about game design.

We fiddled with the granite wall in the treasure room to no effect. We attacked the sleeping cyclops; it just wakes him up. With the thief out of commission, the trap door in the living room no longer locks shut behind us.

We spent the rest of the run going around collecting and depositing treasure, to see how high we could get our score after defeating the thief. Nothing happens when you put the canary in the nest in the tree. But winding the canary, in the forest, summons the songbird, which drops off a minor treasure, a brass bauble. We took the canary, now free of its egg, to the coal mine, but it still doesn’t do anything.

Using the torch as a light source, we went off to try combining the Egyptian scarab with the Egyptian coffin. We had reached the conclusion, in the last episode, that it was not possible to get to the top of the waterfall, collect the scarab, and get back down, without first getting the sceptre (and therefore opening the coffin). But that was mistaken—it is possible, using the boat. From the buoy, go east to the sandy cave, get the scarab, return to the buoy, and land west to White Cliffs Beach south, from where you can re-enter the cave. We got the scarab, took it back to the undisturbed coffin, and abracadabra! it doesn’t do anything. But we learned that the golden coffin itself is a treasure, which requires a special move to get out of the underground.

New personal best: 251/350 points, rank of Adventurer.

Our modest proposal for improving Zork I:

  • Giving an enemy the rusty knife should work to defeat them.
  • The clockwork canary should do something in the coal mine.
  • You should be able to go through the drafty passage as a ghost.

Topics mentioned:

2 Likes

Partially.

Your odds of beating the thief are merely bad with the knife, as opposed to catastrophic with any other weapon.

However, the higher your score, the higher your combat bonus. (Points are “experience points” in some vague D&D sense.) So the correct answer is to attack the thief last.

With the thief out of commission, the trap door in the living room no longer locks shut behind us.

The trap door code does not check the thief status – in any version, as far as I know.

There’s a not-entirely-clear check for the TOUCHBIT flag, but I don’t think that’s related to the thief either.

2 Likes

I believe the logic is:

  • TOUCHBIT is set when the trapdoor is locked behind you
  • TOUCHBIT is cleared when you get back aboveground via the chimney in the studio or via resurrection
  • The trapdoor doesn’t get locked behind you if TOUCHBIT is set

So if you get back aboveground via any “unlimited” means (not the chimney with limited carrying capacity, or resurrection with limited uses), then the trapdoor no longer locks behind you. But because of the way it’s tracked, you can make it lock again if you use the chimney or resurrection, even if you’ve already opened the grate in the forest (etc).

2 Likes

Episode A12

We resumed attempts at the Perfect Run.

This time, we were not going to worry about trying to carry around a piece of treasure to be stolen by the pirate. Going into the pirate’s maze, as we did in the previous episode A11, had probably been a good idea, for reasons that will become more clear when we look at the source code.

Attempt 4

First trip: trident, spices, chain. We entered Witt’s End, having forgotten to first pick up the magazine. After trying many times to get out by going west, the game gave a hint: “Don’t go west.” We abandoned the run and restarted.

66/350 points, novice class adventurer.

Attempt 5

First trip: we dropped the magazine at Witt’s End. Getting out of Witt’s End took an amazing 43 attempts. Then we got the trident, spices, and chain, but lost them to the pirate in the Oriental Room. We pivoted to the emerald, vase, eggs, and silver. To conserve battery, we turned off the lamp while doing FEE FIE FOE FOO and while dropping treasures.

Second trip: we fended off a dwarf attack. We collected the diamonds, then lost them to the pirate again. Then we died to a two-dwarf pincer attack and had to restart.

122/350 points, “Experienced Adventurer”.

Attempt 6

First trip: trident, spices, chain, pearl, silver. We survived two dwarf attacks.

Second trip: magazine, emerald, then a pirate attack. We got the vase and eggs on the way to the pirate’s maze. We survived two dwarf attacks. The pirate got us once more, en route to the secret dead end. There we recovered the vase, eggs, chest, and emerald and took them to the building.

Third trip: pyramid, gold nugget, diamonds, jewelry, rug.

Fourth trip: coins.

While waiting for the cave to close, we re-entered the secret junction north of Bedquilt to explore the south exit. Descending the stalactite drops you into the all-alike maze.

In the last episode, in the repository, we dropped the dynamite at the SW end, moved to the NE end, then blasted. This time, we did the opposite: dropped the dynamite at the NE end, moved to the SW end, then blasted.

There is a loud explosion, and a twenty-foot hole appears in the far wall, burying the dwarves in the rubble. You march through the hole and find yourself in the main office, where a cheering band of friendly elves carry the conquering adventurer off into the sunset. You scored 350 points out of a possible 350, using 369 turns. All of Adventuredom gives tribute to you, Adventure Grandmaster! To achieve the next higher rating would be a neat trick! Congratulations!!

New personal best: 350/350 points, Adventure Grandmaster!

Topics mentioned:

3 Likes

Episode Z13

To begin we looked at a short “fastest eaten by a grue” tool-assisted speedrun we had developed. The speedrun shows that you can stack multiple commands in one line, by separating them with periods. The input to get eaten by a grue is s.e.open.in.u.u.

It felt like we had solved all the game’s essential mysteries—in isolation. Now it was time to put together the Perfect Run for Zork. We made a dependency chart showing which items must be collected before other items. With that, we drafted a rough and untested plan for collecting all the treasures. We scheduled the thief fight, with its high degree of randomness, early in the run, so we could restart without losing much progress every time the battle didn’t go our way.

Plan
* get egg
in house
take lunch and bottle
take lamp and sword
take rope and knife
down
fight troll with sword
drop sword and rope
maze to Cyclops
offer lunch
offer water
drop bottle
offer egg to thief
fight thief with knife
drop knife
* take egg
* take canary
* take chalice
maze to room S
* get coins
get key
maze to grating
unlock grating
up
wind canary
* get bauble
in house
deliver
_ egg
_ coins
_ chalice
_ canary
_ bauble

down
to dam
get matchbook
get wrench
get screwdriver
push yellow
turn bolt with wrench
drop wrench
get pump
inflate boat
launch boat
get buoy
land sandy beach
get shovel
go to cave
dig
* get scarab
launch boat
west
open buoy
* get emerald
drop buoy
go to loud room
echo
* get platinum
go to cellar
up
deliver
_ emerald
_ scarab
_ platinum

down
get rope
go to round room
se
tie rope to railing
down
* take torch
lamp off
go to egyptian room
open coffin
* take sceptre
* take coffin
pray
in house
deliver
_ coffin
go to rainbow
wave sceptre
* take pot of gold
in house
deliver
_ sceptre
_ pot of gold

down
to temple
take bell
s
take book and candles
down
ring bell
light match
light candles with match
read book
drop candles
drop book
in
* take skull
go to mirror room
touch mirror
* get trunk
* get trident
touch mirror
go to gallery
take painting
up
deliver
_ crystal skull
_ painting
_ trunk
_ trident

get garlic
down
go to mirror room
touch mirror
go to bat room
* get figurine
go to shaft room
light lamp
put torch and screwdriver in basket
get coal
put coal in basket
lower basket
go to drafty room
drop all
w
get torch and screwdriver and coal
put coal in machine
turn switch with screwdriver
* get diamond
* get bracelet
go to slide room
down
up
deliver
_ torch
_ bracelet
_ figurine
_ diamond

Attempt 1

Defeated the troll.

Died to the thief.

We wondered if you have to leave the thief alone with the egg for a while to get him to unlock it, or if it happens instantly when you give it to him.

Attempt 2

Defeated the troll.

Died to the thief.

Attempt 3

Counted the leaves.

Defeated the troll.

Died to the thief.

Attempt 4

Counted the leaves.

Defeated the troll.

Died to the thief (turn zero).

Attempt 5

Counted the leaves.

Got a light injury from the troll, and waited for it to heal.

Defeated the thief. The egg was open immediately after the battle—so the thief doesn’t need simulated time to work on it.

First trip: canary, coins, chalice, bauble, egg.

Second trip: scarab, emerald.

We died at the waterfall, unexpectedly, after trying to go west after taking the buoy.

We didn’t restart immediately, but instead went looking for our gear. (We didn’t know, at the time, that the points penalty from dying would prevent us from finishing the game. It doesn’t in Adventure.) But we couldn’t find the scarab again, so we restarted.

Attempt 6

Received a light injury from the troll, and waited it out.

Defeated the thief (in just three attacks).

Counted the leaves.

First trip: canary, coins, chalice, bauble, egg.

Second trip: emerald, scarab, platinum. This time, we took the buoy (containing the emerald) the first time entering the room on the river, not during the return crossing, and didn’t go over the falls.

Third trip: sceptre, pot of gold. We picked up the torch, but held on to it as a light source. We grabbed the sceptre from the Egyptian Room. The coffin is too heavy to carry at the same time as our other items, so we’d come back for it. PRAY works even if you’re not carrying the coffin; we arrived back in the forest. Delivered the sceptre and pot of gold to the trophy case.

Fourth trip: coffin.

Fifth trip: skull, trident, trunk. We tried also for the painting but didn’t have room.

Sixth trip: painting.

Seventh trip: figurine, bracelet, torch, diamond. The lamp started to dim on this trip.

As we placed the final treasure in the trophy case and earned the 350th point, a voice whispered: “Look to your treasures for the final secret.” There appeared in the trophy case a parchment map. The map showed a stone barrow SW of a clearing in the forest. Going outside, there was a new secret path leading SW from the front of the house. We followed the new path, stepped inside the stone barrow, and won!

As you enter the barrow, the door closes inexorably behind you. Around you it is dark, but ahead is an enormous cavern, brightly lit. Through its center runs a wide stream. Spanning the stream is a small wooden footbridge, and beyond a path leads into a dark tunnel. Above the bridge, floating in the air, is a large sign. It reads: All ye who stand before this bridge have completed a great and perilous adventure which has tested your wit and courage. You have mastered the first part of the ZORK trilogy. Those who pass over this bridge must be prepared to undertake an even greater adventure that will severely test your skill and bravery!

New personal best: 350/350 points, rank of Master Adventurer.

We brainstormed things to look at in the next, source code episode. We commented on how, in the making of the tool-assisted speedrun, it seems that grue attacks in the dark are not certain but are slightly randomized, and that the random number generator can be influenced (in the Apple II version, at least) by frame-granularity delays.

Finally we tried the alternative strategy for the cyclops that had been mentioned in a previous episode. Saying ODYSSEUS causes the cyclops to flee in terror and carve a passage to the living room.

Topics mentioned:

3 Likes

The mainframe version of Zork, unlike Zork I, does have a designated “last lousy point”. It’s obscure (but IMO not as obscure as Adventure’s) and also kinda funny in a meta sort of way. I’ll happily spoil it here if you want.

Zork II does, in fact, pick up right where Zork I left off. You get your lamp back (magically recharged, of course). Some areas of Zorks II and III were from the mainframe original, and some aren’t. (And even some of the bits from Zork I play differently in Zork mainframe.)

1 Like

Episode AS

In this XL 3-hour episode we explore the source code of Adventure. The version of Adventure we have been playing is special: it is a literate program, meaning that it has been specially arranged to promote appreciation and understanding. The source code is divided into numbered and linked sections that are grouped thematically and accompanied by essay-like commentary.

The CWEB source code produces both C source code to be compiled and a TeX document meant to be read by a person. Follow along in the PDF as we go section by section.

The typeset program appears in the book Selected Papers on Fun & Games. The printed book version has something the online version does not, this cave map:

Video timestamps and section references:

0:00:33
Literate programming background.
0:04:06
Literate programming demo.
0:16:10
Game map.
0:19:30 §1
Introduction.
0:25:25 §2
Running the program and main function.
0:26:46 §4
The vocabulary. enum wordtype, hash table.
0:29:20 §910
Motion words. N, S, E, W, ENTER, GRATE, XYZZY, etc.
0:34:48 §1112
Object words. LAMP, ROD, BIRD, BRIDGE, BRIDGE_, GOLD, PEARL, etc.
0:40:31 §1314
Action words. TAKE, DROP, GO, TOSS, BLAST, INVENTORY, SCORE, QUIT, etc.
0:48:33 §16
Message words. HELP, INFO, ABRACADABRA, MIST, etc.
0:51:49 §1821
Cave data. enum location. struct instruction and connection logic table. Cave connections. make_loc, make_inst, ditto.
1:05:19 §23
End of road.
1:06:35 §25
Inside building. XYZZY, PLUGH, clip of Don Woods pronouncing the magic words.
1:10:54 §26
Valley. Index.
1:11:45 §27
Forest, random room connections.
1:14:32 §29
Depression, unlocking the grate.
1:15:44 §30
Chamber below the grate. "If you've come this far, you're probably hooked."
1:16:00 §31
Cobble crawl to top of small pit, gold/stairs puzzle, the pseudo-location neck.
1:17:23 §32

Hall of Mists. Possibly erroneous connection to jumble via the motion word Y2.

At your feet is a small pit breathing traces of white mist.  An east
passage ends here except for a small crack leading on.
Rough stone steps lead down the pit.
* d

You are at one end of a vast hall stretching forward out of sight to
the west.  There are openings to either side.  Nearby, a wide stone
staircase leads downward.  The hall is filled with wisps of white mist
swaying to and fro almost as if alive.  A cold wind blows up the
staircase.  There is a passage at the top of a dome behind you.
Rough stone steps lead up the dome.
* y2
A little dwarf just walked around a corner, saw you, threw a little
axe at you, cursed, and ran away.  (The axe missed.)

You are in a jumble of rock, with cracks everywhere.
There is a little axe here.
1:18:48 §34
East bank of fissure, crystal bridge.
1:19:18 §3637
Maze of twisty little passages, all alike.
1:21:52 §39
Maze of twisty little passages, all different. Dwarf-proof passages.
1:23:30 §40

Hall of the Mountain King. Huge green fierce snake, SECRET motion.

You are in the Hall of the Mountain King, with passages off in all
directions.
A huge green fierce snake bars the way!
* secret

You are in a secret canyon, which here runs E/W.  It crosses over a
very tight canyon 15 feet below.  If you go down you may not be able
to get back up.
1:27:42 §41
Y2. "Somewhere Nearby is Colossal Cave", window on pit (east).
1:31:56 §43
Clam/oyster.
1:32:33 §44
Witt's End.
1:34:30 §4546
Bedquilt, Swiss cheese room, ORIENTAL motion, twopit room.
1:39:59 §47
Giant room.
1:40:24 §48
Secret canyon at junction of three canyons, stalactite down to the all-alike maze.
1:41:59 §49
Window on pit (west).
1:44:07 §52
Mirror canyon.
1:45:02 §55
Bridge troll.
1:45:42 §56
Dead ends, pirate logic.
1:46:56 §58
Repository rooms.
1:47:27 §5962
Pseudo-locations. crack, neck, snaked, pdrop, etc.
1:48:54 §6368
Data structures for objects.
1:49:37 §6970
Object data.
1:50:53 §7475
The main control loop.
1:51:36 §7687
Command parser, action dispatcher, special cases in parsing.
1:52:57 §88
Room descriptions, gold/stairs puzzle.
1:53:56 §90
Using objects, TAKE KNIFE.
1:54:32 §9295
Simple verbs. TAKE, EAT, OPEN, CLOSE, READ, INVENTORY, BRIEF, SCORE, QUIT.
1:55:50 §97
SAY, reward check.
2:02:19 §98
EAT.
2:02:39 §99
WAVE, BLAST, RUB, game end obfuscation, bonus points.
2:05:32 §100101
FIND, BREAK, WAKE.
2:06:17 §102103
Lighting and extinguishing the lamp, lamp power.
2:06:37 §104111
Liquid assets. Containers, watering the plant, oiling the door, filling the vase.
2:09:47 §112115
TAKE special cases, bird logic.
2:10:35 §116127
The other actions. DROP, vending machine, bear vs. troll. bird vs. snake, TOSS, combat. lost_treasures.
2:14:04 §128
Dragon combat, main loop impersonation.
2:15:39 §129
FEED.
2:17:22 §130133
OPEN and CLOSE special cases.
2:17:41 §135
READ.
2:17:45 §136139
FEE FIE FOE FOO.
2:18:47 §149150
Motions. Alcove, tight tunnel, pdrop.
2:19:11 §154158
Random numbers.
2:19:43 §159171
Dwarf stuff. Pirate as dwarf 0. Movement and combat, dflag.
2:25:58 §172176
The pirate. Stealing and hiding booty.
2:29:19 §177180
Closing the cave. clock1, clock2.
2:31:58 §181182
Endgame. Repository.
2:33:53 §183192
Death and resurrection. Running out of lamp, replacing batteries. dwarves_upset.
2:36:05 §193200

Scoring. Hints, hints extending lamp life. Launching the program.

Correction to what was stated in the video: you get the Adventure Grandmaster rank even with 349 points, you don't need the full 350.

Topics mentioned:

1 Like

Episode ZS

This is the first of two Zork source code episodes. Our primary instrument for exploring the source code is the remarkable Visible Zorker. It lets you play the game, and at the same time see the function call stack and inspect the world state.

You can also see the source code in a browseable online repository. See the post Zork 1/2/3 are officially and legally released under the MIT license.

Neither of us was already acquainted with the code. In this video we’re learning as we go. This episode saw us generally exploring and following the thread of whatever struck our fancy. We looked at the general game engine (rooms, objects, variables, ADVENTURER, action functions), the parser (PRSA, PRSI, PRSO variables), timers (songbird, injury, thief, sword), and combat—with numerous digressions. We found answers to some questions we had:

  • “Hello sailor” has no effect. It gives different messages if you say it enough times. Besides “sailor”, you can also say “aviator” or “footpad”.
  • It is possible to defeat the thief without the knife, just less likely.
  • ULYSSES is another word that works to scare the cyclops. But the internal name of the verb is V-ODYSSEUS.

There’s a lot more to see, so we’ll be back.

0:03:40
ZIL, MDL, The Visible Zorker.
0:06:49
"Activity" tab.
0:07:46
"World" tab.
0:09:54
Action functions. WHITE-HOUSE-F.
0:13:12
Visible Zorker commentaries (green eyeballs). Rooms and items, scenery and global objects.
0:14:56
ADVENTURER, ME, WINNER, HERE.
0:16:19
"State" tab. BEACH-DIG, COFFIN-CURE, YUKS.
0:17:01
Parser variables PRSA, PRSI, PRSO (action, indirect object, and direct object respectively). PUT and PUT-ON actions. Compound commands (PUT SWORD AND LEAFLET IN MAILBOX).
0:20:09
"Timers" tab.
0:21:08
"Files" tab. Super-brief mode.
0:21:37
"?" tab. Release history.
0:22:56
Timers and daemons. Integer underflow. C-TABLE, C-DEMONS.
0:25:55
DIAGNOSE and I-CURE. STRENGTH and carrying capacity. STRENGTH-MAX, STRENGTH-MIN. Local and global variables.
0:31:06
I-FOREST-ROOM, random chirping of songbird.
0:34:04
I-LANTERN, LAMP-TABLE.
0:35:50
BLACK-BOOK. INTNUM. JIGS-UP. LIVING-ROOM-FCN, RUG-FCN. IT.
0:42:35
Object attributes (TURNBIT, READBIT, etc.).
0:44:23
Troll room. FIGHT-STRENGTH, HERO-MELEE. Cyclops combat? CYCLOPS-MELEE. THIEF-MELEE. Combat results and the structure of melee result tables.
0:53:47
VILLAINS table. Weapon weaknesses. The troll is weak to the sword, the thief to the knife.
0:56:02
Began walking through a round of troll combat. THIS-IS-IT. TVALUE, I-SWORD, INFESTED?. I-FIGHT. DEAD. VILLAIN-STRENGTH, THIEF-ENGROSSED (see also). PROB. Points contributing to combat effectiveness.
1:28:47
TROLL-FCN. TROLL-FLAG.
1:33:53
CYCLOPS-FLAG, LLD-FLAG, MAGIC-FLAG, WON-FLAG. COFFIN-CURE, SOUTH-TEMPLE.
1:37:35
Back to analyzing troll combat. Possibility of killing the troll by getting him to eat something sharp. MUNG.
1:45:42

V-ODYSSEUS. ULYSSES is recognized as a synonym of ODYSSEUS, but ODYSSEUS is canon, for several reasons. One of the reasons is that Commandment #12592 in the black book is an acrostic. The first letters of each line spell out ODYSSEUS:

Oh ye who go about saying unto each: "Hello sailor":
Dost thou know the magnitude of thy sin before the gods?
Yea, verily, thou shalt be ground between two stones.
Shall the angry gods cast thy body into the whirlpool?
Surely, thy eye shall be put out with a sharp stick!
Even unto the ends of the earth shalt thou wander and
Unto the land of the dead shalt thou be sent at last.
Surely thou shalt repent of thy cunning.

1:57:06
Code that is unused in Zork I. V-HELLO. "Hello sailor" does… nothing! In Zork I, at least.

Topics mentioned:

Episode ZS′

This is the second and final episode of Zork source code exploration. Again we are using The Visible Zorker to see the source code alongside the game.

We spent the majority of the time looking at the thief: how he moves, stealing things, and combat. We also browsed the properties of various rooms and items, including weights and container capacities. (And finally settled the mystery of the set of teeth.) We uncovered a few deep secrets, like a magical connection between the treasure room and the temple, a different solution for the loud room puzzle, and the fact that death by grue is not an absolute certainty when you take a step in the dark.

0:02:48

We looked up the "set of teeth" that had bedeviled us since episode Z3. The TEETH object is a global object (accessible from any room) that exists only so that the parser has something called "teeth" to refer to when you try to BRUSH TEETH WITH GUNK. (Otherwise it would say "I don't know the word 'teeth'.") The strange phrase "set of teeth" is an artifact of how objects are defined, like "quantity of water" or "pair of hands".

0:09:10

We looked at the function JIGS-UP, which is called whenever the player does something to gets them killed. (Like brushing their teeth with the gunk, say.) The condition that decides whether you respawn alive in the forest or as a ghost at the Gates of Hades is whether you've been to the south temple or not. The RANDOMIZE-OBJECTS function is what scatters your inventory when you die. There's a failsafe in JIGS-UP for when you die when you're already a ghost. (Which takes some doing, but it can happen!)

0:14:34

WALK AROUND HOUSE.

0:16:19

The songbird and the clockwork canary. The songbird is not a live, moving object like the dwarves and pirate in Adventure; but rather one of those that you can refer to from many rooms that doesn't really exist in any of them. While you're in a forest room, there's a uniform probability that you'll hear the chirping of the songbird. (In that way, the songbird is like the first dwarf encounter in Adventure, but not the subsequent ones.)

0:19:54

The thief and thief movement. The thief doesn't follow the same room connections that are available to the player. Instead, he starts in the Round Room and then warps from room to room on a predefined circuit. The thief's STRENGTH is 5, which is why he is so strong in battle. (Compare to the troll's STRENGTH of 2.) There are some random interactions in combat with the thief that we did not see. If you throw the knife at him while not engaged in combat, there is a small chance that he will flee and leave his items behind. The point at which the jeweled egg is opened is when the thief deposits the egg in his lair (either in his wanderings or after he dies).

It seems like you could take the thief's chalice without killing him, if he is unconscious in the treasure room. That, combined with the random chance of making him drop items, might make possible a run where you do not kill the thief.

0:50:31

DUMB-CONTAINER and STUPID-CONTAINER.

0:52:31

I-THIEF, the thief "demon" routine that runs on every turn. The order in which the thief visits rooms is defined by the ROOMS list. But he doesn't enter rooms that have SACREDBIT set, nor rooms that are not solid land (RLANDBIT bit).

The thief may pick up and drop items as he moves around. He'll never take something from a room you haven't been to yet (TOUCHBIT is not set). Otherwise he has a chance of stealing any treasures that are present (ROB function). He may take non-treasures as well, but how this works differs depending on whether he and the player are in the maze. If the thief and the player are inside the maze (MAZEBIT is set), he calls ROB-MAZE, in which he has a chance to remark "My, I wonder what this fine item is doing here" and possibly to pick up the item. Otherwise, he calls STEAL-JUNK, where he has a chance of picking up each non-treasure in the room.

Correction to what was stated at 1:04:08: it looks like the thief can steal the rope in STEAL-JUNK, and in so doing also sets DOME-FLAG to false.

1:11:06

V-LEAP. You will die if you try jumping in the kitchen, because there's a (never usable) down exit from there. But you can jump down from the tree safely.

1:17:08

Perusing the rooms in ROOMS. Seeing which ones are considered sacred. The "Granite Wall" mystery: the strange engraving in the slide room that had baffled us is an oblique hint that there is a connection between the granite wall on the east side of the treasure room and the the granite wall on the west side of north temple. We had dimly guessed that some kind of connection existed, but were unable to make use of it. What it means is that you can say TREASURE or TEMPLE to warp between the two rooms.

1:31:48

Looking at the commentary on various items and rooms. The broken timber in the timber room was used for a puzzle in the original MDL version of Zork. It has no use in Zork I.

RAISED-BASKET and LOWERED-BASKET. BAT, DAM-ROOM, GARLIC, BONES, BUBBLE, COFFIN.

1:37:59

Object size/weight and the capacity of containers. The WEIGHT function.

The ALTAR, too, acts like a container, albeit one you cannot pick up.

The magic boat is a container as well, having capacity 100. We talked about the "boat of holding" glitch, where you fill the boat with items and then deflate it. The deflated boat is considered a different item, with a lower weight than the inflated boat and the items it contains. Re-inflating the boat brings the items back.

1:46:33

More items and their properties. MATCH, PAINTING, CANDLES, GUNK, LEAVES. The buttons in the dam maintenance room.

1:49:58

An alternative solution for the loud room. I-RFILL.

The rushing sound in the loud room is the sound of flowing water. If you turn the bolt once to drain the reservoir, then turn the bolt again to start to refill it, and hurry to the loud room before it completely refills, the loud room will be quiet and you will be able to take the platinum bar.

The implementation of the loud room is really elaborate. Just like the sneaky extra-loop input that secretly accepts "yes" when you fight the dragon in Adventure, the loud room outputs a fake command prompt, reads input outside the main input loop, and handles the input itself without giving it to the main game engine for processing. This is how the echoing effect is achieved.

1:59:23

Syntax definitions. The $VERIFY command. BLAST.

2:00:15

There is only about an 80% probability that you will be eaten by a grue when taking a step from a dark place.

We had the impression that in the case you are not eaten by a grue, you stay in place and cannot actually make progress in the dark, but the part we were looking at is for when you take a step in the dark in a direction where there is no exit. There is another code path (with a separate about 80% chance) for when you follow a valid exit from one dark room to another. (There's a difference in the death message in each case: the former is "You have walked into the slavering fangs" and the latter is "A lurking grue slithered into the room".)

2:03:59

Combat. The THIEF-VS-ADVENTURER function. HERO-BLOW and VILLAIN-BLOW. The player's combat strength (FIGHT-STRENGTH) goes from 2 (STRENGTH-MIN) to 7 (STRENGTH-MAX), increasing by 1 point for every 70 points of score. The player's strength can be adjusted by their STRENGTH property, which is normally 0, except when injured.

The result of any given blow in combat is a random variable that depends mainly on the absolute strength of the defender, and the difference in strength between the defender and the attacker. These numbers are used to index tables of combat results. There are 9 possible outcomes of any attack. Not all of them are encoded directly in the tables, but use special-case logic, such as the defender having a random chance of losing their weapon when staggered.

Topics mentioned:

2 Likes

The thing with teeth being synonymed as “overboard” is a known thing that’s technically a bug. the developers wanted to allow THROW [objec] OVERBOARD while you’re in the boat. So they needed to treat “overboard” as an object. Presumably they chose to synonym it to teeth as some kind of memory-saving trick to avoid creating another object?

But this also leads to probably my favorite zork bug. The overboard code forgets to check if you’re actually holding the thing you’re throwing. Which allows this to happen:

>throw grue overboard
Ahoy – lurking grue overboard!

>look
Frigid River, in the magic boat
You are on the Frigid River in the vicinity of the Dam. The river flows quietly here. There is a landing on the west shore.
There is a lurking grue here. (outside the magic boat)
The magic boat contains:
A tan label

This gets the grue object in a state it’s not supposed to be in: it now is only in that room. You can no longer get the grue description (or do anything else that refers to the grue) unless you’re in that specific room. If you try, you get “You can’t see any grue here!”, which is technically correct (my favorite kind of correct!) but not supposed to happen.

This works for any other global object. The funniest is that you can “throw me overboard”, which from then on gets it to say that “there is a you here” and stops any commands that refer to yourself from working. (There might be some other side effects, if it’s checking the location of “you” anywhere, but I think there’s a difference from what it’s checking in most places versus the “me” object commands use.)

Oh, and remember how the game synonymed overboard with teeth? Because the teeth are a global object, you can throw the teeth overboard, as I just discovered. This doesn’t cause a line about the teeth to appear in the room description, unlike with other objects. What it DOES do is stops you from being able to throw stuff overboard aside from the spot you did it. When you try, it says “You can’t see any overboard here!” because it made the teeth (ie, the overboard object) no longer global!

One more note: yes, they did recycle some code for all 3 Zorks. This also applies in the other games. For instance, Zork II still understands the verb “odysseus” even though there is no cyclops in Zork II (I hope you don’t mind me spoiling that). Except, it doesn’t respond with anything, presumably because they did clear The section of code that actually handles the command, but not the part defining the vocabulary. It just gives no output and goes right to the next command prompt.

2 Likes

They could also have created a new grammar line with OVERBOARD as (approximately) a preposition. But, again, that takes more memory.

It looks like they wanted the generic response to be “Wasn’t he a sailor?” But they screwed up the indentation, maybe, so that message is never reached.

EDIT: Or else the compiler screwed up. It looks like the line <TELL "Wasn't he a sailor?" CR>)> is executed, but the inline string has been wrongly optimized out. The CR remains, which is why the response to ODYSSEUS is two blank lines.

2 Likes