Where can I get Quickhack?
Quickhack is available on the Quickhack Ludume Dare page.
Released: Apr. 23, 2017
The Ludum Dare, for those who aren't aware, is a game development competition held every four months with the goal of getting people to finish something, mostly by imposing a strict time limit (48 hours for the official competition, 72 hours for the more casual game jam). Last August I participated in my first (Ludum Dare #36), shortly after launching the Worlds of ZZT project officially. The theme was "Ancient Technology" and I was feeling cheeky and decided to make Ruins of ZZT, fitting the theme by nature of being an MS-DOS game made in 2016.
This past April I gave it another try with Ludum Dare #38 - A Small World. These short time limits lend themselves well to making ZZT games, which can be produced very quickly, and have their own historical precedent throughout the late 90s and early 2000s which had seasonal 24 Hours of ZZT contests. These were later followed by 72 hour Weekend of ZZT events in later years, so the idea of making a ZZT game in such a short timeframe is hardly anything new.
I learned of the event a few days prior to it starting, and decided I'd try to participate in the competition itself this time, leaving me with just 48 hours (which would work well seeing as how I had to work on Sunday which was the last day for the jam) to come up with and create a game based around the "A Small World" theme that had been voted on.
The first idea that I came up with was as you can see from the title, "Armory Crossing". The idea was to create a somewhat persistent world in ZZT where each board was a different day in the same Town of ZZT style armory, with the player's choices influencing characters' attitudes and behaviors over time. The inspiration being Animal Crossing where you have a small town and things to do each day.
If you've ever played an Animal Crossing game, they tend to open with the player character riding on a train towards their new town. They have a conversation with a fellow passenger (a cat named Rover) who asks the player some questions about themselves, their name, gender, etc.
None of that would be relevant for Armory Crossing, but I wanted to keep the intro to the game and use it as a chance to show off a little. One thing I constantly run into when trying to create ZZT games these days is always wanting it to be something fresh. ZZT's full of worlds which work with and around its limitations to do things that somebody with only a basic familiarity with the engine would think were impossible.
So of course, I wondered if I could fake parallax scrolling as a way to convey the train's movement.
And well, the end result isn't the best. The foreground trees move faster than the background trees, but there's not enough detail to really create a good illusion. Each row of trees slowly moves in a large rectangle, first from right to left, and then on hitting the edge of the board, they turn invisible, move up a row, and head back to the right until they can reappear on the right edge of the board to look like they're brand new trees.
The ones in the back do so at a slower rate. There are also trees already heading to the right edges that are invisible to ensure a steady flow of movement, and that's where I ran into my issues.
The amount of trees still appear to be rather sparse, and some rows have to be empty so the the invisible trees can move back into position. This board uses 148/150 stat elements, so the scenery simply can't get any more dense. This effect might work better on a purposely constrained board, but one that's full size is too empty!
I wanted to add a few more details, some form of animation onto the visible rail tracks as well, but was already out of objects. I also planned to indicate time passing by having the sky change from blue to purple to red to black to simulate sunset fading into a night sky. Originally the sky on this board was probably twice as large, but I realized I needed a lot of room just for trees.
The Rover equivalent is still there however, and I realized I didn't have much to say at this point, so I wrote some placeholder "Got any plans?" dialog and that's it. Then I noticed I was wasting way too much time on a cosmetic introduction screen and should be making an actual game.
The Ludum Dare has rules against lifting content from other games, so I redrew a Town of ZZT style armory board by hand, and placed a few buildings around.
I didn't have too much of a plan. The player would live in the yellow bordered house (and be able to pay to repaint it for future boards). There's a bed inside that would be used to end a day and advance to the next, and a few buildings placed.
In keeping with the Animal Crossing theme, the residents of the town would be ZZT creatures. Ty the tiger, Lyle the lion, Barbara the bear, Rufus the ruffian, and Sharon the shark. This conveniently meant I could have one building of each of ZZT's seven default colors, with red being used for the armory walls.
Ty the tiger would take on the Tom Nook role, and be the shopkeeper (hence his location where the Town of ZZT's vendor is). Day one would involve ringing the doorbell on Barbara's blue home to get her to open the door and give the player the key to their home that she was holding onto.
I of course wanted to make a persistent world, in ZZT, and in 48 hours, forcing myself to deal with two extreme restrictions. ZZT's only real ways to store data are with the player's stats, health, ammo, torches, gems, and score, and through ten binary flags with arbitrary names.
Barjesse's Nightmare kept track of the letters collected in the word "consciousness" by splitting the word up into chunks of four letters and managing flag stats there. It would be a lot of code, but it did allow for handling more than 10 bytes of data with only 3 flags. (The extra letter had its own little trick as well.)
#if cxxx hasC
#if coxx hasC
#if cxnx hasC
#if conx hasC
#if cxxs hasC
#if coxs hasC
#if cons hasC
You don't have the letter C!
You do have the letter C!
• • • • • • • • •
A lot of if statements were needed to check for something, and you had to check for each permutation when setting an additional letter, but lots of data could be encoded this way. I figured it would be a possibility because I only really needed to encode and decode the state of the world when the player went to bed. I'd just lock them in place, scan the board as needed, create the flags, and then have the next day begin by checking those flags, updating itself, and then allowing the player to do their thing.
Again though, time would be a major factor. This type of code would be very tedious to write out, easy to make a mistake in, and a nightmare itself to test.
The next issue is one that I dealt with for the actual Ludum Dare entry submitted, ZZT's board size limit. I figured for an example of a persistent world I could have fruit trees like in Animal Crossing. Each day you could shake them for some fruit, chop them down for lots of fruit, or plant a new sapling in a spot where a tree was chopped down.
ZZT has a #bind command which allows an object to point to a different object for code execution, preventing a dozen identical objects from having to have identical code written out and bloating the board size. However because it really is a pointer, if you chopped down a tree, and every tree shared the code, you'd find that every single tree on the board would now believe it was in a chopped down state.
This board has 17 trees on it, each with their own code, and they bring the board size to 10 kilobytes. ZZT gets crashy at 20 kilobytes so half the storage is already being used just for some trees. Avoiding that limit would require massive cuts to what could be done. (Plus those trees don't have code yet to manage a flag for the state of all the trees yet!)
It was a cute idea, but clearly not going to work. I considered just dropping out since I wasn't going to have a lot of time and didn't have any ideas, and of course the time remaining was only going to get smaller and smaller.
I called it a night, not really expecting to do anything the next day.
But of course the next day I wanted to try again! I did have another idea to incorporate the theme, if not much of an idea for gameplay. ZZT's scrolls and objects pop up a blue window when drawing text
• • • • • • • • •
You know, this thing.
And yellow text.
• • • • • • • • •
Somebody (no idea who it was or where it was published to find out) once contributed a little minigame to some ZZT magazine world or other compilation where they had drawn a replica of a scroll's layout on the board itself, making it look as if one was open when there wasn't a scroll anywhere. They placed the player inside, who conveniently matches the colors used in scrolls and made a puzzle where the player had to escape from the scroll.
That minigame has stuck with me, and I thought of making something about a player inside a scroll trying to exit. I had the idea of maybe using the red arrows as a start and end goal, with tiny mazes and enemies inside. So I redrew the scroll in ZZT (which I have probably done a dozen times now for one reason or another over the years) and then called it quits immediately. I didn't have ideas for level design, and didn't want to just slap down some walls and lions and call it a day.
So I waited another hour before coming up with Quickhack, and game whose level design was me slapping down some walls and lions and calling it a day.