Panda Blast!

Why wouldn't you shoot pandas? I mean they're cute, they're endangered, they're adorable... and... ah yes. They're cute, they're endangered and they're adorable, that's why you wouldn't shoot them. Anyways, Panda Blast! (not "Panda Punisher", "Pandamonium", or "Shot On The Spot") is an embarrassingly stupid game based off Monkey Blast!, an equally moronic QuickBASIC game created by Focus ZERO and released in 2001. Inspired by Missile Command, the game had you protect a stock of banana from starving monkeys, blasting them to smithereens with various firearms you could purchase in-between waves. It was violent, dumb, and simple... exactly what I needed to start working with Mode Y.

Dealing with graphics

The Jaws remake was using Mode 7, which offers a resolution of 320x200, 16 colors, and 8 pages of video memory (using all 256K available of some EGA card). Sexy Smart Slide looked better because it worked in Mode 13, which has the same resolution and can display up to 256 colors at once! Unfortunately, only one page of video memory is available in that mode, which means that you're forced to modify the video buffer as it is displayed, which tends to flicker. Panda Blast! uses "Mode Y", a tweaked Mode 13 with 4 pages of video memory, and so, more room to store graphics, and produce non-flickering animation such as a very neat Doom-style scene transition (it could easily be optimized since all slices are moving at the same rate and many checks could be moved out of loops... but like my wife said after leaving the maternity: "meh, good enough.")

Before I programmed for modern hardware (where you could just shove all your textures, sprites and miscellaneous graphics in your video card memory), I used to store everything in RAM... that's how I always handled graphics in QuickBASIC... and just because of that, I was reluctant to use the multiple pages of video memory Mode Y provides, which defeats the whole point of coding in Mode Y to begin with. Let's be honest, wasting RAM on dying pandas and ugly explosions would have been a terrible idea, so I finally settled for using the extra video buffer available.

What about sprites? There's a neat built-in feature in the VGA chipset that allows masking latch copy/pasting (four pixels at a time.) Of course, it requires a mask, and that mask has to be stored in RAM. The other downside to this technique is that sprites have to be stored multiple times "in rotation" so they would align with the first plane (it's a bit technical, there's an article available on the topic.) At the end, I went for a straightforward copy and paste from memory with software transparency (skipping pixels that match a specific index.)

I used the masking system for characters because it only required 8 bytes of memory for each character, it was rather fast, and somehow having to align characters on a 40x25 grid feels "right" to me.

I also experimented with different ways to render messages and at some point came up with an overly complex routine that would identify unique characters in the string, get offsets for each of them, and draw them in batch. It would read to video memory once, set the Bit Mask Register once, and write multiple times. It was an awful idea because the gain from the "set once, write multiple times" wouldn't compensate for the string processing time.

Let's get back on topic. Graphics are stored in a single 320x200 sheet, which is both convenient and frustrating. While exporting graphics was easy (because there was no need to quantize multiple images whenever changes were made to the palette), I kept looking at the available space in fear, wondering if I needed to pump more graphics to show off, or spare every pixel at my disposal, "just in case". At the end of the day, I think the amount of free memory is comfortable enough for you not to worry; just swap your graphic banks when you need to and you'll be fine. It's like free RAM after all.

Considering it's been a while since I drew pixel art and that I wasn't really interested in the project (it was more a proof-of-concept than anything else), I guess it turned out kind of okay? Everything was done from scratch except for the title screen which is a photoshopped picture of a yawning panda, and bamboos which were almost copy/pasted from Konami's "Legend of the Mystical Ninja". I also ripped part of the green palette from that game, which, in retrospect, was a bad choice. Greens don't look vibrant enough and make for dull grass... meh, good enough (have I ever told you about that one time my wife was in the delivery room and... scratch that.)

Bits and pieces

Monkey Blast!'s sound effects were borrowed from an early build of Counter-Strike, and thus all files were 22,050hz 8-bit mono. To keep things simples, everything but the actual sound sample was removed from sound files. The end result has no signature, no check, just plain old 8,000hz 8-bit mono raw data. Also, they were padded in such a way they could be loaded using a LONG array instead of reading each byte individually. Jumping from 22,050hz to 8,000hz was brutal. It was no problem for Focus ZERO to store large files in memory thanks to DirectQB 1.6 and its built-in EMS handling routines, but I wanted to keep things simple so it had to be done. At the end of the day, every byte of memory I spared thanks to Mode Y was used to store sounds instead (a buffer of 40,000 bytes was reserved for all the sound effects.) I regret not having multiple sounds playing at once, but I really needed to finish this thing... talking about it...

Oh dear, look at the time!

I've wasted a lot of time on this project and failed to move fast enough to keep it fresh and entertaining, which made me reluctant to go back to it. There are many reasons for this: I had no planning, often rewrote whole sections of the code, drew more sprites than needed, got sidetracked with cool ideas I had no time to implement or research,... essentially, Panda Blast only began to look like an actual game in the last two days of development. Allow me to expand on that:

I first thought the project would be simple, so I didn't focus on what I really wanted to achieve. In my head, it was summarized as "panda moves, player shoots, panda dies". It was meant to be a bare-bone demo of some sort, so why would I plan stuff ahead, right? As I progressed into the code, I began to have ideas to flesh the game out (pissing on my masterfully-crafted six-words-sentence design document.) The lack of organization shows in user-defined types, where variables that would be more suited for the current game are stored in the engine UDT. This could look like a detail, but keeping things clean would make save/load games super easy among other things. (Lip smacks) what a shame.

Mode Y was a keyring shaking in front of my eyes. I learned about it as I went and somehow got too invested in it. It's only when I began to bug-fix primitive drawing routines that I realized I didn't NEED them.

The lack of coherent plan pushed me toward flexibility. When I began working on sprites and animations, they were hard-coded. Since I had no idea how many sprites I needed, how many frames, what perspective the pandas should be drawn in, etc., I began working on a simple scripting system (which turned out to be a simple INI parser). As I needed to include new stuff like weapons and menus, I decided to rely on that one bit of code that was too easy to use for its own good. Everything I wanted to add had to work with the INI parser. I forced myself to rewrite the scripting files multiple times as to process everything through the same pipeline (thanks to some Excel voodoo, it didn't take too long.) In a sense, it's still a half victory, even though using binary files instead would be much faster and creating dedicated tools for menus would have made things far less confusing (manually linking indexed pages with indexed shapes with indexed vertices is a mess.) Lesson learned. I hope.

Speaking of menus, originally the shop was going to be a simple list of items the player could purchase, but then I decided that everything should be done with the mouse. So I began creating new graphics, more fitting for the input. I tried a few different designs until I thought it would be cool to have a nice pre-rendered image with all the guns available, where the player could just highlight a gun and purchase it right away... I'm uncertain about the outcome, but I like how the shop and the main menu look.

With no clear direction and no real interest in the gameplay, I kept wondering how to make the game cool. It felt like polishing a turd. I wanted three or four different types of enemies: Pandas that would tank more damage; Red Pandas that would be faster but easier to kill; "Trash Pandas" (Racoons) that would zigzag, making them much harder to shoot; At first, they were all meant to steal bamboo steams away (like apes did in Monkey Blast), but I revised my plans as I went. I also wanted to add walls and turrets that the player could place, a bit like a tower defense game... I gave up on that when I also realized that I desperately wanted localized damage... which I never got around to implement. I also failed to include a hall-of-fame so the score is pointless (I will claim "pun intended" because I still haven't met my quota of stupid jokes in this text.) I abandoned the idea of save games, scrapped the option menu, and decided not to fix some stupid bugs just to be done with the game (using direction vectors to move pandas would have been much easier in the long run.)

The weird balance of customizability and hard-coded stuff got me to implement some kind of modding support (essentially an array of archives and a simple loop in the file system.)

Final words (hopefully, not too final)

I wanted to write a small tech demo and ended up writing a game. It's like marrying (and having three kids) with a hooker you hired for a quickie... which is basically the plot to Pretty Woman. Anyway, I had plenty of ideas, some of which I implemented in a half-assed way so I could shove the game out the door fast (bugs and glitches are plenty.) I cut corners as much as I could, and to drive the point home, I added a classic "order me" screen. So there you have it. Panda Blast! There are some ideas here and there, but the realization is sloppy.

Oh, one more thing: I didn't tell you, when I released Sexy Smart Slide that you shouldn't chop women down to tiny bits and pieces and spend your afternoon furiously masturbating as you attempt to reassemble their bodies... because I thought it was common sense. But it turned out I was wrong (I'm not giving names - you know who you are.) Anyway, don't go around popping pandas kids! They're cute, endangered and adorable.

The game requires a mouse, a VGA card with 256K of memory, and I'd recommend a SoundBlaster 16 for the sweet, sweet sound effects (even though it's not necessary.) In DOSBox, 3000 cycles is enough to get the game to run, but I'd advise you to crank it up a bit (10000 cycles is solid enough.) Sometimes, the game throws random errors in DosBOX 0.74 with unlimited cycles, never seen that happen in 0.72 with 3000 cycles. I don't know what's up with that.