Category Archives: My Projects

Gruepal – Lurking Horror Bug Fix

Just a quick update for those following along – I had a bug when running The Lurking Horror that would put the game into an endless loop upon pressing one of the buttons on the microwave.

The issue was an honest problem with one of my algorithms. Objects in z-machine games can have properties that tell the game things about them (things like descriptions and exits). Well, I wrote my code to assume that all objects have at least 1 property, when it truth they don’t necessarily, and it bit me in this case. The loop ran past where the object ended (since it was looking for properties where none existed), and general mayhem ensued. Fixed now. I can now cook things in the microwave.

DrupalZM – Bug fixes and name update

First off, I’m renaming the DrupalZM module to the “Gruepal” module (ala Grue from Zork mixed with Drupal), thanks to Seth Cohn for the idea. Subsequent posts with be prefixed with Gruepal.

Also, a few bugs squashed, two of these took a while to track down, a lot of sloshing through zcode assembly –

Planetfall Endless Loop

While Planetfall would start fine, whenever I tried to do anything (move, look, wait, anything), the game would go into an endless loop. Upon tracing through an execution dump, I noticed that it kept comparing variables that were initialized from the random number opcode. For the loop to end, it needed to NOT match a range of numbers, but it was always matching, so the loop continued forever.

It turned out that the RANDOM z-machine opcode is inclusive in its range. I misread this originally, I thought if you specified an upper bound of, let’s say, 8, it would generate a random number from 1 to 7 (e.g. up to 8), which is the C programmer in me, everything is 0 based in an exclusive range (e.g. 8 would be 0-7). I did the see the part about it starting at 1, but not about including the upper bound of the range. In the Planetfall case, it was passing in an upper bound of 7, but I only generated 1-6, and the code was looking for a 7 to exit out of the loop, so it never did. I increased the range to be inclusive, and life was good. Which is good, because Planetfall rules, and I found myself playing quite a bit when I was supposed to be debugging. ๐Ÿ˜‰

Take All Endless Loop

Another issue I noticed was in any game, when I typed “take all”, it would go into an endless loop. This was a REAL tricky one, because the loop wasn’t a tight one, it covered about 100 operations before looping. I nailed it down that the loop wasn’t exiting out when comparing the return value from a function that reported back the index number of the item number in the room to take (e.g. if there were 5 items, it would loop through 1 through 5, taking each item. But in my case, it would just get stuck on keep trying to take 2 over and over again because the iteration counter wasn’t increasing).

The reason is, there’s a little gotcha in the standard CALL opcode which, again, I did know about, but only implemented half of (by mistake). Normally a call statement is for calling a new subroutine – it saves all the information of the current call onto the stack, then (in my implementation’s case), creates a “call record” which has the return address once the subroutine exits and some other info.

Well, normally CALL has the address of the subroutine to set the PC to. However, there’s a gotcha that if its called with 0, it simply returns FALSE and doesn’t actually perform a call. This is to make certain operations in the game easier I imagine, when you need to dynamically call subroutines, and 0 indicates end of list – the false would stop the loop from going. Well, while I did return false, I unfortunately still overwrote part of the call record (which would happen if it was a normal call). But it overwrote the current call record instead of a new one, which could have caused any amount of havoc – in this case it just caused a loop. But I fixed that, and loop is gone.

Kill Me Bug

This one was easy. When I typed “kill me”, it would say “What do you want to kill the me?” instead of the correct “What do you want to kill the me with?” – e.g. it left the “with” out. Leaving words off I’m sure came up in other places, this was just how I found it. The issue is – there are a few opcodes that print to the screen, maybe 5 or so. 1 of them was passing the array with the output buffer by value instead of reference, so even though it was adding the word “with” to the output buffer, when the function exited that would be lost. Just a typo of one character, after adding a & for pass by reference, life was good. This was the bug I thought was having to do with zscii conversion, but it wasn’t!

New Found Bugs

A few more bugs to squash:

1. In lurking horror, using the buttons on the microwave puts the game into an endless loop. I have no idea what’s causing this yet without looking through an execution trace.

2. In Moonmist, when asking the user for their favorite color, it puts a weird symbol before the color repeated back to the user. I’m guessing this is a zscii/zchar issue.

Fun fun!

DrupalZM – Status Line

Unfortunately I came down with a nasty cold yesterday, but did manage to finish up the AJAX functionality tonight, including the ability for the page to redirect instead of displaying content (in the case of when the game is restarted/quit – in these cases the browser redirects to another URL which resets the game and sends the user back to the game description screen if they’re quitting).

Also, I implemented the status bar and got that working with both normal page refreshes and via AJAX. Additionally, the current room, score, and moves is now stored in the machine state database entry, which means that its possible to see where everyone online currently is and what the high scores are for all games.

Here’s a quick screenshot of a Zork I screen with status bar. You can see the beginnings of the save/load block as well, though more functionality and cleanup will be going into that.

DrupalZM Screenshot 1

DrupalZM – AJAX

Just a quick post, I have most the AJAX functionality done. I need to clean up a few little things like making sure the output window is always scrolled to the bottom, and handling when the page needs to redirect (in the case of game restarts/quits), but otherwise it works well.

TFNN – Virtual DNA

You may be wondering what TFNN is – it stands for Temporal Frame Neural Network, an artificial intelligence project of mine to accurately simulate the biological brain. Sadly, I haven’t worked on it in a few years for a number of reasons – reasons that were good at the time (and I wouldn’t change, the whole learning experience thing), but ones that aren’t so important now.

What the Heck Happened?

Jumping off topic a bit, but relevant to why I’m starting back up again, I realized a few weeks ago that I’m not really happy with the way my life is going. I mean, don’t get me wrong, overall things are great and I’m doing okay, but there is definitely something off. There are a few reasons, but one of the biggies was I was always doing things I felt obligated to do and never did things for fun anymore. I was always taking on a project to advance somehow, and never did it for the art or to enjoy it. I was always working hard, but honestly not really wanting the outcome, so it would never really go anywhere. I’m not a business man – I don’t like or want to play the game (There’s another article in here about not always turning your hobbies into something you get paid for, but that’s for another day). There’s nothing wrong with being a business man mind you – I’m just not one.

So I made the decision to just stop worrying about “succeeding” in these classic ways that are good for some people, but not for me. I learned something big from Shredz64 – I will never make any money off the project, but I had an incredible amount of fun doing it, and I have made so many connections with people because of it – it’s just amazing. I want to keep doing that all the time – I want to make things – not worry about marketing or selling them – I just want to create and share. I’ll save the rest of my thoughts for another post, but the bottom line is, I’ve already started working a ton more on my projects and I’ve been much happier because of it.

Back to Virtual DNA

SO, that being said, I recently made a 10 hour drive to and from Toronto, and it gave me a lot of time to think. Some of that thought was dedicated to the TFNN project. While the “neurophysiology” of the TFNN works great on a neuron and connection level, the overall issue remains in how those synaptic connections are made. Their configuration. Biology has a great thing going for it with DNA that controls neural development – during the neurulation phase when the neuroectoderm forms a lot of things happen, but at the end of the day through migration, axon paths and some other tricks, neurons are placed into their proper locations and form appropriate connections. Regardless of the nature vs nurture argument, there is definitely prewiring that is done. It’s the reason why a cat will never develop the ability to speak Romanian and why rabbits breathe without being trained to do so – it’s millions and millions of years of neurological evolution packed into a double helix.

Therein lies the problem – I have the materials with TFNN, but no blueprint I can use to construct something. I can make very small and specific networks, or very large, random ones, but neither of those will accomplish the goal of creating animal intelligence. So a blueprint is needed. Life has DNA, but what does TFNN have?

Use Real DNA?

My first idea to conquer this issue (as outlined on the project page) was to use some of the sequence databases that are available online – there are a couple species that have a very full nucleotide sequence documentation available. I won’t even bother mentioning all the reasons why this was never going to work, because the biggest reason is, I’m not a molecular geneticist, and while I have a good understanding of how DNA works, I don’t come close to having enough understanding to use DNA sequencing information to form a TFNN. It’s another project that I would love to start one day to build my understanding of the process, but not right now.

Let the Turing Machine Do What it Does Best

What I decided on the car ride was instead of using real DNA, it would be more realistic (relatively speaking) to create a virtual (accelerated) environment where evolution could take place and form virtual DNA. The TFNN already has rudimentary functionality for building neural networks from a list of instructions, so this is doable. Here’s the very lofty plan:

  1. Flesh out the matrix class inside of TFNN to construct neural networks as defined by encoded, segmented bit sequences. This will be some work but I have a good idea of how to accomplish it. There are already class members that control size, synaptic density, geography, and even connection specific formation within the neural matrix – the bit sequence needs to drive these member functions. The purpose of something encoded like a bit sequence as opposed to human readable scripts is to allow for easy engineering of mutation capabilities necessary for evolution
  2. Find a lightweight, open source graphics/physics engine. There are a few of them out there for games – it doesn’t need to look good or even come close to being the most advanced one available, it just needs to support a number of attributes common to our world such as mass, gravity, displacement, etc. The key is lightweight as possible, we don’t want to eat up CPU maintaining the world, we need all the cycles we can get for TFNN processing
  3. Engineer a method of recharging a lego NXT robot (Bit, my little LEGO robot will be the subject in these experiments) that can be initiated and completed by the robot itself. There are a number of ways to accomplish this, something tactile is preferred to force movement. Something like a magnetic connector with DC current. It would also need to produce a distinct stimulus to indicate it was a source of “nourishment” so to speak, such as producing an audible tone at a specific frequency .
  4. Create a VDNA (virtual DNA, easier to type) sequence to form a neural network that dictates motor control to guide robot to its “feeding station”. It doesn’t need to have any logic outside of a straight path for the source. I’ve created simple neural networks like these before and it is doable.
  5. Within the physics engine, model an environment that very simply and basically models a real world environment. The goal is by no means to have every possible physical scenario that could exist in the real world, its to offer enough obstacles and stimulus that evolution can take place, while using obstacles that are common to the environment the robot will operate in. Also include feeding stations
  6. Build an engine to generate instances of TFNNs using VDNA sequences and process them. Connect them to virtual robots modeled after the NXT lego robot and place them in the virtual world. Also include functionality to take the VDNA of a specific instance and spawn a new instance of the virtual robot. We could do this asexually or start with a neural configuration that drives two robots to touch in a manner that shares VDNA for virtual reproduction – I haven’t decided on this one yet. Regardless, new VDNA is subject to random mutation or corruption in the bit sequence
  7. Build in parameters that cause death in the virtual robots as well as prevent premature reproduction – most importantly that reproduction doesn’t take place if nourishment isn’t obtained.
  8. Run this simulation until results are obtained
  9. Take VDNA from successful virtual robot, generate instance of TFNN, connect to Bit and watch the fun

I can’t complain about being bored, that’s for sure – I will post here as I go. It may lead nowhere, but I’m extremely interested to see the results – even if it completely fails, it will still be fun science.

DrupalZM – Save and Restore

Things have been a bit hectic lately – with the massive cooking and cleanup of Thanksgiving, and preparing for the TPUG WoC expo (and driving to and from Toronto to get there), I haven’t had a ton of time to do much coding. I did manage to slip in a couple hours last night and finished up the save/restore code.

It was actually pretty easy – what’s nice about DrupalZM is since it’s being driven from the web, it needs to save the state of the z-machine to the DB every page refresh. The save/restore code simply copies the current state of the machine to a save slot. Specifically, the table that stores the state of the zmachine now has a “slot” field associated with each record. Slot 0 indicates the current state, while slots 1-9 are saved games. Anytime a game is saved, DrupalZM simply copies the record in slot 0 to the desired slot, and restoring does vice versa.

I’m implementing a simple block to allow for easy saving/restoring. Classically one would type “save” or “restore” during gameplay, but typing these commands out in DrupalZM instructs the player to use the functionality in the block. The block will make saving/restoring much faster, plus an added bonus is the screen buffer is completely stored during the save process, so when a user restores a game, it shows them all the text on their screen exactly how it was at the time of saving.

To Do

Most of the zmachine is functional for versions 1-3 of zcode, but the following is still left to do (not necessarily in order of how I’ll tackle it):

1. Debug current issues (picking up “all” items seems to fail, zcharacter->ascii translator is still missing small bits of functionality, out of the 3 games I’ve tried, 2 work but 1 gets caught in an endless loop processing upon issuing the first command)
2. Finish all opcodes for versions 4-8 of the zmachine
3. Implement an AJAX interface
4. Finish the save/restore block
5. Implement room location/moves status bar (as well as exporting this with scores to be used elsewhere on site (e.g. location of currently logged in users, high scores per game, etc)
6. Experiment with extra functionality (quasi-multiplayer, automapping, integrating zmachine objects with drupal nodes/fields)

Shredz64 – TPUG’s WoC tomorrow, demoing Shredz64

Just a reminder, if you’re in the Toronto area (or have a sick obsession with driving long distances like me), TPUG’s World of Commodore expo is tomorrow (12/6/08) starting at 10. I will be demoing Shredz64 and will have a few PSX64s available for purchase. Also, there are a lot of other neat demos going on by some talented guys, lots of stuff to buy, and good conversations to be had, so stop by if you want to join in the retro fun.

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!