Minesweeper on the Nintendo DS
At some point last year, I had the brilliant idea of making a Minesweeper game for the Nintendo DS. But we don't talk about that one.
At some point this year though, pretty recently I decided to take another shot at the exact same idea, but with better knowledge on how to work with the system and just generally being better at programming.
Why? I don't know. I don't know why I decided to make either of the iterations of it. There are definitely easier platforms to make Minesweeper for. A website already exists. A desktop application exists. I could've made one in like an afternoon and moved on with my life.
Instead I chose the path of "What if I made it run on a handheld from 2004?"
Ah fuck.
Starting the project
The goal was simple: make a proper Minesweeper experience that feels like it belongs on the DS. The game uses the DS screens, buttons, and touch input for the game to actually feel like a handheld game rather than "Minesweeper port #323679392" just slapped onto the hardware.
Obviously, the gameplay is the same as the original has always been: reveal tiles, avoid mines, flag shit, and occasionally gamble with your (digital minesweeper) life.
The interesting part wasn't implementing Minesweeper itself. The rules are dead simple. The fun part lies in figuring out how to design it for the DS, making art, creating an "engine" (if you can even call it that, the new code is just a less duct taped banana on a wall and some spaghetti somehow on top of it while still keeping it there)
Designing around the DS
The DS has two screens (I think DS stands for Dual Screen if I recall correctly.), so one of the first things I had to decide was figuring out what shit I wanted on each screen.
The bottom screen houses some big buttons on the left, one is to reset the game, and at the same show your game status (Smiley means you're alive, the dead guy means your ass passed away from an explosion, some mf with sunglasses means you win. Good fucking job lad.), then there's also two more buttons, letting you control bombs and grid size respectively. The bottom screen also holds the grid, on the right/middle of the screen. it goes from 2x2 to 22x22 in size and bombs can go up to the grid size minus 1. Also neat thing: I implemented RNG protection, so that your first move can NEVER be a bomb.
The top screen is pretty de-cluttered, holding just your how many bombs subtracted by the amount of flags you've placed, a timer, a game logo, and my logo.
The game also has touchscreen controls. If you're lucky I have enough energy to write about it below. (I did)
Working with devkitPro and libnds
The game is built using devkitPro (dkp) and the Nintendo DS development libraries that it provides. (fun fact, I was using dkp containerized in the beginning of the project, because I had bad experiences with it on Linux in the past)
Getting started with DS development is both fun and absolutely gut wrenching depending on how it goes for you. You are really close to the hardware which depending on how you look at it is both very fun and sometimes very horrible (mainly due to lack of debugging). But honestly I managed to make a great game (in my opinion ofc) and maybe you can too. Also on the DS you usually use tiled background modes which require you to assemble backgrounds (in my case the entire game) with 8x8 tiles.
The graphics pipeline on the DS is kind of restricting, Instead of throwing an arbitrarily colored and sized image on the screen, you first need to worry about palettes, tiles, background modes, and maybe some more shit.
Using tools like grit (included with dkp) help alot because they convert your images (in this case .bmp) to formats the DS can understand, and it also generated palettes.
Working with Audio and shit
For music and sound effects, i used MaxMod. (like many others before me)
The audio system is one of those places where older hardware shows its personality. You can't really just load a random audio file from disk and play it. You have to prepare assets in the right format and use the tools designed for the platform. Not to mention these get baked into the ROM of the game.
Honestly, the setup was kind of underwhelming, there were parts I had to change in the Makefile (honestly might've genuinely taken me an hour) but the rest was smooth sailing.
Adding the singular music track to the game was a whole different beast though, because I've never used a tracker (bullshit retro ahh software you make music in) I had to learn that, which was hard. (actually just made the track in LMMS and exported it to a .mid file and imported it into OpenMPT) finally after literal HOURS of trying, I got the track in (deadass just a bass track, cause I love bass so much. and the only way to mute the music is to mute your entire DS)
Actually, since one, two or three versions ago, I swapped the track for an atmospheric synth sample with some chords.
And I actually made a volume control for music and sfx
The annoying parts
Of course, working with ancient hardware is bound to come with challenges (I already mentioned a few)
DS development has a lot of small details that are easy to get wrong. A wrong background configuration (this was actually the demise of a different attempt at this game, which I didn't tell you about) can (pretty obviously) end up with literally nothing showing up on screen.
Then you spend your beautiful 2, 20, 200 minutes trying to debug it (YOU CANTTTTT BECAUSE THERE IS NO SCREENNNN) and wondering where you went wrong, eventually doing an ancient ritual for the Nintendo gods before it finally agrees to display your dumpster fire.
(The ritual is usually "read the documentation")
Fortunately libnds has documentation.
What I learned.
Surprisingly little if I think about it, maybe if I ponder more I'll realize how far I've come.
Making a Minesweeper clone for the DS isn't exactly pushing the limits of any hardware. The only limit I'm pushing is palette sizes.
Now the Nintendo DS can play Minesweeper. (Someone has definitely made this before)
Controls
While on the grid
- A: Reveal tile
- B: Flag tile
- D-Pad: Move the cursor
While in the menu
- A: Activate the selected button
- D-Pad:
- Up & Down: Navigate menu buttons
- Left & Right: Change values on buttons that support it
Menu items
- Face: Shows the current game status
- Pressing it (A or touch) resets the grid
- Bomb count: Change the number of bombs (D-Pad)
- Grid size: Change the grid size (
x*x) (D-Pad) - Difficulty: Scroll through difficulty presets (D-Pad)
- Music Volume: Set music volume (D-Pad)
- SFX Volume: Set the volume of sound effects (D-Pad)
Anywhere
- Select: Switch the cursor between the grid and menu
- Start: Reset the grid
Touch
- Grid tiles: Tap an unselected tile to move the cursor there. Tap it again to reveal. Hold for .25s to flag
- Menu items: Tap to navigate and activate buttons.
Ouu shii it's 3 AM.
Yes I wrote this at night time and my legs hurt because for some reason I need another growth spurt.
I blame this for my horrible writing (please ignore the sentences that seem like they feel down a damn staircase)
(This blog post is 7 kilobytes big)
I may have slightly overexplained Minesweeper.
But it's fine, because this is a completely different Minesweeper. This one has:
- two screens
- a cursed tile-based graphics pipeline
- a soundtrack consisting mostly of me asking "why won't OpenMPT do the thing"
Totally different. Trust me.
Also download here