Hi all,
We've finished our next game, Crypt Sweeper, after ~2 months of development.
Links:
I thought this community might be interested in some of the development and history as well.
We have been working on a platformer for a while, but started to feel stuck. I'm always on the look out for interesting games, and stumbled on this article from ArsTechnica, where they clued me into DragonSweeper.
It took me a while to figure out the game, but once I did, it was really addicting! I kept discovering new mechanics and ideas, and fell in love with it. I thought it would be a great idea to port the game to the GBA, and reached out to the developer (@danielben). He didn't want me to use his assets, but suggested I clone the game instead.
This seemed like a project I could tackle in a reasonable amount of time so I got to work. I made a basic clone of how I understood the game, and then dove into the original DragonSweeper code to look at the level generation.
DragonSweeper's level generation is really interesting -- the basic idea is to place monsters on the board, then score how "happy" the monsters are, and wiggle them around until their "happiness" is maxed out.
I attempted to port this same basic logic to C, but when I ran it on the GBA, it took 40+ seconds to generate a level! This was not acceptable.
I ripped out the level generator, and rewrote it from scratch, based on my new understanding of how the game worked. There are a lot of constraints that need to be maintained, but in principle, it's still very easy. For example, the walls are always placed in pairs (horizontal or vertical). Most monsters have placement logic as well. Instead of encoding the preferred placement as "happiness", I just placed them directly in the structure I wanted, and gave up and started from scratch if I failed after 100 attempts.
The level generation still took a while though, 15-20 seconds (iirc).
My solution was to do all level generation at compile-time. This actually turned out to be a really good decision.
A side effect of doing level generation at compile-time meant that I could do additional analysis on the levels. In particular, I wanted to have 5 levels of difficulty, with harder monsters spawning on more advanced levels, but also the boards themselves needed to be analyzed for their difficulty in reasoning.
So I created an AI that could play the game, based on different amounts of understanding of the game. For example, the base level understanding is just math. But I could also add knowledge of how the monsters behaved into the AI. That meant I could run the AI against a board with different levels of understanding of the game.
At compile-time, I generate 1024 levels per difficulty, and in order to validate that a board conforms to a difficulty level, I let the AI play the board with a certain level of understanding. If it can beat the board at that level of understanding -- and not at a lower level of understanding -- then I can be certain that the board has a certain level of difficulty.
This does increase compile-time quite a lot, but it's a fixed cost.
This is a similar technique I've done for Sudoku boards, for example. It's hard to generate an easy board from scratch, but you can generate lots of boards, validate they have one unique solution, and categorize them after the fact. This is roughly what I do for Crypt Sweeper as well.
One last step, since the player only has 1024 unique levels per difficulty, that felt a little small. In order to increase variability, I also shuffle the two lowest level monsters randomly on the board, at run-time. These monsters are always placed randomly, so shuffling them around after the fact shouldn't alter the difficulty that much, and hopefully provides a tiny bit of variety at run-time.
Lastly, now that I had everything working, I got a little creative with the monsters. I did copy a lot of the monster behavior from DragonSweeper, but I added new monsters, variations of monsters, dropped some of the mechanics I didn't understand (gnome?), and reworked some mechanics specific to the GBA (Dracula's Ire).
After all that, I gave it to my wife, who did all the graphics and came up with the story. I wrote an 8-bit rendition of Moonlight Sonata for the soundtrack, and added final touches, like sound effects, and an in-game tutorial.
Anyways, we hope you enjoy the game! We decided to release it as Pay What You Want because we took so much from DragonSweeper, which is also a free game, so it didn't feel right to charge for the game. At the same time, if people want to give us money, that would be great, because it helps us make more games!
Thanks for reading!
Sean
- Sean aka velipso // Crypt Sweeper // Inky and the Alien Aquarium