Way back in 2016 when I had all the time in the world thanks to a lengthy period of unemployment, I decided to enter a Ludum Dare game jam with the goal of creating a ZZT game for it. That game was Ruins of ZZT and it was a lot of fun to make. Eight months later and I was able to enter another one and make Quickhack. I had hoped to continue making ZZT games for these jams, but made the horrible mistake of getting into retail and working pretty much every Friday and Saturday for the next four years.
But now I am free! So when I happened to see that it was time for another Ludum Dare at the end of April I had to give it another go and threw away a weekend to create a third Ludum Dare entry which came to be known as Doug Tudeap in: The Ore Gone Trail.
Past jam entries taught me a few things. I was confident I'd be writing this postmortem article so I did my best to keep scrapped content rather than delete it. Tudeap has a lot of twists and turns in its development as I focused on always moving forward and never being afraid to scale back ambitions. One major difference between this entry and my previous Ludum Dare games was that this time I opted for the "compo" versus the "jam". Compo games have some stricter rules, but the most important is that you only get 48 hours versus the jam's 72. I'd love to say that I picked the compo to hone my skills or something, but really I just had other things to do and booking 48 hours meant my Sunday would be free.
In retrospect, I think I'd have been better off in the jam and just enjoying the extra time or submitting early.
Ore Gone Trail
If you haven't played the game yet, you can complete it in less than 10 minutes over on the game's Itch page. The basic game idea is that you control a minecart and have to pass by various valuables to mine and collect them. Your major obstacles are the various gates installed that will change how the minecart follows the track its on. The player can toggle these between two states. Each stage is on a time limit with the goal of the game being to get the highest score possible.
And some of the initial brainstorming ideas...
...have nothing to do with that.
"Deeper And Deeper"
The theme for this event was "Deeper and Deeper", which needless to say resulted in plenty of games about exploring the oceans, caves, and deep space. I've also run across a few games that went for the obvious downward-platformer idea. In ZZT, "platformer" is rarely a good idea, so my first concept was to design a board where as the player moved down, a wall would appear behind them. Instantly I began thinking "So I'm making Downwell, but worse". Not that that was going to stop me.
Hastily I threw together this engine to see if the idea could be done in the first place, and it very quickly demonstrated why it would not be a good fit.
It was definitely possible to restrict the player from going up! However this just makes it trivial to run down a section to just a single row and shoot any enemies that happened to survive with basically a guarantee that you wouldn't miss. Granted this was just a very quickly thrown together proof of concept. You could do things like only prevent going up once the player passes certain points, or actually try making a platformer, but downgraded Downwell certainly wasn't clicking.
When in doubt, simplify.
Quickhack worked, and it's always been a game I wanted to revisit in some way. I've always been a big fan of ZZT dungeon crawlers, and Quickhack's class system was a lot of fun to design around, so why not go for something in that vein? This got me thinking about a lot of concepts all at once. Quickhack had you select between a fighter with a short ranged sword, a magician with limited-but-recharging mana for magic missiles, or an elf that could shoot as many arrows as they wanted, but had to keep an eye on their limited ammunition on each dungeon excursion. The idea with Quickhack was that the entire game took place on a single board, encouraging playing as every class due to its limited scope. For a pseudo-sequel, I considered the idea of having you choose a weapon to bring to each floor of the dungeon letting the player experience every weapon available. I'd be able to tune dungeons to favor a specific load-out, and a player who got a game over could try again with a different offensive style on their next attempt.
It could work.
It would need a plot though, and why not take inspiration from Ezanya, one of ZZT's oldest fantasy themed games with its iconic evil king. Perhaps instead of being a heroic adventurer, the protagonist could be a poor miner sent to clean out the mines from... orcs I guess. It's always orcs. A big bad sorcerer could be leading some orcs to smash stuff. It's fine. Just trust King Ezanya.
Dwarftown would serve as a hub. It would need some buildings of course, some kind of shop to spend gold at, a tavern, that sort of thing. The idea that the player would be a citizen living in the town presented an opportunity to do something a little different. Quickhack had the player restore their health by (surprise) staying at an inn. If the player lives in town, they'd have their own place to rest, so how could I give the game a bit of a challenge when there's a free bed every time you head back to town?
What if resting meant passing time?
A time limit seemed like an interesting approach! It certainly didn't have to be realistic, just advance the clock a set amount every time a dungeon floor is visited as well as for taking a rest. This dark sorcerer could be performing a ritual in X days and need to be stopped before that much time passed. Now there's something for the player to consider. Do they descend even deeper, or do they take the time to turn back and rest as the clock ticks away...
This is where the seeds of the game that actually got made were first formed. If the player was going to have to backtrack, they'd wind up doing so through completed floors. I came up with the idea for a sort of fast travel unlocked once a floor was completely cleared out of enemies where the player could then ride a minecart to quickly reach the stairs.
Confession: I have had the idea of making a wild west themed 2D-Zelda game for a good decade now with minecarts that would let you zip through dungeons faster.
Which meant that I didn't just want the player to touch a minecart object and then trigger a board transition. I wanted a moving minecart! This idea, was not simplifying.
So I drew some caves and laid down some tracks. What was the rest of the level going to be like? I don't know, I just need to run some tracks.
A part of me also had the horrible thought of "I could modify ZZT's source code and make linewalls walkable and use those for tracks". The idea of a custom font was a temptation as well. I am glad I was smart enough to say NO to this kind of thing on a 48 hour time limit.
I was very much distracted by minecarts and much less invested in dungeon-crawl. Time to simplify. I could ditch the minecarts of course, and do in fact have a cross-section view of some mines (which is just rectangles fading from brown to gray to dark gray), but m i n e c a r t s. Time to throw out the Quickhack and go all in on minecarts and their tracks.
Two issues I'd be running into with the dungeon-crawl minecart system were how to actually push the player along with the cart which would become a big problem as soon as it turned and how to program an object to properly follow a track. So the next plan was to make the track the focus of the game. My next idea would be a sort of tower defense-esque title where you laid out the tracks and then steered your cart to defend against approaching enemies, protecting a town or something in the middle. I still think this could work as a game idea, but probably not with vanilla ZZT.
So scratch the customizability. Just make a fixed track and fixed levels.
This is the first time there's something that can really be recognized as something resembling the final game's gameplay. This rough proof of concept is still intended for something more akin to a tower defense. I was thinking of zooming around a track and firing "arrows" from the cart more akin to an overhead Space Invaders perhaps.
By definition, a ZZT engine is going to have to sacrifice play-space to leave room for the objects that handle everything. Like a cousin of the Atari 2600 where screens would be shrunk to let the CPU handle game logic in time to draw a frame, ZZT engines also come at the cost of space. Some folks will take a very minimal approach to this, cramming as much into a secluded corner as possible to minimize the engine's footprint, but far more common is to just slice the board to keep the actual play area in a rectangular shape.
Most predominantly this is done by mimicking the massive sidebar used by ZZT which already feels like its taking away what would otherwise be part of the play area. Dark blue is the color of choice nine times out of ten, and the ability to produce dark blue walls with blue text meant that even early ZZT worlds with limited colors could still pull this off if they wanted.
I really didn't know how complex the controls might end up becoming, but kept things fairly conservative from the start. There's an indicator of the speed and the necessary arrows to adjust it. "Adjustable speed" isn't something you see too often in ZZT engines, and my next task was to make sure that I did it right.
Having played Speed Racer X not too long ago, I noticed one flaw of the engine (which worked to its benefit in some ways by making crashes chaotic) was that the speed of your car was handled entirely by adjusting the object's cycle. While that certainly changes the speed at which it would move through the course, it also meant that driving at a slower speed would lead to dropped inputs. A speed that isn't cycle 1 means the car will often take multiple cycles to respond to your inputs. This leads to a game where slowing down actually makes it harder to drive.
So I opted to introduce a middle-man between inputs to adjust the speed and the minecart actually doing so. This mover object (tucked away in the lower right) would essentially simulate the cart moving at a slower cycle while allowing it to really be executing code at the fastest speed of cycle 1. Doing this requires faking six cycles before the code can repeat.
|Game Cycle||Move on speeds|
|1||1, 2, 3|
The gameplay still was far from in place though. I could still go with the plan of a tower defense, but had to worry about what would happen if an enemy reached the tracks or how to get the minecart to not derail if an enemy blocked its path.
There was also the issue that with the current design the cart's track needed to be a looping circuit. This would really make finding a good scale for the levels rather difficult. No matter how convoluted the track might actually be, it would ultimately just be a circle which meant that there would be a fixed amount of time to get from one point on the circle to its opposite. That could be tedious if it took too long, but if the path was too short it would hardly feel like some dwarven miners' sprawling cave operation.
Simplify. It was time to complicate things.
This board is where the game really begins to take form. This test track was tweaked as needed to let me confirm the cart was properly turning when traveling forwards or in reverse. A flag would track the current "forward" direction, and some of those purple smileys would helpfully indicate which flags were set as well as the current speed. Both of these could save a flag and use other methods of tracking state since it only needed to be per-board. Whether or not flags were ideal is hard to say. It certainly meant a lot of duplicated code as checking if the cart was moving forward meant checking for "f1", "f2", and "f3". I could've split these up into a forward/reverse flag and a speed1/speed2/speed3 flag, as I had plenty flags still remaining to spare. My real concern was memory, but even this ultimately wasn't an issue.
There are a few other new additions here. This board was first used to test the gate system, which as a placeholder was a simple as shooting to toggle all the gates. The corner also has three gemstones which would be scattered along the track. These two systems do appear in the final game, but they had some interesting evolutions from how they're coded on this board versus the final game.
The gates were simpler to begin with. Rather than placing sliders to open one path and close another, the gate object here would physically move itself into the appropriate positions. Using tweaked X/Y-steps to let the object
#walk diagonally and constantly bump into a wall until a command to flip the gate was received which would flip the movement with
#walk opp flow.
The gems mark another change to gameplay. No more tower defense, now you'd be mining gems in the walls and trying to get as many as possible. They also betray a scrapped gameplay mechanic here. Since adjusting speed was handled so eloquently, I wanted that to be part of the game's strategy. Give the player a reason to slow down, and that reason was that different gems could only be collected if the cart was moving slow enough. This could give score chasing some new challenges. A player could zip around a mine at high speeds and pick up the smaller gems, but to really max out on points you'd have to figure out where it was worth the time slowing down, and minimizing the time as well to be able to navigate to the next vein!
At this point my work was cut out for me. I had to get the engine developed enough to be able to make levels for it, and then see what kind of levels I could actually make. Other things to figure out included how to handle crashing. I definitely failed at giving much incentive to slow down so the complexities of crashing are pretty difficult to actually notice. The faster your speed when you hit a wall the longer before the player regains control of the cart with the crash handler running a short loop that ticks up/down the speed until the cart is back in a parked state.
Eventually enough pieces were in place to make a playable test track. I'm actually unsure why this one doesn't have any gems placed on it. I think this board was made and then some mishandled edge cases for turns were found. One notable difference from this board and the final game is the beginning and ending tunnels. I hadn't fully settled on a time limit yet and was intending on having a level structure of "collect all the gems and head to the exit". A time limit could be implemented later when I had an idea of how much time the player would actually need!
It was time to start making some components.
It's also time to switch to the final file. Just to keep things clean, I was working on a file with the expectation that it would be renamed before publication with the cruft thrown out, not so much as a file size thing, but just so all these pointless boards weren't making linking up passages take longer as I'd have to scroll through a longer list of possible destination boards.
I coded the eight possible gates, and definitely played with a test level where i had the gates use
#bind only to watch everything break since I was using
#restore to track which position each gate was in. Those labels get shared between every object when binding is involved so every gate is ultimately its own unique copy.
There's a whole lot of scrapped content here regardless of plans to keep things more polished for the final file! Oh the right there's a mention of
@rswitch and two scrolls that explain the other types of gates that were planned and removed to keep it simple. Red switches were going to have marks on the track which passing over them would cause them to switch positions. A third type of switch would act similarly but only control a single switch. These got scrapped for a mix of time constraints as well as adding a lot more complexity to the game which is frantic enough already.
If I had to do it again, I think I'd have gone with red switches so that the player could be focused more on their cart. White got coded first though, and they worked. Well, mostly. I did spend some time trying to ensure that gates couldn't destroy the minecart object on accident. This was easy enough, but I had hoped to do so in a way that would also prevent it from being possible to desync a gate from the others. I don't doubt that it could be done, but it was burning time for little benefit, and I figured at worst, desyncing could create some emergent gameplay where some extremely precise route is only possible if the player got a gate to desync.
The scrapped gems on the left are just the original speed-dependent power-ups set up to check for the cart in each direction as needed. For these I could get away with using
#bind. The source objects could blend into the background and then i could sprinkle gems as needed.
On the right are the final gems and ores. I opted to split everything into just three categories for scoring to make it easier for a player to try and figure out their routes through each level versus having a whole bunch of different items of different values. Since I was going to need four objects regardless, I gave each direction a different ore. This creates a sort of uniformity to the placement of items (you'll always collect gold by being to the east of it), but I preferred the efficiency of doing it this way over having to later do an art-pass where i'd change some generic objects to various colors and characters. In most levels, I don't think anybody would notice without it being pointed out to them? Perhaps the bonus stage or stage three where everything is placed on just one axis makes it a bit more clear.
I also cared to make things not too busy with the ores. Colors don't repeat between classes with the exception of the lowest class ores where there are two instances of light gray, and I had even changed a yellow topaz into a purple amethyst to prevent repeating yellow. Hopefully this kind of thing aided in the game's readability.
Lastly, the quote on the bottom which popped into my head at one point and I vowed I'd find some way to work into the game.
I think that finally covers all the historical bits and pieces. There are still some differences between the engine in these tests and in the actual stages, but it's time to get to the honest to goodness Ore Gone Trail.