The Residents’ Gingerbread Man and Keyboard Input Weirdness
In the README file packed in with The Residents' interactive Gingerbread Man CD-ROM software, good ol' Uncle Willie gives you some cryptic advice in operating the interactive movies:
Uncle Willie sez: If it hurts when you do that, then DON'T DO THAT!
(In other words, avoid the following...)
- If the Caps Lock key is down then the buttons don't work. This continually torments some of the slower testers around here.
Why don't the buttons work when Caps Lock is activated? I'm pretty sure DOOM II, released the same year, doesn't suddenly lock up if you accidentally hit caps lock... and since this is clearly written up in the README, it means that someone who worked on this game noticed this before it was shipped!
So why did this happen and why wasn't it fixed? In this post I'd like to look at the code to examine why exactly they could have missed such an obvious error.
So why doesn't it work with Caps Lock?
Adobe Director's Lingo programming language can handle keyboard input in multiple ways. Keyboard event functions basically have a few magical variables they can use.
One of these variables, called
(and yes, Lingo's verbose syntax means that articles can be
randomly tossed around variable names like that)
returns a number called... well, the "Key Code" which represents the
actual physical button being pressed on a keyboard. Analyzing the key
code is the most effective way of handling most keyboard input (and
mouse button input for that matter!) since key code just abstractly
represents that button's pressed state, with no other information
getting in the way of that. What that means is that if you, say, flip
on Caps Lock, it won't have any effect on the key codes being thrown
at your input handlers.
However... there is another variable that input handlers can also
used: the more simply-named
the key returns a
single character string representing the actual ASCII character being
input. What this means is that things like the Caps Lock and Shift
keys will affect what value this
the key parameter
holds! So, if you're using this parameter to check if, say, the
a key is pressed, you'll have to check if
the key = "a" or the key = "A". Yeesh, talk about verbose!
Okay, so they didn't use Key Codes? Is that it?
Not using keycodes is one reason why this seemingly glaring issue is present in the game. But as I demonstrated, you can still have "case insensitive" key detection in your code by using character strings. So were they really just too lazy to do this?
Well... kind of. Because of the way the code in Gingerbread Man is organized, implementing this case insensitivity is way harder than it should be. Let me show you an example of some uncompiled code found in the actual game's files!(From SHARED.DIR in The Gingerbread Man)
I'm not entirely sure how this code works since I don't have access to
the entire game's codebase, only random snippets that were left
uncompiled. However, it appears to be using Lingo's
case syntax to run specific bits of code based on the
ASCII character code being pressed (probably gotten by passing
the key into the
charToNum()). In Lingo, multiple cases can't point to the same block of code and
you can't put logical expressions in them either. So to make things
case insensitive with this input handling framework in place, you'll
need to double up every single line of code... and there are a LOT of
lines of code like this, since this code is duplicated for each
character's Director movie.
Here's some more code that responds to actual alphabetical characters:
And here's how that code has to be edited to make it be "case insensitive":
Now in this example we only had to add 5 more lines of code, but also remember that because of the way this is organized, we're adding extra code that needs to be maintained! If we want to redefine the functionality of the "A" key for instance, we'd have to make sure that both the lowercase and uppercase blocks of code are updated. I assume having horribly rigid code like this would seriously inhibit creative tinkerers like The Residents (and would probably just be very time consuming to fix everywhere since Director didn't exactly have the most robust development tools!), so in the end they just slapped a "DON'T TURN ON CAPS LOCK OR YOU'LL BREAK EVERYTHING!" into the README file that came with the software.
Well I guess that solves that mystery!
Well, not quite. There is a bit of code that caught my eye in the first defined text node of SHARED.DIR:
These seem to be key bindings for debugging functions! This code
defines two key behaviors: it makes the
\ (Backslash) key print out the amount of free
kilobytes in memory to Director's message window, and it makes the
| (Vertical Bar) key print out what I assume
to be a list of active objects belonging to the global scene to
Director's message window.
It's strange since on most keyboards, backslash and the vertical bar are on the same key and you have to actually press shift to type the vertical bar. This suggests that the programmer(s?) knew about this whole case insensitive input thing rather early on, and even took advantage of it to easily bind two debugging commands to the same key!
(By the way, if anyone does have a copy of GBM and a computer that can run it, I'd be interested in seeing if this functionality is still enabled in the game. Perhaps the debug information is spit out to standard output and can be read if you launch the game from the command prompt?)
I think this suggests that the whole Caps Lock issue was known pretty early on and they just straight up decided to ignore it. Maybe they designed the key handler like this early on and forgot later in development, until a tester couldn't get the game working with Caps Lock on? Or what if this software really was programmed by The Residents and as a result it is just kind of weird and clunky? Perhaps The Residents wanted to map separate behavior to the uppercase alphabet but stopped when they realized they couldn't really do much more, leaving uppercase letters to do mostly nothing at all.
And yes, I did say they mostly do nothing, since it seems that uppercase F, M, and S keys actually do something, specifically set the "random speed" parameter of the global director object... I assume it's the exact amount of time that has to pass between random events occurring on their own in the game. F, M, and S stand for "Fast", "Medium", and "Slow" respectively... I would assume.
I don't think this functionality is documented anywhere, and again, I'm not even sure it works in the final game (given how it's plastered everywhere in the code I think it might still be functional though). But I think it seems to indicate that the game was designed around this weird case sensitive input system. Personally I think that's a really weird design decision, but hey, if the README is to believed this software was programmed by The Residents so I guess that makes sense...
So... that was a rather deep dive into how The Gingerbread Man probably handles keyboard input. This piece of software is such an anomaly to me as a Residents fan and computer programmer... and doing a deep dive like this leaves me only more puzzled as to why the developers designed the game in such way that you can't have caps lock on while playing it. Gingerbread Man was developed with the same technology as the other Residents CD-ROM projects, Freak Show CD-ROM and Bad Day on the Midway, but it was handled by a completely different development studio. I haven't looked at Freak Show yet, but I can tell just from how the available uncompiled code is laid out that Bad Day was... much better put together, to say the least.
I found all of this while researching these Residents CD-ROMs (with the ultimate goal to document Bad Day on the Midway in its entirety) and I hope I can learn more interesting things about these games as I continue trying to dig through the game files. Thanks for reading!