the-infocom-files / zork-substrate

Substrate for the Zork Trilogy Original Editions
4 stars 4 forks source link

PRE-TURN oddities #4

Open eriktorbjorn opened 5 years ago

eriktorbjorn commented 5 years ago

While the V-TURN routine has remained the same in all preserved versions of the Zork I, II and III source code:

<ROUTINE V-TURN ()
     <TELL "This has no effect." CR>>

The PRE-TURN routine has gone through a series of evolutions, with the last one appearing to have some bugs. Here are the various versions of it:

Zork II R22

<ROUTINE PRE-TURN
     ()
     <COND (<NOT <FSET? ,PRSO ,TURNBIT>> <TELL "You can't turn that!" CR>)
           (<NOT <FSET? ,PRSI ,TOOLBIT>>
        <TELL "You certainly can't turn it with a " D ,PRSI "." CR>)>>

Zork I R88, Zork II R48, Zork III R17

<ROUTINE PRE-TURN ()
     <COND (<NOT <FSET? ,PRSO ,TURNBIT>>
        <TELL "You can't turn that!" CR>)>>

Zork I R119 and Solid Gold, Zork II R63, Zork III R25

<ROUTINE PRE-TURN ()
     %<COND (<==? ,ZORK-NUMBER 3>
         '<COND (<AND <EQUAL? ,PRSI <> ,ROOMS>
                  <EQUAL? ,PRSO ,DIAL ,TM-DIAL ,T-BAR>>
             <TELL
"You should turn the " D ,PRSO " to something." CR>
             <RTRUE>)>)
        (ELSE T)>
     <COND (%<COND (<==? ,ZORK-NUMBER 1>
            '<AND <EQUAL? ,PRSI <> ,ROOMS>
                  <NOT <EQUAL? ,PRSO ,BOOK>>>)
               (ELSE
            '<EQUAL? ,PRSI <> ,ROOMS>)>
        <TELL "Your bare hands don't appear to be enough." CR>)
           (<NOT <FSET? ,PRSO ,TURNBIT>>
        <TELL "You can't turn that!" CR>)>>

A couple of things here:

In Zork III, it makes exceptions for DIAL, TM-DIAL and T-BAR. I can understand the first two, but T-BAR can't be turned to anything, doesn't even have TURNBIT (it probably shouldn't) and has its own custom action:

<ROUTINE T-BAR-F ()
     <COND (<VERB? TURN>
        <TELL
"You don't have enough leverage to turn the T-bar. You might be able
to turn the whole structure, however." CR>)>>

I can't find any way to trigger that message at the moment:

>TURN T-BAR
You should turn the T-bar to something.

>TURN T-BAR WITH LAMP
You can't turn that!

I'm still a bit fuzzy on exactly when actions are handled where. Can some of these checks be moved to V-TURN instead, to avoid overriding custom handlers? Judging by a quick search the following action routines handle TURN:

(ROBOT-FCN and DUNGEON-MASTER-F are probably for ordering the robot and Dungeon Master around.)

I haven't had the time to check if all of these work as intended.

eriktorbjorn commented 5 years ago

I did notice this in GWIM:

        <COND (<EQUAL? .GBIT ,RMUNGBIT>
               <RETURN ,ROOMS>)>

I'm not sure what that implies. Possibly it has to do with the syntax definitions that use (FIND RMUNGBIT)? The "TURN" verb is one of those:

<SYNTAX TURN OBJECT (FIND TURNBIT) (HELD CARRIED ON-GROUND IN-ROOM)
        WITH OBJECT (FIND RMUNGBIT) = V-TURN PRE-TURN>
eriktorbjorn commented 5 years ago

Here's what I get in Zork I:

An object that can't be turned, e.g. the bubble:

>TURN BUBBLE
Your bare hands don't appear to be enough.

>TURN BUBBLE WITH SWORD
You can't turn that!

>TURN BUBBLE WITH HANDS
You can't turn that!

>TURN BUBBLE WITH WRENCH
You can't turn that!

I think "TURN" should have printed "You can't turn that".

The bolt:

>TURN BOLT
Your bare hands don't appear to be enough.

>TURN BOLT WITH SWORD
The bolt won't turn using the sword.

>TURN BOLT WITH HANDS
The bolt won't turn using the pair of hands.

>TURN BOLT WITH WRENCH
The bolt won't turn with your best efforts.

I think "TURN BOLT WITH HANDS" should produce the same message as "TURN BOLT".

The switch:

>TURN SWITCH
Your bare hands don't appear to be enough.

>TURN SWITCH WITH SWORD
It seems that a sword won't do.

>TURN SWITCH WITH HANDS
It seems that a pair of hands won't do.

>TURN SWITCH WITH SCREWDRIVER
The machine comes to life (figuratively) with a dazzling display of colored
lights and bizarre noises. After a few moments, the excitement abates.

I think "TURN SWITCH WITH HANDS" should print the same message as "TURN SWITCH".

Still, every object that handles the "TURN" action does work.

eriktorbjorn commented 5 years ago

Here's what I get in Zork II:

Any object that can't be turned acts like in Zork I.

The robot:

>ROBOT, TURN ROBOT
"My programming is insufficient to allow me to perform that task."

>ROBOT, TURN KEY
"Whirr, buzz, click!"
Your bare hands don't appear to be enough.

Actually, I have no idea why the robot even handles the TURN action. The second response is clearly wrong, though.

The key:

>TURN KEY
Your bare hands don't appear to be enough.

>TURN KEY WITH SWORD
The door is locked.

>TURN KEY WITH SWORD
The door is now locked.

>TURN KEY WITH HANDS
The door is now unlocked.

Clearly, the "TURN KEY" response is nonsense. But more seriously, the key wasn't in the lock and I was nowhere near the door when I got the other responses. I need to test this without cheating (I wrote a debug verb to just move the key and some other tools to me), but I do think I just stumbled across another bug...

The menhir:

>TURN MENHIR
Your bare hands don't appear to be enough.

>TURN MENHIR WITH HANDS
The menhir weighs many tons and is eight feet wide. You can't even get a grip on
it, much less move it.

I think "TURN MENHIR" should print the same message as "TURN MENHIR WITH object".

eriktorbjorn commented 5 years ago

Here's what I get in Zork III:

Any object that can't be turned acts like in Zork I.

Telling the Dungeon Master to turn the dial in the endgame:

>MASTER, TURN DIAL
"If you wish," he replies.
Your bare hands don't appear to be enough.

>MASTER, TURN DIAL WITH SWORD
"If you wish," he replies.
The dial face only contains numbers.

>MASTER, TURN DIAL TO 4
"If you wish," he replies.

The first two are, presumably, the same problem as when ordering the robot in Zork II to turn anything.

The dial in the endgame:

>TURN DIAL
Your bare hands don't appear to be enough.

>TURN DIAL WITH SWORD
The dial face only contains numbers.

>TURN DIAL TO 4
The dial now points to 4.

The first message is wrong. It's neither the "You should turn the object to something." message from PRE-TURN, nor the "You must specify what to set the dial to." message from DIAL.

"TURN DIAL WITH SWORD" is presumably interpreted as "TURN DIAL TO SWORD". I don't think that's a problem. At least not if the "TURN DIAL" message is fixed.

The T-bar:

>TURN T-BAR
You should turn the T-bar to something.

>TURN T-BAR WITH SWORD
You can't turn that!

>TURN T-BAR WITH HANDS
You can't turn that!

The response to "TURN T-BAR" is wrong, and the custom message from T-BAR-F is not printed.

Turning the compass rose acts like turning an object that can't be turned. The custom message in ROSE-F is not printed.

The time machine dial:

>TURN DIAL
You should turn the dial to something.

>TURN DIAL WITH SWORD
You can't do that!

>TURN DIAL TO 444
The dial is set to 444.

The response to "TURN DIAL" is correct, but could probably be handled by TM-DIAL-F since it already has a "You have to say what to turn it to!" response.

The second one is a bit nonsensical, but is probably intended as the response to "TURN DIAL TO SWORD".

eriktorbjorn commented 5 years ago

So, to summarize:

The current exceptions in PRE-TURN are wrong and/or incomplete. They block some action functions from handle "TURN", and the exception for DIAL is just plain wrong. DIAL is the action routine (which should really be called DIAL-F or something like that instead). The object is called SUNDIAL.

I'm not sure why we need PRE-TURN at all. Couldn't V-TURN handle all the error cases? If we do need PRE-TURN, it's probably enough that it looks for TURNBIT like it used to. (We'd have to make sure that any object that handles the "TURN" action has that bit.) And the Zork III exceptions look like they could already be handled in the objects's action routines.

We may still have to check if PRSI is equal to ROOMS, though I haven't checked when that actually happens.

"TURN object" and "TURN object WITH HANDS" ought to have the same default error message.