DrupalZM – The Lurking Horror

One more quick update – I figured that if Zork I worked so well all the way up to the Troll room, that I could try giving another Zmachine a whirl and see how far it got. I added a node for “The Lurking Horror”, one of my favorite Infocom games of all time. There was one opcode that it used to manually call for a refresh of the status line that I needed to add, but after that…..

You’ve waited until the last minute again. This time it’s the end of the term, so all the TechNet terminals in the dorm are occupied. So, off you go to the old Comp Center. Too bad it’s the worst storm of the winter (Murphy’s Law, right?), and you practically froze to death slogging over here from the dorm. Not to mention jumping at every shadow, what with all the recent disappearances. Time to find a free machine, get to work, and write that twenty page paper.

THE LURKING HORROR
An Interactive Horror
Copyright (c) 1987 by Infocom, Inc. All rights reserved.
THE LURKING HORROR is a trademark of Infocom, Inc.
Release 203 / Serial number 870506

Terminal Room
This is a large room crammed with computer terminals, small computers, and printers. An exit leads south. Banners, posters, and signs festoon the walls. Most of the tables are covered with waste paper, old pizza boxes, and empty Coke cans. There are usually a lot of people here, but tonight it’s almost deserted.

A really whiz-bang pc is right inside the door.

Nearby is one of those ugly molded plastic chairs.

Sitting at a terminal is a hacker whom you recognize.

>s
Second Floor
This is the second floor of the Computer Center. An elevator and call buttons are on the south side of the hallway. A large, noisy room is to the north. Stairs also lead up and down, for the energetic. To the west a corridor leads into a smaller room.

>w
Kitchen
This is a filthy kitchen. The exit is to the east. On the wall near a counter are a refrigerator and a microwave.

Sitting on the kitchen counter is a package of Funny Bones.

>open fridge
Opening the refrigerator reveals a two liter bottle of Classic Coke and a cardboard carton.

>take coke
Taken.

Worked great!

DrupalZM – It is pitch black.

After fixing a dumb bitwise math bug and fixing a piece of the insert object logic (after removing an object, it wasn’t setting siblings correctly), things are looking pretty awesome. I would call the following a pretty successful test!

ZORK I: The Great Underground Empire
Copyright (c) 1981, 1982, 1983 Infocom, Inc. All rights reserved.
ZORK is a registered trademark of Infocom, Inc.
Revision 88 / Serial number 840726

West of House
You are standing in an open field west of a white house, with a boarded front door.
There is a small mailbox here.

>n
North of House
You are facing the north side of a white house. There is no door here, and all the windows are boarded up. To the north a narrow path winds through the trees.

>e
Behind House
You are behind the white house. A path leads into the forest to the east. In one corner of the house there is a small window which is slightly ajar.

>open window
With great effort, you open the window far enough to allow entry.

>go in
Kitchen
You are in the kitchen of the white house. A table seems to have been used recently for the preparation of food. A passage leads to the west and a dark staircase can be seen leading upward. A dark chimney leads down and to the east is a small window which is open.
On the table is an elongated brown sack, smelling of hot peppers.
A bottle is sitting on the table.
The glass bottle contains:
A quantity of water

>take bottle
Taken.

>w
Living Room
You are in the living room. There is a doorway to the east, a wooden door with strange gothic lettering to the west, which appears to be nailed shut, a trophy case, and a large oriental rug in the center of the room.
Above the trophy case hangs an elvish sword of great antiquity.
A battery-powered brass lantern is on the trophy case.

>take lantern
Taken.

>move rug
With a great effort, the rug is moved to one side of the room, revealing the dusty cover of a closed trap door.

>open door
Which door do you mean, the wooden door or the trap door?

>trap
The door reluctantly opens to reveal a rickety staircase descending into darkness.

>i
You are carrying:
A brass lantern
A glass bottle
The glass bottle contains:
A quantity of water

>take sword
Taken.

>d
You have moved into a dark place.
The trap door crashes shut, and you hear someone barring it.

It is pitch black. You are likely to be eaten by a grue.
Your sword is glowing with a faint blue glow.

>turn on lantern
The brass lantern is now on.

Cellar
You are in a dark and damp cellar with a narrow passageway leading north, and a crawlway to the south. On the west is the bottom of a steep metal ramp which is unclimbable.

>n
The Troll Room
This is a small room with passages to the east and south and a forbidding hole leading west. Bloodstains and deep scratches (perhaps made by an axe) mar the walls.
A nasty-looking troll, brandishing a bloody axe, blocks all passages out of the room.
Your sword has begun to glow very brightly.
The troll swings; the blade turns on your armor but crashes broadside into your head.

>kill troll with sword
You are still recovering from that last blow, so your attack is ineffective.
The troll swings his axe, but it misses.

>g
You charge, but the troll jumps nimbly aside.
The axe sweeps past as you jump aside.

>g
The troll is staggered, and drops to his knees.
The troll slowly regains his feet.

>g
The fatal blow strikes the troll square in the heart: He dies.
Almost as soon as the troll breathes his last breath, a cloud of sinister black fog envelops him, and when the fog lifts, the carcass has disappeared.
Your sword is no longer glowing.

>score
Your score is 35 (total of 350 points), in 18 moves.
This gives you the rank of Amateur Adventurer.

DrupalZM – Opening the Small Mailbox Reveals…

Even though it seems like I encounter a new set of issues at every step, things are progressing really nicely with the zmachine module. The lexical parser is done, it parses the input buffer and creates the parse table, looking up each word in the game dictionary. I had a few bugs with memory addressing and setting attributes of objects, but those are cleared up now.

I dont have any user interface to put commands into the input buffer yet, but I am able to set a “script” in the program so it will execute commands one by one, as can be seen below. This shows how much progress is done – as can be seen, it recognizes commands properly, but there are still a few bugs (notice how even though I take the leaflet and its in my inventory, its still in the mailbox as well – I’m not updating the objects 100% correctly yet). Also, if you try to move from the first room it crashes, which I think is actually related to the previously mentioned object issue. But anyway – here’s a nice transcript of how much is working so far!

ZORK I: The Great Underground Empire
Copyright (c) 1981, 1982, 1983 Infocom, Inc. All rights reserved.
ZORK is a registered trademark of Infocom, Inc.
Revision 88 / Serial number 840726

West of House
You are standing in an open field west of a white house, with a boarded front door.
There is a small mailbox here.

>open mailbox
Opening the small mailbox reveals a leaflet.

>take leaflet
Taken.

>read it
“WELCOME TO ZORK!

ZORK is a game of adventure, danger, and low cunning. In it you will explore some of the most amazing territory ever seen by mortals. No computer should be without one!”

>look
West of House
You are standing in an open field west of a white house, with a boarded front door.
There is a small mailbox here.
The small mailbox contains:
A leaflet

>i
You are carrying:
A leaflet

>jump
Are you enjoying yourself?

>jump
Wheeeeeeeeee!!!!!

>jump
Very good. Now you can go to the second grade.

>take me
How romantic!

>hello sailor
Nothing happens here.

>look at me
That’s difficult unless your eyes are prehensile.

>quit
Your score is 0 (total of 350 points), in 11 moves.
This gives you the rank of Beginner.
Do you wish to leave the game? (Y is affirmative): >
Ok.

Now to fix things up with the objects!

DrupalZM – West of House

I’m pretty excited about DrupalZM, things are going fairly smoothly. I fixed up a few major bugs with signed number calculations and the z-character -> zscii -> ascii converter. I also implemented more opcodes, as well as the output buffer that takes care of rendering text to the screen properly and in a controlled fashion. The machine now executes until it expects user input! Definitely exciting, as this means that the object table is being correctly manipulated and read (e.g. the west of house object, the cretin (the player), the mailbox, etc). Below is text from DrupalZM – the expected text for the starting room of Zork I!

ZORK I: The Great Underground Empire
Copyright (c) 1981, 1982, 1983 Infocom, Inc. All rights reserved.
ZORK is a registered trademark of Infocom, Inc.
Revision 88 / Serial number 840726

West of House
You are standing in an open field west of a white house, with a boarded front door.
There is a small mailbox here.

>

More soon!

Shredz64 – Board Production Going Well

Just a quick heads up that things are on schedule for having a number of boards available at the upcoming World of Commodore expo in Toronto in December, and then online afterwards. The process definitely gets easier and easier as it goes, I’m pushing out about 5-10 a weekend. Stay tuned!

DrupalZM – A Good Start!

So I had some free time this weekend and decided to work on DrupalZM a bit.

A Little About the Machine

The Z-machine is an interesting virtual machine. Unlike the average system architecture, the Z-machine has no registers in the typical sense, and keeps a separate stack from main memory. It can store local variables on its stack that can be used for the current call, and global variables in memory that can be used across calls. It has opcodes for the typical operations like math, boolean logic, calling, jumping, comparing, etc, but it also has text adventure specific opcodes, like an opcode for looking up game objects and their properties (e.g. is the mailbox open, whats the name of this room, is the light on or off, etc), opcodes for looking up dictionary and lexical data for parsing, and high level opcodes like print to the screen, save, restart, etc.

Additionally, the total size of an opcode and operands can vary in length (since there are no registers, the opcodes allow you to assign results to many different locations from the stack to memory), and sometimes can be followed by high level data like a string of characters. It’s an interesting quasi-mix of typical low level processor functionality and high level operations. It’s actually pretty cool, and a bit of a challenge (I think) to program.

For those who wish to see technical specification in its full glory, you can check it out here.

Progress So Far

So that being said, I’ve set out on the long road. So far, I’ve accomplished the following:

  1. Created a Drupal module that installs the custom content type “z-machine”, that allows z-machine nodes to be added (basically a description of the game and the file it points to). This will allow Drupal site admins to easily add new stories to their website.
  2. Memory, Stack, and PC storage per user per z-machine, which means that a user’s progress will be saved at all times in any game he/she is playing. Saving and Restoring will still be available if desired of course, but there will be no need to save when done playing.
  3. When a user goes to a z-machine page, code will execute that will either read the machine from the appropriate file, or use the user’s memory if its available (i.e. they’ve played before).
  4. All opcode types except extended opcodes are processed and directed, in all forms. So this includes 0OP, 1OP, 2OPs, and VARs, in their Long, Short, and variable forms
  5. Storage and branching is fully supported for all opcodes. Return values will be stored in their correct location (Stack, local variables, global variables), and instructions that require a branch will do so to the correct address, both in their positive and negative forms (if true/if false).
  6. The stack is fully implemented, both in normal pushes and pops, as well as storing call information such as next PC, local variables, and return variable. Upon a return call, the z-machine will correctly clean the stack up and set the PC correctly
  7. About 20 opcodes (which means 40-60 or so with their different forms) have been implemented so far
  8. A full zcharacter <-> zscii <-> asciii conversion system has been implemented with abbreviation table lookup
  9. Basic object and property handling has been implemented
  10. For what’s been done so far, it fully supports versions 1-3 and some support 4-5, and little support for 6-8.
  11. I’ve made quite a bit of progress, but there is still a tonnn to go. But it’s a lot of fun. The machine can execute about 150 instructions before dying from an unknown opcode. But, in those 150 instructions, I’m already seeing text on the webbrowser! Here’s a small excerpt:

    Instruction:178 print: ZORK I: The Great Underground Empire
    Copyright (c) 1981, 1982, 1983 Infocom, Inc.
    Instruction:178 print: All rights reserved.
    Instruction:187 print:

    Instruction:16
    loadbstack push
    Instruction:73
    andstack push
    Instruction:160
    Instruction:178 print: ZORK is a registered trademark of Infocom, Inc.

    Pretty exciting! More to come…

DrupalZM – My New Project

For those eager to purchase a PSX64, don’t worry, I’m still planning on selling a batch at the upcoming World of Commodore Expo and then selling online. The following project is slow moving right now – Shredz64 is still my priority.

The Project Idea
That being said, I’ve been itching for a new project to work on. I have a few Commodore related hardware ideas, but I’m putting them off until most of the PSX64 sales are done with. I wanted another fun software project to work on in the meantime. I’m a huge fan of text adventures, both the Infocom classics (The Zork series, HGTTG, Lurking Horror, etc) and the great interactive fiction that’s still being written by the IF community (if you’re an IF fan and haven’t yet, check out the Interactive Fiction Archive, there are thousands of awesome stories on there to play, many are really amazing).

I’m also a Drupal developer as a part of my day job – we often get into conversations at work about cool vintage technologies we miss, and text adventures are one of the topics that comes up often. During one such conversation, a coworker (Hi Seth!) and I got onto the subject of how it would be great if there was a Drupal Z-machine module that allowed Drupal sites to offer text adventures for users to play online (no need for downloads). And I thought, now THAT would be a fun project. I had always wanted to write a virtual machine/emulator, and being a fan of the text adventure genre, this was perfect.

Now of course there are java, a whole slew of local, and mobile Z-machines out there (and maybe even other PHP implementations), but this is more of a fun academic exercise for myself – a big learning opportunity – the Z-machine has a hefty list of opcodes and nuances. I normally wouldn’t post this early into a project in case I lost interest or my time grew short, but I feel confident about this one, and I really want to let people follow along if they’re interested.

I’m going to post what I learn about the Z-machine from the tech specs on the web as I go, coupled with the work I do to implement that in PHP/Drupal. So far I’ve done some work reading the data file from disk, parsing information from it, and parsing op codes and operands, but I will save these details for the next (series) of posts.

Wish me luck!

Shredz64 – Difficulty Selection and Upcoming Live Demo

Thanks to a few nice, quiet hours I had tonight, I was able to do some Shredz64 development. One thing I quickly noticed at the ECCC convention last month was that Shredz64 is too hard for new players. The timing is different from Guitar Hero, and is pretty demanding on top of that, so unless you’ve been playing for a while, it’s pretty hard. This was where it was nice to see other people using it, as its hard to judge the difficulty of something you’ve been playing for a year.

So to combat this issue, I’ve added the choice to play a track in either “Easy” or “Hard” mode when selecting the song by pressing green or red, respectively.

Shredz64 - Difficulty

Selecting hard plays the track at the same difficulty as before, but selecting easy plays the track much more leniently – the notes are the same, but the note matching gives you an additional 10 pixels above and below what is considered a valid note hit in hard mode. This will hopefully make the game a little more approachable for new players coming from playing Guitar Hero.

Live Demo – TPUG’s World of Commodore Expo

Also – just a quick announcement, I will be demoing Shredz64 and the PSX64 interface, as well as selling a few PSX64s at the upcoming World of Commodore Expo hosted by TPUG in Toronto on December 6th. Even if you’re not interested in Shredz64, I urge you to check out WoC, they have quite a few demos, lots of tables with great Commodore stuff for sale, and knowledgeable and friendly people to talk to. Toronto is always a fun place to visit as well, so make a weekend of it! Hope to see you there!

Setting Up an IRIX Cluster

In my quest to collect a massive number of vintage and non-x86 machines, I recently picked up two Silicon Graphics workstations. I was pretty excited about this – as a teenager I had always been in awe of SGI and the amazing 3D their machines pumped out. As the originators of OpenGL and creators of some of today’s fastest supercomputers, SGI is one impressive organization.

The Operating System

One of the cool things about SGI stations besides their fast as hell (at the time) MIPS RISC processors is their operating system, IRIX. IRIX is a UNIX designed for the MIPS line and an X custom tailored to the SGI graphics chipset.

SGI Screenshot
Photo of IRIX screen running a demo, GIMP, and a terminal

Another great feature of IRIX is built in clustering using array services. Like all clustering, this allows you share the processing power and memory of multiple IRIX workstations to accomplish tasks more quickly. Being an older OS, I was nervous the process would be difficult, but it wasn’t bad at all.

The following is what I did to create my “Excelsis” cluster, consisting of my two SGI workstations, Metatron and Gabriel:

  1. Install Array Services – array services can be found on the operating system disks that come with your workstation.
  2. Configure Your Array – IRIX comes with an arrayconfig script to generate the array configuration file, but chances are you’ll need to tweak it anyway, I find it easier to simply create the file in its entirety. The configuration file can be found at “/usr/lib/array/arrayd.conf”.

    Each array this machine participates in must be defined in this file. The first is normally an array labeled “me” which consists only of the localhost. Any further arrays require a name, plus a list of all machines in the array, which each need their own label and IP address or address to contact them at.

    array me
         machine localhost
    
    array excelsis
         machine metatron
              hostname "192.168.0.15"
         machine gabriel
              hostname "192.168.0.16"
    

    According to the documentation, quotations are necessary for hostname. As can be seen, I have defined an array called “excelsis”, with two machines, one named “metatron” and one named “gabriel”. I then specified the IP address of each machine.

    The default arrayd.conf file will define a number of array commands that can be run from the terminal. These are all well known UNIX commands such as top, ps, and who, only they can be run on the array as a whole, as opposed to just the local machine. E.g., running “array who” would list all users logged into the array (i.e. any machine connected to the array). Leave these commands where they are and jump to the end of the config file.

    The end of the configuration file contains a “local” identifier that contains settings and defaults for array services running on the machine, such as the port array services listens on and the default array for array commands (remember, your machine can participate in more than 1 array. If you run an array command without specifying an array, it will default to the one specified here). You’ll want to change “destination array” to be the name of your default array. In my case, I changed it to “excelsis”. That’s it for this file!

  3. Configure Array Security – By default, your array will be configured to not allow connections from remote machines. This allows messages to be passed via MPI between programs running on your machine, but doesn’t allow for clustering. Edit the “/usr/lib/array/arrayd.auth” file, and you should see “AUTHENTICATION NOREMOTE”. You’ll want to change this to “AUTHENTICATION NONE” if you want any machine to be able to connect to your array (not secure, but may not be an issue if you’re running behind a firewall), or “AUTHENTICATION SIMPLE” if you’d like to setup private keys for each machine. If you go the simple authentication route, you’ll need to specify “HOSTNAME machine1.domain.com KEY 0x3817382771948” where machine1.domain.com is the address of the machine, and the hex string following KEY is the private key. You’ll need to specify this for all machines. These keys must match per machine on all machines in the array.
  4. Autostart Array Services – Now that you have your array services configured, you can tell IRIX to start it on bootup by enabling it in chkconfig. If you aren’t familiar with chkconfig, it is a special utility that configures whether various daemons should autostart at bootup or not. You can see a list of which daemons are currently set to start by running “chkconfig” with no arguments. To autostart array services, type “chkconfig array on”.
  5. Rinse, Repeat – You’ll need perform the above steps on every machine participating in the array. Assuming you have NFS starting before your array, I don’t see any reason why these configurations couldn’t be symbolically linked to one central configuration, but if you ever wanted machine specific settings you’d be out of luck. I simply edited the files on both my SGI workstations.

At this point, you can run an “array who” to see all people logged into your array and “array ps” to see all processes running on all your clustered machines. The fun really begins for programmers at this point, as you can make use of the MPI libraries to share tasks across multiple nodes in your cluster for parallel processing.

While IRIX is on its way out and the chances of needing to setup a cluster is slim, it can be a fun little project if you have a few SGIs kicking around. It would also be interesting to see the compatibility of passing MPI messages between IRIX and non-IRIX clusters. A project for another day!

Telltale Games – A Top Notch Gaming Company

I’m a pretty big fan of games in general. I love playing them, making them, watching the impact they make – everything about the industry is pretty awesome. While I was certainly a Nintendo kid, gaming really started for me on the Commodore 64, and enjoyment grew into a true appreciation with adventure games and my first PC, as I talk about here.

Where Did the Adventure Go?

The gaming market has changed in some very distinct ways over the years for a number of reasons. One of these changes that has been talked about quite a bit is the decline of the adventure game market. These games used to dominate, and now are the stuff of homebrew projects and small corners in software stores. While it’s sometimes difficult to discern if the market shapes corporate decisions or vice versa, we are indeed in a place where giants like Activision abandon clearly sought titles (read: Ghostbusters) as the profit margins are deemed unworthy by their market research and finance personnel. A business must survive and prosper to continue to push out product, but there is that point where an organization becomes more concerned about their profit than their product. And we are in no shortage of companies that subscribe to these views.

The Gallant Few

On the other side, there are those gaming companies that understand they can make a profit but still have a soul – staying true to the heart of the gaming community. I speak of Telltale Games, makers of the Sam and Max series, Strong Bad’s Cool Game for Attractive People, and the upcoming Wallace and Gromit’s Grand Adventure. They are a group of people whose passion lies in adventure games, even in a time where the typical market research would suggest this is not as profitable a route as creating a string of Call of Duty or Grand Theft Auto clones. Makes sense, since Telltale was founded by veterans from LucasArts, the company that at one time had produced masterpieces such as the Monkey Island series, Maniac Mansion, Day of the Tentacle, and yes – Sam and Max Hit the Road.

Sam and Max Ep 203
Screenshot from Sam and Max Season 2 Episode 3: Night of the Raving Dead

Having played through both season 1 and season 2 of Sam and Max, and the first episode of Strong Bad, it’s clear to me that Telltale puts out simply awesome games. Packed with humor, beautiful illustration, and quality gameplay, these adventures are truly fun to play. They also go to show that adventure games are not confined to the retro, homebrew, and Myst clone market.

Give Them a Visit

If you haven’t yet, take a moment and check out their site, there are even some free downloads to get a taste of what their fare is all about. And if you like what you see, give them some money! I know I for one would like to see a little more diversity in my gaming selection, but it can only happen if we support companies that are in it for the games, not just the revenue.