the-infocom-files / ballyhoo Goto Github PK
View Code? Open in Web Editor NEWBallyhoo
Ballyhoo
I wasn't sure if I should report this as a bug or not, but since it seems so easy to fix...
>OPEN BALLOON
You untie the end of the balloon, holding it closed.
>TAKE HELIUM FROM BALLOON
You grab the helium-filled balloon at the frill where it is tied. The balloon
gives a constant upward tug at your fingertips.
This message is supposed to be printed when you first pick up the balloon. See BALLOON-F
:
<COND (<VERB? TAKE>
<FSET ,BALLOON ,TOUCHBIT>
<MOVE ,BALLOON ,PROTAGONIST>
<TELL
"You grab the helium-filled balloon at the frill where it is tied. The
balloon gives a constant upward tug at your fingertips." CR>)
I guess it's printed here because the balloon is PRSI
, and therefore gets the first shot at handling the action. So for the message to work properly, it should either check if the balloon is actually PRSO
, or if the balloon does not yet have TOUCHBIT
. Perhaps the latter would be the more natural way to fix it?
Import the latest release source code from Zarf’s Obsessively Complete Infocom Catalog.
There is this code in OFFICE-OBJECT-F
:
(<AND <EQUAL? ,HERE ,OFFICE>
<VERB? DISEMBARK>>
<DO-WALK ,P?UP>)
This means that the game will always try to walk you up through the ceiling panel when responding to the DISEMBARK
action. But during the end game, you can't even go that way. See UP-OFFICE
when END-GAME
is set:
<ROUTINE UP-OFFICE ()
<COND (<FSET? ,DESK ,RMUNGBIT>
<SETG OFFICE-C 5> ;"this move munrab enters in I-OFFICE"
<CLIMB-PANEL>
<RETURN ,ON-WAGON>)
(,END-GAME
<V-DIG>
<RFALSE>)
(T
<TELL "You're not" ,NOT-REACH "." CR>
<RFALSE>)>>
So in that case it would make more sense to walk west, through the front door. At this point in the game, there's no one to stop you from entering and leaving the office.
This is V-WALK-TO
:
<ROUTINE V-WALK-TO ()
<COND (,PRSO
<COND (<EQUAL? ,PRSO ,INTDIR>
<DO-WALK ,P-DIRECTION>
<RTRUE>)
(T
<V-FOLLOW>)>)
(T
<V-WALK-AROUND>)>>
The purpose seems to be that if you provide a PRSO
(and I don't see how you couldn't), it works like "WALK" if you gave it a direction, and otherwise it works like "FOLLOW". But it doesn't:
>EXAMINE COMRADE THUMB
You see nothing extraordinary about Comrade Thumb (except that he's about two
feet high).
Comrade Thumb flaps his little arms once in frustration, and waddles off into
the darkness.
>WALK TO COMRADE THUMB
Which way did he go? Which way did he go?
>FOLLOW COMRADE THUMB
Beside the Big Top
You're standing next to the big top, which is gently flapping in the warm
breeze.
A cheap plastic clown mask, having been carelessly dropped here, is lying face-
up on the ground.
About waist-high, a barred passage for wild animals extends several yards out
from the big top.
That's because "FOLLOW COMRADE THUMB" is handled by THUMB-F
:
(<VERB? FOLLOW>
<COND (<EQUAL? ,FOLLOW-FLAG 1 10>
<DO-WALK ,P?WEST>)
(<EQUAL? ,FOLLOW-FLAG 2>
<COND (<EQUAL? ,HERE ,BACK-YARD>
<DO-WALK ,P?SOUTH>)
(T
<DO-WALK ,P?WEST>)>)>)>>
When you simply call <V-FOLLOW>
you get the default handler. So it should probably call <PERFORM ,V?FOLLOW ,PRSO>
instead.
There is a global variable called DREAM-C
:
<GLOBAL DREAM-C 0> ;"number of times you ask to be hypnotized"
That may have been its original purpose. The TICKET-CHECK?
routine suggests that you originally only got three attempts at solving the hypnosis puzzle:
<ROUTINE TICKET-CHECK? ("OPTIONAL" (OBJ <>))
<COND (<NOT ,HYP-BOX>
<TELL "\"Ticket, please.\"" CR>
<RTRUE>)
(<OR <FSET? .OBJ ,RMUNGBIT>
<AND <EQUAL? ,PRSA ,V?HYPNOTISE>
<OR <G? ,DREAM-C 3>
,WON-STANDS>>>
<TELL
"With the arrogant self-satisfaction common to members of his profession,
he responds, \"It's been done.\"" CR>
<RTRUE>)
(T
<RFALSE>)>>
(The game uses RMUNGBIT
to flag that Rimshaw has looked at your head and hands.)
But in the final game it's increased when Rimshaw looks at your head and hands. So from what I can understand, DREAM-C
will never ever be greater than 2. So this bit in HYP-F
looks wrong:
(<VERB? GIVE SHOW THROW>
<COND (<PRSO? ,TICKET>
<COND (,HYP-BOX
<COND (<OR <NOT ,WON-STANDS>
<L? ,DREAM-C 4>>
<TELL-WHAT-NOW T>)
(T
<TELL
"\"I have done all that I can do. No more.\"" CR>)>)
(T
<TELL-WHAT-NOW>)>)
You will never get the "I have done all that I can do. No more." message. Perhaps you should, if you've exhausted his services?
When you encounter Comrade Thumb at the drinking fountain, if you wait for him to leave one move passes for each message:
>SCORE
Your score is 0 of a possible 200, in 1 turn.
>WAIT
Time passes...
The little general gets up on his tiptoes in front of the drinking fountain.
>SCORE
Your score is 0 of a possible 200, in 2 turns.
and so on. Until you reach the last one:
>WAIT
Time passes...
The midget looks up at you sadly, then at the drinking fountain.
>SCORE
Your score is 0 of a possible 200, in 5 turns.
>WAIT
Time passes...
Comrade Thumb flaps his little arms once in frustration, and waddles off into
the darkness.
>SCORE
Your score is 0 of a possible 200, in 8 turns.
So the last message did not interrupt the waiting. I noticed this while testing if "FOLLOW COMRADE THUMB" works, and it does. But only if you're quick enough. If you wait like this, you lose your chance.
This is because I-BOOST
returns false here:
(<EQUAL? ,BOOST-COUNTER 6>
<TELL
"Comrade Thumb flaps his little arms once in frustration,">
<BOOST-EXIT>
<RFALSE>)>
Oddly enough, if you wait in another room, Comrade Thumb exiting does interrupt the waiting. This is presumably because BOOST-EXIT
returns true, and so I-BOOST
does as well:
<COND (<EQUAL? ,BOOST-COUNTER 7>
<BOOST-EXIT>)
I think the correct behaviour would be to <RTRUE>
in the first case, and <RFALSE>
in the second. It seemed to work for me when I tried it.
This case in CHUTE-F
...
<COND (<AND <OR <IS-NOUN? ,W?BAR>
<IS-NOUN? ,W?BARS>>
<VERB? EXAMINE>>
<RFALSE>)
... makes the game respond differently if you "EXAMINE BAR" or "EXAMINE BARS", instead of for instance "EXAMINE PASSAGE". I could understand why if the game responded something about the bars, but that's not what happens. Instead the game uses the default code for looking in a container, and since the lions have NDESCBIT
you won't see them. I think.
>FIND SMOOTH LION
It's in the barred passage.
>EXAMINE PASSAGE
Two lions are strolling the length of the barred passage.
>EXAMINE BARS
You can see nothing extraordinary in the barred passage.
I'm not sure what the original intention was here.
This condition in V-CHEAT
looks wrong:
<COND (<IN? ,HERE ,THUMB>
<PERFORM ,V?BET ,GLOBAL-MONEY>
<RTRUE>)
(T
<TELL "You'll need help." CR>
<RTRUE>)>)>
It's checking if HERE
is inside THUMB
, not the other way. So even when Comrade Thumb is hiding under the table, you get this:
>CHEAT AT BLACKJACK
You'll need help.
Changing it to <IN? ,THUMB ,HERE>
you get the expected response:
>CHEAT AT BLACKJACK
[Specify an amount of money, such as: BET 75 CENTS, or BET $1.50.]
PLATFORM-F
has some code to distinguish between "PLATFORM" and "OPPOSITE PLATFORM":
<COND (<IS-ADJ? ,W?OPPOSITE>
<COND (<VERB? WALK-TO THROUGH>
<COND (<OR ,HEADING-EAST?
<EQUAL? ,HERE ,PLATFORM-1>>
<DO-WALK ,P?EAST>)
(<EQUAL? ,HERE ,PLATFORM-2>
<DO-WALK ,P?WEST>)>)
(<TOUCHING? ,PLATFORM>
<CANT-REACH ,PLATFORM>)>)
But it seems that the adjective isn't properly cleared on new commands:
>LOOK
Platform
You're standing on a small, unstable platform which is suspended high above the
arena floor by guy wires converging on it from all directions. A rope ladder
dangles from the platform and the tightrope stretches east to the opposite
platform.
>TOUCH PLATFORM
Fiddling with the platform accomplishes nothing.
>TOUCH OPPOSITE PLATFORM
You're not close enough to the platform.
>TOUCH PLATFORM
You can't reach the platform.
So apparently it still thinks the adjective is "OPPOSITE". This is how IS-ADJ?
is implemented:
<ROUTINE IS-ADJ? (TEST-ADJ)
<COND (<EQUAL? .TEST-ADJ <GET ,P-ADJW 0> <GET ,P-ADJW 1>>
<RTRUE>)
(T
<RFALSE>)>>
From what I understand, P-ADJW
is cleared at the beginning of PARSER
, but one of the entries gets set at the end of GET-OBJECT
. That's about as far as I got before giving up for now.
>UP
As you hoist yourself onto the ladder, the platform buckles with the addition of
your weight. Mahler is spooked, and loses his bundle which falls tragically in
front of your horrified face to the ground below.
Your score is 180 of a possible 200, in 804 turns.
Would you like to start over, restore a saved position, or end this session of
the game? (Type RESTART, RESTORE, or QUIT):
Usually there's a blank line before the score, but not in this particular case which is handled by CLIMB?
:
(<AND <EQUAL? ,APE-LOC 1>
<EQUAL? ,HERE ,RING>>
<SETG APE-LOC 2>
<FCLEAR ,PLATFORM-1 ,TOUCHBIT>
<TELL
"As you hoist " D ,ME " onto the " D ,LADDER ", the platform buckles with the
addition of your weight. " D ,APE " is spooked, and ">
<COND (<NOT <IN? ,NET ,MUNRAB>>
<TELL
"loses his bundle which falls tragically in front of your horrified face
to the ground below.">
<FINISH>)
If you try to follow the crowd from In the Wings, after you've already been to the Connection at least once:
>LOOK
In the Wings
The big top can be entered to the north and exited to the south. To the
northeast, the grandstand begins its precipitous rise.
>FOLLOW CROWD
Which way did he go? Which way did he go?
I don't know if it's worth fixing, but if it is, it should probably simply be a special case in V-FOLLOW
to print "they" instead of "he" or "she". Perhaps.
Sometimes implicit actions are bracketed:
>KILL
[figure of President Taft]
Taft wobbles slightly, revealing himself to be nothing but a cardboard
character, a mere prop.
Other times they are parenthesized:
>OPEN DOOR
(with the crowbar)
You wedge the crowbar between the frame and the door then give it a yank. The
trailer door pops open.
I know of no easy way to find all these instances to compare them, so I'll leave it at that for now.
There are several ways to trigger this bug. I'm using this one because it's one which you can test pretty quickly in the original release. (Spoiler warning: It doesn't happen there.)
>KICK FLASK
Flailing your leg at Dr. Nostrum's Prehydrogenated Genuine Preparation of
Naturally Nitrated
Compound Herbified Extract has no desirable effect.
It's probably because FLASK
is defined like this:
<OBJECT FLASK
(IN LOCAL-GLOBALS)
(DESC
"Dr. Nostrum's Prehydrogenated Genuine Preparation of Naturally Nitrated
Compound Herbified Extract")
ZILF includes the newline in the DESC
property. I guess ZILCH did not.
>LOOK IN CAGE
The confines of the cage are so darkly shaded that you cannot distinguish
anything inside, except for a hoop key ring hanging against the far wall which
happens to be illuminated by a spot of soft light.
>DROP POLE
Dropped.
>TAKE KEYS WITH POLE
You're not holding the fiberglass pole.
>HIT KEYS WITH POLE
You're not holding the fiberglass pole.
>MOVE KEYS WITH POLE
Using the fiberglass pole, you fish the hoop ring off the wall. It slides down
the raised pole and jingles into your hand.
There are three actions that will pick up the key. See TAKE-WITH-POLE?
:
<COND (<AND <FSET? ,PRSO ,TRYTAKEBIT>
<VERB? TAKE-WITH MOVE KILL>
<PRSI? ,POLE>>
This is how they're defined:
<SYNTAX TAKE OBJECT (FIND TAKEBIT) (;CARRIED IN-ROOM MANY)
WITH OBJECT (HELD) = V-TAKE-WITH PRE-TAKE> ;"ADDED BY JO"
<SYNTAX MOVE OBJECT WITH OBJECT = V-MOVE>
<SYNTAX ATTACK OBJECT (FIND ACTORBIT) (ON-GROUND IN-ROOM)
WITH OBJECT (HELD CARRIED HAVE) = V-KILL>
The ZIL manual admits that the parser tokens are "incredibly confusing, and no one really understands them except Stu", but from what I can understand...
HELD
means that the object has to be in the player's inventory, but not in any container.CARRIED
means that the object has to be in the player's inventory, and can be in an open container.HAVE
supposedly controls how the parser responds if you don't have the object, but it didn't seem to make any difference here, so I don't know...Either way, perhaps the MOVE
syntax should be changed to <SYNTAX MOVE OBJECT WITH OBJECT (HELD CARRIED HAVE) = V-MOVE>
instead? They're still inconsistent about the object you're trying to take/move/hit, but that difference is probably even less noticeable.
>SUPERBRIEF
Super-brief descriptions.
>SOUTH
You emerge into the warm night air of summer.
The last of the crowd just now trickles eastward through the turnstile.
A midget decked out in a Russian general's uniform is standing before the
drinking fountain.
>SOUTH
>WEST
>
And so on. Super-brief mode is supposed to print the room's name at least, but here it doesn't. It works in the official release.
I think the problem is in DESCRIBE-ROOM
:
<COND (<IN? ,HERE ,ROOMS>
<COND (<AND <NOT <EQUAL? ,HERE ,TIGHTROPE-ROOM>>
<NOT <ZERO? ,VERBOSITY>>>
<TELL D ,HERE>)>
<SET AV <LOC ,WINNER>>
The VERBOSITY
check appears to be new. The source code for Release 97 is apparently lost, but here's what txd tells me:
Release 97:
L0005: JIN G00,#2b [FALSE] L0007
JE G00,#3e [TRUE] L0006
CALL R0004 (G00) -> -(SP)
L0006: GET_PARENT Gaf -> L03
Relase 99:
L0005: JIN G00,#2b [FALSE] L0007
JE G00,#3e [TRUE] L0006
JZ G3b [TRUE] L0006
CALL R0004 (G00) -> -(SP)
L0006: GET_PARENT Gaf -> L03
So what's special about the tightrope room? Here's what it looks when you step out on the tightrope in release 97, using brief or verbose mode:
>EAST
You are standing, poised high above the arena floor, a couple of baby steps
across the tightrope.
>
Note that it doesn't print any short name of the room.
But in suprierbrief mode, you get nothing:
>EAST
>
Maybe this was a failed attempt at fixing that bug?
This one has been bugging me for years:
>GIVE TICKET TO RIMSHAW
Rimshaw steps nearer, speaking in a very spiritual tone, "I can tell immediately
that you yourself possess great powers of transcendence. It is your eyes which
bespeak your affinity with those mysterious energies that choose to remain
unseen."
He punches your ticket and hands it back. "Whadda you want?"
>RIMSHAW, FEEL MY HEAD
Rimshaw the Incomparable places his fingertips on top of your skull and begins
going carefully over its hills and valleys, pausing occasionally for comment.
"Intelligence: I ascertain you play Infocom games. Personally I enjoyed
"Enchanter" ... Romance: A woman of mysterious beauty will soon come into your
life ... Travel: You will visit the Grand Canyon before the year is out."
With this, Rimshaw gives a perfunctory slap up the side of your head and says,
"End of Session."
>PUT MEAT IN BUCKET
Not in the least bit helpful.
In instead I do this, it keeps working:
>GIVE TICKET TO RIMSHAW
Rimshaw steps nearer, speaking in a very spiritual tone, "I can tell immediately
that you yourself possess great powers of transcendence. It is your eyes which
bespeak your affinity with those mysterious energies that choose to remain
unseen."
He punches your ticket and hands it back. "Whadda you want?"
>RIMSHAW, FEEL MY BUMPS
Rimshaw the Incomparable places his fingertips on top of your skull and begins
going carefully over its hills and valleys, pausing occasionally for comment.
"Intelligence: I ascertain you play Infocom games. Personally I enjoyed
"Enchanter" ... Romance: A woman of mysterious beauty will soon come into your
life ... Travel: You will visit the Grand Canyon before the year is out."
With this, Rimshaw gives a perfunctory slap up the side of your head and says,
"End of Session."
>PUT MEAT IN BUCKET
Done.
Very weird, considering "MY HEAD" and "MY BUMPS" should refer to the same object:
<OBJECT HEAD
(IN GLOBAL-OBJECTS)
(DESC "your head")
(SYNONYM HEAD SKULL BUMP BUMPS)
(ADJECTIVE YOUR MY)
(FLAGS NARTICLEBIT)
(ACTION HEAD-F)>
This looks like a grammatical error to me.
>LEAVE SHORT LINE
You hesitate momentarily, as your line has appears to be about to move.
I.e. I think it should be "line appears to", not "line has appears to". This is printed by V-DISEMBARK
:
<COND (<EQUAL? ,LINE-COUNTER 2 3>
<TELL
"You hesitate momentarily, as your line has appears to be about to move." CR>
<RTRUE>)>
In APE-ROOM
, the EAST
and OUT
exits do not behave the same way:
(EAST PER APE-ENTER)
(OUT TO MEN IF APE-DOOR IS OPEN)
The difference is that APE-ENTER
will let you through regardless of the door during the end game:
<ROUTINE APE-ENTER ()
<COND (<OR ,END-GAME
<FSET? ,APE-DOOR ,OPENBIT>>
<COND (<EQUAL? ,HERE ,APE-ROOM>
<RETURN ,MEN>)
(T
<RETURN ,APE-ROOM>)>)
(T
<TELL "The " D ,APE-DOOR " is ">
<OPEN-CLOSED ,APE-DOOR>
<TELL ,PERIOD>
<RFALSE>)>>
This is because in the end game, Mahler has bent open the bars and escaped from his cage.
I guess you could argue that "OUT" implies going through the door, but the description of Inside Mahler's Cage says that the door "is east". So I think it's just an oversight, and that both should use PER APE-ENTER
.
CHEESE-F
contains the following code:
(<AND <TOUCHING? ,CHEESE>
<NOT <FSET? ,TRAP ,RMUNGBIT>>
<IN? ,CHEESE ,TRAP>>
<RASH-ACT>)
(<AND <VERB? TAKE>
<IN? ,CHEESE ,TRAP>
<NOT <FSET? ,TRAP ,RMUNGBIT>>
<EQUAL? <ITAKE> T>>
<TELL
"With great care, you take the cheese." CR>)
Since the TAKE
action is handled by TOUCHING?
, the "With great care..." message is never printed. I'm not sure that counts as a bug, though...
>PUT TICKET UNDER FRONT
The ticket disappears under the plywood and moments later a secret panel in the
old sideshow front slides open.
>CLOSE PANEL
>CLOSE PANEL
The spring-loaded secret panel slides shut.
The game relies on the panel sliding shut automatically, printing the appropriate message. So all that BLUE-DOOR-F
does is to intercept the action and print nothing. Like this:
(<AND <VERB? CLOSE>
<FSET? ,BLUE-DOOR ,OPENBIT>>
<RTRUE>)>>
But if the panel isn't actually about the close on the next move, you'll get no message at all, like above.
There's this line in I-JOEY
:
OH<SETG FOLLOW-FLAG 4>
The "OH" seems to serve no purpose.
Here is a rough partial map of the Midway area:
+--------------------+ +-----------------------+
| Hypnotist's Parlor | | West Half of Fat Lady |
| PARLOR | | FAT-EAST |
+--------------------+ +-----------------------+
| |
+-----------------+ +------------------+ +-------------------+
| Midway Entrance |--| Midway of Midway |--| Far End of Midway |
| MIDWEST | | MID | | MIDEAST |
+-----------------+ +------------------+ +-------------------+
|
+-------------------+
| Jennifer's Budoir |
| BUDOIR |
+-------------------+
And here is the part of FRONT-F
that describes the sideshow front:
<COND (<VERB? EXAMINE READ>
<TELL "The " D ,FRONT>
<COND (<EQUAL? ,HERE ,MIDWEST>
<TELL " heralding the charms of Tina is">)
(<EQUAL? ,HERE ,NOOK ,MIDEAST>
<TELL " is">)
(T
<TELL "s are">)>
<COND (<EQUAL? ,HERE ,NOOK>
<TELL " warped and faded beyond recognition." CR>
<RTRUE>)
(T
<TELL
" an eyeful of dazzling, flamboyant artwork similar to that represented
in the circus program along with glowing introductions of the performers. ">
<COND (<EQUAL? ,HERE ,MID>
<TELL "Each ">)
(T
<TELL "The ">)>
<TELL "front has a small entrance." CR>)>)
The front is visible from the following rooms:
Room | Description |
---|---|
MIDWEST |
The sideshow front heralding the charms of Tina is an eyeful of dazzling, flamboyant artwork similar to that represented in the circus program along with glowing introductions of the performers. The front has a small entrance. |
MID |
The sideshow fronts are an eyeful of dazzling, flamboyant artwork similar to that represented in the circus program along with glowing introductions of the performers. Each front has a small entrance. |
MIDEAST |
The sideshow front is an eyeful of dazzling, flamboyant artwork similar to that represented in the circus program along with glowing introductions of the performers. The front has a small entrance. |
NOOK |
The sideshow front is warped and faded beyond recognition. |
So the front at MIDWEST
is "heralding the charms of Tina", even though the entrance to her place is at MIDEAST
.
Actually, the description of MIDWEST
doesn't even mention any sideshow fronts, so if they are described at all in this room it should probably be a general description, like "The sideshow fronts are an eyeful of dazzling, flamboyant artwork similar to that represented in the circus program along with glowing introductions of the performers." I.e. it should say "fronts" not "front" (like in MID
) and not mention any entrance at all.
If you look up in the Elephant Tent, you can see the burn holes if there are any. See V-LOOK-UP
:
(<AND <EQUAL? ,HERE ,BULL-ROOM>
<NOT <FSET? ,BURN-HOLE ,INVISIBLE>>>
<TELL ,YOU-SEE " " D ,BURN-HOLE "s." CR>)
The holes are made visible in I-POKE
:
<FCLEAR ,BURN-HOLE ,INVISIBLE>
<TELL
"Suddenly, and with a muffled \"pop,\" a sleek metal shaft is thrust
upward through the canvas. ">
But since the holes are never made INvisible, you can see the burn holes at any point in the game after the elephant is gone:
<OBJECT BURN-HOLE
(IN LOCAL-GLOBALS)
(DESC "burn hole")
(SYNONYM HOLE HOLES)
(ADJECTIVE BURN)
(FLAGS NDESCBIT)
(ACTION BURN-HOLE-F)>
It should be enough to simply add INVISIBLE
to the FLAGS
property.
It looks like UP-STAIRS
is meant to print a longer message the first time Andrew blocks your way up, and a shorter on subsequent attempts:
<COND (<IN? ,ANDREW ,HERE>
<TELL D ,ANDREW>
<COND (<NOT <FSET? ,STAIRCASE ,RMUNGBIT>>
<TELL
" goose-steps to a position in front of the " D ,STAIRCASE ", dragging
Jenny's high heel across the ground. There " D ,ANDREW>)
(T
<FSET ,STAIRCASE ,RMUNGBIT>)>
<TELL
" stands blocking your way up. Stiffly, he pats his holster a couple of times
and you hear its leather crinkle." CR>
<RFALSE>)
But it doesn't work that way, because it only sets RMUNGBIT
on STAIRCASE
if it has already set that bit. Which never happens, so you get the longer message every time:
>UP
Andrew goose-steps to a position in front of the spiral staircase, dragging
Jenny's high heel across the ground. There Andrew stands blocking your way up.
Stiffly, he pats his holster a couple of times and you hear its leather crinkle.
>UP
Andrew goose-steps to a position in front of the spiral staircase, dragging
Jenny's high heel across the ground. There Andrew stands blocking your way up.
Stiffly, he pats his holster a couple of times and you hear its leather crinkle.
You can "HELP COMRADE THUMB" at the start of the game, to let him drink from the fountain:
>LOOK
Connection
This area of matted-down crabgrass lies between the vaulted big top entrance to
the north and the enticements of the midway to the east, where a sagging banner
hangs crookedly above a turnstile. There is a drinking fountain near the side
wall of the tent. You can enter the night to the west and south.
The little general gets up on his tiptoes in front of the drinking fountain.
>HELP COMRADE THUMB
Once elevated, Comrade Thumb slurps his fill of water. He then plops down, gives
you a quick salute, and waddles off into the darkness.
However, V-SAVE-SOMETHING
doesn't actually check who you are trying to help. Only that Comrade Thumb is there, and he's trying to get a drink:
<COND (<AND <RUNNING? ,I-BOOST>
<IN? ,THUMB ,HERE>>
<PERFORM ,V?RAISE ,THUMB>
<RTRUE>)
So it will accept a lot of nonsense commands, e.g.:
>HELP THE FUTURE
Once elevated, Comrade Thumb slurps his fill of water. He then plops down, gives
you a quick salute, and waddles off into the darkness.
It should probably check <PRSO? ,THUMB>
as well.
>PUT MOUSETRAP AND VEIL ON LION STAND
mousetrap: Done.
veil: Done.
>SEARCH LION STAND
You can see a veil and a mousetrap.
>STAND ON LION STAND
You are now on the lion stand.
>SEARCH LION STAND
a veil and a mousetrap.
>GET VEIL AND MOUSETRAP
veil: Taken.
mousetrap: Taken.
>SEARCH STAND
It's empty (not counting you).
Printing " a veil and a mousetrap." doesn't look very nice to me. V-SEARCH
handles this case by calling DESCRIBE-VEHICLE
:
<ROUTINE DESCRIBE-VEHICLE () ;"for LOOK AT vehicle when you're in it"
<MOVE ,PROTAGONIST ,ROOMS>
<COND (<FIRST? ,PRSO>
<PRINT-CONTENTS ,PRSO>
<TELL ,PERIOD>)
(T
<TELL ,EMPTY " (not counting you)." CR>)>
<MOVE ,PROTAGONIST ,PRSO>>
Compare this to how the stand is described when you're not inside it:
(<AND <FIRST? ,PRSO>
<NOT <FSET? <FIRST? ,PRSO> ,NDESCBIT>>>
<TELL ,YOU-SEE>
<PRINT-CONTENTS ,PRSO>
<TELL ,PERIOD>
I.e. it prints YOU-SEE
first. Maybe DESCRIBE-VEHICLE
should do the same? It's called in a few other places that I haven't yet investigated.
There is a somewhat cartoonish "puzzle" where you ask the guard about the missing girl. He will insist that you already asked, like so:
>ASK THE GUARD ABOUT THE GIRL
"But you already asked me about her, right?"
>DID NOT
"Of course you did now, didn't you?"
>DID NOT
"Did so."
>DID SO
"Did not ... Er, um ... Well, I guess I didn't answer that question before. All
I can say is that I haven't seen the kid all evening."
The way this is implemented, when you ask the guard about the girl it will set AWAITING-REPLY
to 6 and start the I-DID
timer. Usually AWAITING-REPLY
is cleared by I-REPLY
, but this scene is one of the exceptions. The timer keeps running until either:
YES
or NO
. In this case, the game clears AWAITING-REPLY
. See I-DID
.AWAITING-REPLY
. See V-YES
.So there are two problems I can see here:
The AWAITING-REPLY
reply flag is not cleared when you solve the puzzle. The timer isn't even stopped, though it will be stopped by I-DID
as soon as you use another action than YES
or NO
. Like this:
>DID SO
"Did not ... Er, um ... Well, I guess I didn't answer that question before. All
I can say is that I haven't seen the kid all evening."
>DID NOT
"Did so."
>JUMP
Your feet barely leave the ground.
>DID NOT
You sound rather negative.
But if you agree too soon, the timer is stopped and AWAITING-REPLY
isn't cleared. So now there's nothing to clear that flag until you trigger some other event in the game that uses the flag. So now the guard will answer even if you're no longer in the same room:
>ASK THE GUARD ABOUT GIRL
"But you already asked me about her, right?"
>YES
"Thought you'd see it my way."
>EAST
Near White Wagon
You are standing on a gentle upslope of the grassy field, next to a rather
imposing trailer whose door is closed to the east. In dark panorama, the field
continues north and west -- and south, where a large banner has been erected.
Part of a narrow pole is sticking out from under the wagon.
>NO
"Of course you did now, didn't you?"
A trivial change to V-YES
should take care of both. This is what the code looks like now:
(<EQUAL? ,AWAITING-REPLY 6>
<COND (<NOT <EQUAL? ,DID-C 0>>
<FSET ,PROTAGONIST ,RMUNGBIT>
<TELL
"\"Did not ... Er, um ... Well, I guess I didn't answer that question
before. All I can say is that I haven't seen the kid all evening.\"" CR>)
(T
<TELL "\"Thought you'd see it my way.\"" CR>
<SETG DID-C 0>
<DISABLE <INT I-DID>>)>)
One feature I really like about Infocom games is that they (usually) make sure that "it" refers to something sensible. For instance, if the game tells you that the door you just tried to go through is closed, it usually sets "it" to mean the door.
For ordinary door exits, this would be handled by V-WALK
itself:
<RFATAL>)>)
(<EQUAL? .PTS ,DEXIT>
<COND (<FSET? <SET OBJ <GETB .PT ,DEXITOBJ>> ,OPENBIT>
<GOTO <GETB .PT ,REXIT>>)
(<SET STR <GET .PT ,DEXITSTR>>
<TELL .STR CR>
<SETG P-IT-OBJECT .OBJ>
<RFATAL>)
(T
<TELL "The " D .OBJ " is closed." CR>
<SETG P-IT-OBJECT .OBJ>
<RFATAL>)>)>)
(For some reason, this game does not have any THIS-IS-IT
routine, so it sets P-IT-OBJECT
directly.)
But for Mahler's cage, this doesn't work:
>EXAMINE CHEESE
You see nothing unusual about the cheese morsel.
>WEST
The cage door is closed.
>OPEN IT
You can't open a cheese morsel.
That's because APE-ENTER
doesn't set P-IT-OBJECT
:
(T
<TELL "The " D ,APE-DOOR " is ">
<OPEN-CLOSED ,APE-DOOR>
<TELL ,PERIOD>
<RFALSE>)>>
>PUT CLOWN MASK IN BUCKET
Done.
>WEAR CLOWN MASK
You put on the clown mask.
>FIND CLOWN MASK
It's in the bucket.
>DROP CLOWN MASK
You'll have to remove it first.
The syntax for the "WEAR" command is defined like this:
<SYNTAX WEAR OBJECT (FIND WEARBIT) (HAVE) = V-WEAR PRE-WEAR>
HAVE
is supposed to mean that the object has to be "in the player's inventory", but I guess it still includes objects inside containers in your inventory? I think I have already reported this bug in some other game.
<ROUTINE BLIND-SIDE ()
<JIGS-UP 2
"You are suddenly blindsided in a lightning attack lead by claws which sink
deep into your jugular.">
<RTRUE>>
To me, it feels like it should be "led by", not "lead by". Of course, all the usual caveats that I'm not a native English speaker apply here. Perhaps more so than usually.
If you release the lions again after you trap them, the game refers to Nimrod by name:
>OPEN GRATE
With the force and brightness of a supernova, Nimrod's mane suddenly bursts from
the dark passage.
**** You have died ****
The message is printed by GRATE-F
:
<COND (<IN? ,ELSIE ,CHUTE>
<COND (<VERB? OPEN RAISE>
<JIGS-UP 2
"With the force and brightness of a supernova, Nimrod's mane suddenly
bursts from the dark passage.">)
You could argue that at this point, you've deduced which lion is which. But if you try to examine Nimrod from Beside the Big Top you're still told you don't know:
>EXAMINE NIMROD
You glance at each lion and realize that, because you were outside the big top
stuck waiting in line when the lions were introduced, you're not certain who is
who. You'll have to refer to each as the shaggy lion or the smooth-bodied lion.
Though I'm not sure this is the kind of bug we should fix...?
During the endgame, when everyone is busy holding the safety net, you're probably not supposed to be able to interact with the circus performers in any meaningful way. But Rimshaw will still take time out to read your palm:
>RIMSHAW, READ MY PALM
You're hardly recognized above the commotion.
>GIVE HAND TO RIMSHAW
Rimshaw the Incomparable takes your hand and studies the palm lines with the
intensity of a cartographer, finally saying in a dramatic whisper, "Tonight you
have an appointment with destiny."
Munrab & Company, their faces anxiously upturned, are pulling the safety net
every which way, kicking sawdust from one end of the ring to the other.
Perhaps you shouldn't be able to do that? If so, it's probably the <VERB? GIVE SHOW THROW>
case in HYP-F
that needs to be fixed. Maybe by checking if you're in PARLOR
or not.
Build the game using the ZILF toolset. Eliminate compilation and startup errors where necessary.
GLOBAL-ROOM-F
has a special case for "ENTER RING":
(<VERB? THROUGH WALK-TO ENTER>
<COND (<AND <PRSO? ,RING>
<EQUAL? ,HERE ,WINGS>>
<DO-WALK ,P?NORTH>)
This doesn't work as intended, though:
>ENTER RING
Did you have any particular direction in mind?
Changing RING
to RING-OBJECT
fixes that, though you still have a problem if you're carrying the key ring:
>ENTER RING
That would involve quite a contortion.
I thought it would be possible to fix that with a GENERIC
routine, but apparently not.
When Rimshaw hypnotizes you, if you attack Jerry and one other team member, and then do it again, you will get yourself "killed":
>KILL GROUP
The second baseman steps in between. "This clown giving you trouble?" Then the
shortstop backs you off with a nasty stare.
Jerry continues glad-handing the shortstop.
>KILL JERRY
The first baseman steps in between. "This clown giving you trouble, Jerry?" Then
the center fielder backs you off with a nasty stare.
Jerry continues ribbing the shortstop.
>KILL JERRY
With the ensuing rhubarb, you end up on the permanently disabled list.
**** You have died ****
Well not quite died. The doctors do what they can, but as the debts rise and the
prognosis dips you take the only avenue left -- and sell yourself to the circus.
As "The Human Armadillo," you enjoy top billing as a popular midway attraction,
garnering fame to rival that of nineteenth century oddity John Merrick.
Still, as the fingers of the Great Unwashed poke at your benumbed hide, you
contemplate how this fate might have been thwarted.
Your score is 30 of a possible 200, in 144 turns.
The FIGHT
routine handles this:
<COND (<AND <FSET? ,JERRY ,RMUNGBIT>
<FSET? ,TEAM ,RMUNGBIT>>
<JIGS-UP 5
"With the ensuing rhubarb, you end up on the permanently disabled list.">)
This doesn't really make sense to me, because you are in a flashback. If I had been a tester at Infocom at the time (wishful thinking!) I would have suggested that it should wake you up from the hypnosis instead.
But I think it's much too late to fix that now, and you do have to make an effort to get this ending.
When hannibal stampedes through the fence, the game will clear TOUCHBIT
on MEN
(the menagerie room) and NEAR-WAGON
. This is presumably so that the next time you enter the room, you will see the hole in the fence even if you're playing in brief mode. (If you are playing in superbrief mode, you're obviously a glutton for punishment and deserve to be kept in the dark about these things!)
However, it only does this if you are there to witness the stampede, i.e. when it's needed the least. See I-BULL
:
<SETG SCORE <+ ,SCORE 10>>
<MOVE ,BULL ,LOCAL-GLOBALS>
<COND (<EQUAL? ,HERE ,MEN ,APE-ROOM>
<FCLEAR ,MEN ,TOUCHBIT>
<FCLEAR ,NEAR-WAGON ,TOUCHBIT>
<ENABLE <QUEUE I-FOLLOW 2>>
<SETG FOLLOW-FLAG 12>
<TELL CR
"Loudly trumpeting its frustration, Hannibal of the Jungle thunders
out of the tent, shearing its " D ,CHAIN " with a dull thud. The raging
bull stampedes ">
<COND (<EQUAL? ,HERE ,APE-ROOM>
<TELL "past you and ">)>
<TELL "through a fence to the southwest." CR>)>
<RTRUE>)
Wouldn't it make more sense to always clear these bits when the elephant stampedes? I mean, the game is clearly trying to draw your attention to something new that happened to the room.
Once you've gotten Tina's attention ("...and cranes her wrecking-ball-sized hand over to you"), "SHAKE HANDS" and "SHAKE HANDS WITH TINA" don't produce the same result:
>SHAKE TINA'S HAND
As you take hold, the fat lady's hand becomes relaxed, its full weight now
residing in your arms like a sandbag and making your knees buckle.
The fat lady appears quite taken by your kindnesses. She clasps both her hands
up to her chins, and stares ahead in teary silence.
>SHAKE HANDS WITH TINA
As you take hold, the fat lady's hand becomes relaxed, its full weight now
residing in your arms like a sandbag and making your knees buckle.
Even worse, if you've already taken her hand:
>TAKE TINA'S HAND
As you take hold, the fat lady's hand becomes relaxed, its full weight now
residing in your arms like a sandbag and making your knees buckle.
>SHAKE HANDS WITH TINA
You already have it.
"SHAKE TINA'S HAND" is handled by FAT-HAND-F
:
(<VERB? SHAKE>
<COND (<HELD? ,FAT-HAND>
<TELL
"Though unable to budge the " D ,FAT-HAND ", your friendly intentions
are nevertheless understood. ">
<WIN-FAT>
<RTRUE>)
(,HANDOUT
<PERFORM ,V?TAKE ,FAT-HAND>
<COND (<IN? ,FAT-HAND ,PROTAGONIST>
<CRLF>
<WIN-FAT>
<RTRUE>)>)
(T
<TELL ,NOT-HOLDING " " D ,FAT-HAND "." CR>)>)
You're not holding her hand, but HANDOUT
is true. So you take the hand, and if that succeeds (I don't see why it wouldn't) you immediately solve the puzzle (WIN-FAT
).
("SHAKE HANDS" works too, but I think that would first go through HANDS-F
.)
"SHAKE HANDS WITH TINA" is handled by FAT-F
:
(<AND <VERB? SHAKE-WITH>
<PRSO? ,HANDS>>
<PERFORM ,V?TAKE ,FAT-HAND>
<RTRUE>)
I don't see why these two actions should produce different results. Perhaps FAT-F
should call <PERFORM ,V?SHAKE ,FAT-HAND>
instead? If I make that change...
>SHAKE HANDS WITH TINA
As you take hold, the fat lady's hand becomes relaxed, its full weight now
residing in your arms like a sandbag and making your knees buckle.
The fat lady appears quite taken by your kindnesses. She clasps both her hands
up to her chins, and stares ahead in teary silence.
>TAKE TINA'S HAND
As you take hold, the fat lady's hand becomes relaxed, its full weight now
residing in your arms like a sandbag and making your knees buckle.
>SHAKE HANDS WITH TINA
Though unable to budge the fat lady's hand, your friendly intentions are
nevertheless understood. The fat lady appears quite taken by your kindnesses.
She clasps both her hands up to her chins, and stares ahead in teary silence.
So it looks like it would work.
This bit in CEILING-F
...
<COND (<AND <EQUAL? ,HERE ,ON-WAGON>
<IN? ,MUNRAB ,ON-WAGON>>
<PERFORM ,V?KNOCK ,OFFICE-DOOR>
<RTRUE>)
means that anything you try to do to the ceiling while on the wagon, and Munrab is present (actually, from a story point of view he's in his trailer and it's only from an implementation point of view that he's on top of it) will be the same as knocking on the door:
>HYPNOTIZE CEILING
Below you Mr. Munrab very cautiously steps outside and begins poking around,
closing the door behind him. He wanders into the darkness.
This seems a bit strange to me, but I'm not sure which verbs should actually trigger the action.
This bug report will list objects I find that should perhaps have TRYTAKEBIT
to prevent implicit taking. The simplest way I've found to test verify that an object can be implicitly taken is "CLOSE OFF object".
Object | Comment |
---|---|
BALLOON |
Has a custom message for being picked up for the first time. Implicit taking bypasses that, but probably does no other harm. |
TRAP |
Otherwise you can bypass the whole bit where you set off the trap accidentally. |
MEAT |
Otherwise you can get the meat from Beside the Big Top while the lions are eating it. (The meat is then removed from your inventory when the lions finish.) |
PROD |
The game acts on you explicitly taking it, but doesn't notice if you take it implicitly. It doesn't break the puzzle, but still... |
HEADPHONES |
Or you can snatch the headphones from Mahler without him noticing you did it. (He will notice that the music has stopped, though.) Fixing this would need some testing, because there is code in CAGE-F that checks if the headphones have TRYTAKEBIT . Currently that never happens, as far as I can tell. See also #64 |
THUMB |
Otherwise you can pick up Comrade Thumb even in cases when you shouldn't be able to, e.g. during the endgame. If you're feeling cruel, you can then drop him from the tightrope. (He's too big to feed to the lions.) |
I don't know if this qualifies as a bug, but it looks like you were meant to be able to ask Rimshaw to hypnotize you without explicitly handing him the ticket first, as long as you are holding the ticket. See HYP-F
:
(<AND <EQUAL? ,WINNER ,HYP>
<VERB? HYPNOTISE>
<EQUAL? ,PRSO ,ME>
<HELD? ,TICKET>>
<CRLF> <CRLF>
<TELL-WHAT-NOW <> T>
<CRLF> <CRLF>
<PERFORM ,V?HYPNOTISE ,ME>
<RTRUE>)
However, it won't work because <HELD? ,TICKET>
checks if the WINNER
is holding the ticket, and I don't think Rimshaw ever actually does that. Though changing it to <HELD? ,TICKET ,PROTAGONIST>
doesn't quite work, because then there is a missing quotation mark after "unseen."
>RIMSHAW, HYPNOTIZE ME
Rimshaw steps nearer, speaking in a very spiritual tone, "I can tell immediately
that you yourself possess great powers of transcendence. It is your eyes which
bespeak your affinity with those mysterious energies that choose to remain
unseen.
He punches your ticket and hands it back.
You settle into the tufted leather sofa and Rimshaw the Incomparable approaches
you purposefully. Poised in front of you, the hypnotist points both of his
hands' tension-filled fingers at you and commands, "RE-LAX!!! Now count backward
slowly from 100."
With transcendental calm you begin mouthing the words one hundred, ninety-nine,
ninety-eight ...
Your mind begins to drift back, back, back into the most recently forgotten past
...
Standing Room Only
You're in the "blues," sitting high above the arena floor. You know the exit
from the grandstand to be vaguely eastward and down. All around you the crowd is
in a state of pandemonium.
Easily fixed, of course, but maybe it's better to leave it as it is, since it's inconsistent with the other services he provides?
Often, games will reuse the same routine for multiple actions, if the response is generic enough. For instance, this is V-COUNT
:
<ROUTINE V-COUNT ()
<TELL <PICK-ONE ,IMPOSSIBLES> CR>>
This is then called by other routines like V-DRINK-FROM
, V-DRIVE
, etc. Also from V-INHALE
:
<ROUTINE V-INHALE ()
<COND (<PRSO? ,AIR>
<TELL "Deep-breathing -- good for the health." CR>)
(T
<V-COUNT>)>>
It turns out that V-INHALE
is also used by other verb routines:
V-CLIMB-UP
(V-CLIMB-DOWN
calls V-COUNT
instead.)V-CUT
V-POUR
V-THROUGH
V-UNTIE
V-WAVE
(Also ITAKE
, but it makes sense there, I guess.)
That means that you can get unexpected responses from the game:
>CLIMB UP AIR
Deep-breathing -- good for the health.
>CUT AIR
Deep-breathing -- good for the health.
>POUR AIR
Deep-breathing -- good for the health.
>UNTIE AIR
Deep-breathing -- good for the health.
>WAVE AIR
Deep-breathing -- good for the health.
(I can't find any way to trigger it from V-THROUGH
.)
Perhaps these should call V-COUNT
instead, just like V-CLIMB-DOWN
already does, to avoid the special case in V-INHALE
?
>LOOK
You are standing, poised high above the arena floor, a couple of baby steps
across the tightrope.
>DROP MOUSE
It falls to the ground below.
The mouse will still be in the Performance Ring (though it's described as "You can hear faint scurryings of a rodent somewhere in the tent.") when you get down, and it can be picked up.
Usually, when you drop the mouse this happens:
>DROP MOUSE
The mouse scampers out of your hand, hits the ground running and darts out of
sight.
Dropping objects form the tightrope is handled in IDROP
, but there's currently no special case for the mouse:
(<AND <EQUAL? ,HERE ,TIGHTROPE-ROOM>
<NOT <PRSO? ,BALLOON ,WATER>>
<NOT <EQUAL? ,PRSI ,PLATFORM ,BUCKET ,DRESS>>
<NOT <VERB? GIVE>>
<NOT <FSET? ,PRSO ,WORNBIT>>>
<MOVE ,PRSO ,RING>
<COND (<AND <PRSO? BUCKET>
<IN? ,WATER ,BUCKET>>
<MOVE ,WATER ,LOCAL-GLOBALS>)>
<TELL "It falls">
<COND (<OR <IN? ,NET ,RING>
<IN? ,NET ,MUNRAB>>
<TELL
", luckily for the sake of whoever may later dive into the net,">)>
<TELL " to the " D ,GROUND " below." CR>)
Perhaps simply move the mouse silently to LOCAL-GLOBALS
in this case, i.e. it falls down and runs off when you're not looking.
This is how the performance ring is described:
>LOOK
Performance Ring
This is the arena's oval-shaped performance ring which is occupied by a sagging,
rectangular safety net. A rope ladder dangles to within a foot of the ground.
Just west lies the entrance to a large, round cage that completely encircles the
second of the two rings. To the south the big top's vaulted wing leads out into
the open air. The arena's rickety grandstands rise steeply north and east.
There is a single RING-OBJECT
that apparently represents both of the rings. It has the following action routine:
<ROUTINE RING-OBJECT-F ()
<COND (<IS-NOUN? ,W?SECOND>
<PERFORM ,PRSA ,LION-CAGE ,PRSI>
<RTRUE>)
(T
<GLOBAL-ROOM-F>)>>
I'm guessing the idea here is that if you refer to the "ring" or the "performance ring", you mean the current room, but if you explicitly refers to the "second ring", that's the lion cage. Except it doesn't work because the noun will still be "ring", not "second".
Changing <IS-NOUN? ,W?SECOND>
to <IS-ADJ? ,W?SECOND>
seems to fix that, though of course we'd have to check to make sure that doing this doesn't allow you to to interact with the lion cage in ways you shouldn't be able to.
If you ask the pitchman about anything, he'll try to steer the conversation to Dr. Nostrum's extract instead.
>ASK PITCHMAN ABOUT MUNRAB
"I don't know much about that," he says. "But have you asked me about Dr.
Nostrum's Prehydrogenated Genuine Preparation of Naturally Nitrated
Compound Herbified Extract?"
At that point he'll respond to "YES", "NO" and "PITCHMAN, YES":
>YES
Well then scram."
>PITCHMAN, YES
"Well then scram."
>NO
He takes a deep breath. "Well, brother, step right up -- I don't care what's
your sickness, I don't care what's draggin' you down, don't tell me 'cause I
don't want to know whether it's pyorrhea, anorexia nervosa, sick headache,
goiter, varicose veins, bilious derangements, nervous debility ..." The pitchman
realizes he's getting nowhere with you and turns his attention back to the
detective.
But PITCHMAN, NO
does not work:
>PITCHMAN, NO
He just grins, revealing a gold tooth.
It's obviously meant to work. CON-F
does this:
(<AND <VERB? YES>
<EQUAL? ,AWAITING-REPLY 8>>
<V-YES>)
(<AND <VERB? NO>
<EQUAL? ,AWAITING-REPLY 8>>
<V-NO>)
(T
<TELL "He just grins, revealing a gold tooth." CR>)>)
But it probably fails because V-NO
does this:
(<AND <EQUAL? ,AWAITING-REPLY 8>
<IN? ,CON ,HERE>>
<PERFORM ,V?ASK-ABOUT ,CON ,FLASK>
<RTRUE>)
So WINNER
is probably still the pitchman, i.e. this would be equivalent to "PITCHMAN, ASK PITCHMAN ABOUT FLASK", not "ASK PITCHMAN ABOUT FLASK".
Temporarily setting WINNER
to PROTAGONIST
(like in the "PITCHMAN, HELLO" case) fixes the problem. Either in CON-F
or V-NO
.
When in the Lions' Den:
>ENTER LION CAGE
Look around you.
>
When in the Performance Ring:
>LEAVE LION CAGE
Look around you.
>
I.e. there's no blank line before the prompt. (As usual, that looks much worse in superbrief mode, because then the new prompt will appear at the end of the message, not on a new line by itself.)
That's becaues LION-CAGE-F
uses <TELL ,LOOK-AROUND>
where it should use <TELL ,LOOK-AROUND CR>
:
(<VERB? BOARD ENTER THROUGH>
<COND (<EQUAL? ,HERE ,RING>
<DO-WALK ,P?WEST>)
(T
<TELL ,LOOK-AROUND>)>)
(<VERB? LEAVE EXIT DISEMBARK>
<COND (<EQUAL? ,HERE ,DEN>
<DO-WALK ,P?EAST>)
(T
<TELL ,LOOK-AROUND>)>)>>
(You can actually find a correct example earlier in the same routine.)
The classic bug returns...
>LOOK
Platform
You're standing on a small, unstable platform which is suspended high above the
arena floor by guy wires converging on it from all directions. A rope ladder
dangles from the platform and the tightrope stretches east to the opposite
platform.
>EXAMINE HANDS
Your lifeline is very short.
>THROW HANDS OFF PLATFORM
It falls to the ground below.
>EXAMINE HANDS
[You can't see any hands here.]
>TOUCH HEAD
You feel the bumps but lack the interpretive skills of the phrenologist.
>THROW HEAD OFF PLATFORM
It falls to the ground below.
>TOUCH HEAD
[You can't see any head here.]
V-THROW-OFF
doesn't check for this, and IDROP
(called by PRE-THROW
) only makes an exception for some actions:
(<PRSO? ,HANDS ,BACK ,HELIUM ,HEAD>
<COND (<OR <VERB? DROP THROW GIVE>
<AND <PRSO? ,BACK ,HELIUM ,HEAD>
<VERB? PUT PUT-ON>>>
<V-COUNT>)
(T
<RFALSE>)>)
I guess it should add THROW-OFF
to that list of actions?
GLOBAL-NET-F
handles "PUT object IN NET" like this:
(<AND <VERB? PUT>
<PRSI? ,GLOBAL-NET>>
<PERFORM ,V?DROP ,PRSO>
<RTRUE>)
Which works fine while balancing on the tightrope:
>LOOK
You are standing, perched precariously high above the arena floor, a couple of
baby steps across the tightrope.
>PUT MASK IN NET
It falls, luckily for the sake of whoever may later dive into the net, to the
ground below.
But not so well when you're standing on the platform:
>LOOK
Platform
You're standing on a small, unstable platform which is suspended high above the
arena floor by guy wires converging on it from all directions. A rope ladder
dangles from the platform and the tightrope stretches east to the opposite
platform.
>PUT MASK IN NET
Dropped.
The "It falls ..." message is printed by IDROP
:
(<AND <EQUAL? ,HERE ,TIGHTROPE-ROOM>
<NOT <PRSO? ,BALLOON ,WATER>>
<NOT <EQUAL? ,PRSI ,PLATFORM ,BUCKET ,DRESS>>
<NOT <VERB? GIVE>>
<NOT <FSET? ,PRSO ,WORNBIT>>>
<MOVE ,PRSO ,RING>
<COND (<AND <PRSO? BUCKET>
<IN? ,WATER ,BUCKET>>
<MOVE ,WATER ,LOCAL-GLOBALS>)>
<TELL "It falls">
<COND (<OR <IN? ,NET ,RING>
<IN? ,NET ,MUNRAB>>
<TELL
", luckily for the sake of whoever may later dive into the net,">)>
<TELL " to the " D ,GROUND " below." CR>)
Though extending this condition to cover "PUT object IN NET" seems a bit messy to me, so I don't know...
There is a V-YOU-ARE-OBJECT
routine that is a bit mysterious:
<SYNTAX YOU = V-YOU-ARE-OBJECT>
<SYNTAX YOU OBJECT = V-YOU-ARE-OBJECT>
<ROUTINE V-YOU-ARE-OBJECT ()
<COND (<AND <NOT ,PRSO>>
<ENABLED? ,I-TURNSTILE>
<PERFORM ,V?TELL ,ANDREW>
<RTRUE>)
(T
<PERFORM ,V?TELL ,ME>
<RTRUE>)>>
I think the main purpose of it is to implement this exchange:
>LOOK
Jennifer's Boudoir
This is a cozy little drawing room where guests are received. On the gloomy west
side of the room, a spiral staircase leads upward.
Andrew Jenny is the attraction of this sideshow. He appears standoffish, she's
looking bored.
>EXAMINE ANDREW
Andrew's wearing an army boot, combat fatigues with a black leather shoulder
holster, and a pith helmet. He sneers at you, his handlebar mustache nearly
poking his eye. "What are you staring at!"
>YOU
Hmmm ... Andrew looks at you expectantly, as if you seemed to be about to talk.
ANDREW-F
(ab)uses the I-TURNSTILE
timer to indicate that Andrew is waiting for you to respond:
(<VERB? EXAMINE>
<ENABLE <QUEUE I-TURNSTILE 2>>
<TELL
D ,ANDREW "'s wearing an army boot, combat fatigues with a black leather
shoulder holster, and a pith helmet. He sneers at you, his handlebar mustache
nearly poking his eye. \"What are you staring at!\"" CR>)
But V-YOU-ARE-OBJECT
doesn't test if I-TURNSTILE
is running. It just calls the ENABLED?
routine. So even if Andrew isn't nearby, typing "YOU" will act as if you're talking to him.
So it should probably be like this instead:
<COND (<AND <NOT ,PRSO>
<ENABLED? ,I-TURNSTILE>>
<PERFORM ,V?TELL ,ANDREW>
<RTRUE>)
>WEAR DRESS-SUIT
You are now wearing the dress-suit combination.
>REMOVE DRESS-SUIT
You wriggle out of the dress-suit combination.
Looking at DRESS-F
, it looks like there was meant to be a custom message for wearing the dress-suit combination as well:
(<AND <VERB? WEAR TAKE-OFF REMOVE>
<FSET? ,DRESS ,WORNBIT>>
<COND (<FSET? ,SHAWL ,WORNBIT>
<REMOVE-FIRST ,SHAWL>
<RTRUE>)>
<TELL "You wriggle ">
<COND (<VERB? WEAR>
<TELL "into">
<MOVE ,DRESS ,PROTAGONIST>
<FSET ,DRESS ,WORNBIT>)
(T
<TELL "out of">
<FCLEAR ,DRESS ,WORNBIT>)>
But it's not used because it only handles the WEAR
action if the dress-suit combination is already worn, and in that case it's already been caught by PRE-WEAR
.
>LOOK
Inside Trailer
These quarters are furnished in a foreigner's vision of American Rugged
Individualism. The head of a moose, for example, hangs as a trophy against one
wall. Against the west wall the door stands open and a gaily decorated curtain
is open at the window.
>PUT THUMB IN WALL
A wide-eyed Comrade Thumb goes easily through the opening and drops to the floor
on the other side of the wall. You can hear a faint whimper coming from the
crawl space.
This is because the action gets handled by WALLS-F
:
(<AND <VERB? PUT>
<PRSO? ,THUMB>
<EQUAL? ,HERE ,TAMER-ROOM>>
<PERFORM ,V?PUT ,THUMB ,CRAWL-SPACE>
<RTRUE>)
It will also refer to the crawl space if you knock on the wall, even if you haven't seen the crawl space yet. That, too, is handled by WALLS-F
:
(<AND <VERB? KNOCK>
<EQUAL? ,HERE ,TAMER-ROOM>
<IN? ,GIRL ,LOCAL-GLOBALS>
<NOT ,GIRL-CRIED>>
<TELL-WIMPER>)>>
In this case, perhaps TELL-WIMPER
should adjust its message if the moose head hasn't been moved?
<ROUTINE TELL-WIMPER ()
<SETG GIRL-CRIED T>
<TELL
"You can hear a faint whimper coming from the " D ,CRAWL-SPACE "." CR>>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.