Pretty banner! :)

4k Flash Game Post Mortems

Falling With Style Post Mortem

falling_with_style

Project Introduction

“Falling With Style” was the name of my entry into the first GamePoetry 4k competition.

I heard about the comp both from the Gaming Your Way and 8-Bit Rocket blogs, and it instantly appealed to me. I really enjoy short game development competitions, and feel that they are an excellent way to hone my skills. Normally I enter speedgame competitions, but this was the first time I’d been under a space constraint. I had only recently seen Left4kDead, and so with dreams of wow’ing the judges, I started out on my game.

What Went Right

1. Procedural Graphics FTW

I’ll be the first to admit, I sortof went about this competition backwards from how I normally do game development. Normally I focus on gameplay, and leave the graphics as an afterthought. But as being this is a 4k competition, I thought that if I could try to squeeze some impressive graphics into the game, I might have a better shot at placing in the top two, and given the space constraints, I wanted to explore what graphics options were available before I started thinking about gameplay. Being inspired by .kkrieger when it came out in 2004, I felt that there was a lot of ripe opportunity for procedural graphic generation in this competition. I searched around until I found the Perlin noise generator in Flash, and was instantly hooked. I spent time reading about Perlin noise, and was very interested in some of the animated cloud demos I saw. I soon learned that you could animate Perlin noise in Flash through use of the Offsets Array, and was soon playing with different ways of painting animated clouds. I was very pleased by how small the test applications were, and had a nice misting cloud example that compiled to a mere 979 bytes. This was a definite good thing that happened early on in development.

2. Finding an Idea that Fit

After determining what sorts of graphics we wanted to use, we settled on a good game idea pretty quickly (though somewhat simultaneously). After I’d started learning to using Perlin noise for the game, a friend of mine and I were discussing minigame game ideas based on a friends’ comic book series. One of ideas he suggested for that project was a skydiving game, and it instantly appealed to me for use with a Perlin cloud generator, and I decided to prototype his idea by using it for my 4k game. Thankfully, he didn’t mind at all, and in fact really seemed to enjoy having his idea spring to life so quickly.

3. Playing Darts with 3D Math

Next up was trying to get the visual look of falling towards the ground through successive layers of clouds. I’ll admit, the math was pretty tricky, and, still being new to the math behind Perlin noise, I wasn’t always sure how to scroll it around and zoom it as well. One of the big blessings I hit early on in the development was getting my guesses as to the 3d math equations right on the first try. One thing that was tricky to synchronize was the movement of the targets (drawn with the Shape class) and the movement of the clouds (moved by adjusting both the ScaleX and ScaleY parameters, and the under-documented Offsets array). Thankfully, I hit upon the perfect scaling factors pretty quickly, and was able to draw these two items on the screen with two vastly different methods, and still have them move synchronously.

4. A Little Help from my Friends

I was very blessed to have some good friends tell me plainly what I had done right, and where my game needed work to be fun. This was difficult in that the criticism came with only a week or so left in the competition, and I was already way over budget at 4800 bytes. Thankfully, Charlie really stepped up and helped me with the math behind an algorithmic level generator, and finding levels that made sense, and what reasonable minimum scores for each level would be. He also really helped me with my ground texture generator (which previously had been static), and making it able to change with each level. At this point in the competition, I was burning out, and his willingness to dig in and understand my code was a most timely help.

5. Leaving Some Headroom

I’ll talk about this more in What Went Wrong #4, but when things were realized to be terribly wrong with an hour to go in the competition, I was able to fix things because I had saved myself some bytes. For my persistent local high score code, I wrapped two sections in try/catch blocks. These exceptions would only be thrown in extreme cases (paranoid people who disallowed local storage on my game), and as such, I could probably fly dangerously and remove the blocks. Experiments with taking the try/catch clauses out saved me about 150 bytes, which was pretty significant in the late game of the competition. Still, I didn’t feel comfortable taking them out unless I had a compelling reason, so worked very hard to be able to keep those try/catch blocks in the code.

When things started to go wrong though, it was truly a gamesaver to be able to remove the try/catch and have an extra 150 bytes for fixing problems.

What Went Wrong

1. Lack of a Preprocessor

Throughout the competition, I kept thinking that I should probably employ a preprocessor of some kind to shrink my game. I had a number of constants at the top of my class, and I knew that the AS3 compiler wasn’t efficient with in-lining those values the way a #define would in C. But as I was space-crunching my game, I decided to try (just to see…) how far down it would go by find/replacing my variables with a register array, and hard-coding all of my constants, etc. At first I was careful to undo some of these one-way changes, but… well… one thing led to another, and I never wound up going back. My code from this point on was cryptic, and though I started making very liberal use of comments to explain to myself (and any friends who were giving me code reviews), it still hampered my development for the last week.

2. Determined Resolution

Early on in the development, I was drawing the ground texture, and all of the clouds and targets for every level on every frame. To get things to a playable speed, I lowered the resolution of the game. Then, in order to speed things up even more, I made use of the Octaves parameter of the Perlin noise generator. This parameter allows one to specify the amount of detailed noise that is put into the texture, and for textures that were further away, I used this to implement a simple Level Of Detail (LOD) scaling for my cloud and ground renderers. I then extended my LOD even further, by simply not drawing clouds if they were too far away from you, and as they start to come in range, fade them in with an alpha blend. This LOD all worked great to improve the performance of my game, but I never went back and bumped up the resolution of the game again. As such, I was a little stuck. If I had gone ultra-low resolution, I could have gotten away with being “retro”, and if I had gone high res, I could have passed the game off as “smooth and shiny”, but as such, I was stuck at an annoying middle that was neither very retro, nor very high res, but it just felt “last gen”. By the time I realized this, I had already replaced all of the constants in my game with hard-coded numbers (see What Went Wrong #1), and I was too busy with other things to hassle with it.

3. Limited Control Scheme

Pilot Wings is a fantastic game, but one fundamental thing in the control scheme couldn’t be easily cloned — the rotozooming. Pilot Wings used Mode7 graphics, and so your two controller axis adjusted forward/backward tilt (x-axis rotation), and your spin (rotation about the Z axis). However, even with my LOD optimizations, I didn’t have the cycles to spare to do arbitrary rotation on every frame cycle. As such, I had to settle for using a modified control scheme, rotating one’s player about the x-axis (for normal front/back tilt), and about the y-axis (for side-to-side rolling). This would be a fine control scheme, if so many people weren’t used to PilotWings. This control scheme was fine for normal free-falling (belly to the ground), but for time-bonus speed runs (with one’s head pointed downwards), it made it extremely difficult and unintuitive to control. Thankfully, we were able to isolate this difficult aspect of the control scheme by creating a special “acrobatic mode” that would let you put your head down if you were an advanced player, but normal players could progress through about half of the levels without using acrobatics, and could simply use the default control scheme. I felt that this was perhaps one improvement that we made over Pilot Wings, but even with this change, the controls were still a rough point. As Pany pointed out in the judging, perhaps this could have been better addressed with mouse control, but we were already so over budget, it would have been a squeeze to fit in the math for proper mouse control.

4. Hint: Understand the Rules.

Because the rules had it posted: You must provide the ability for me to build your game from Flash Develop (using the Flex3 SDK) or Flash CS3. Flash Develop supports importing Flex Builder projects, so Flex Builder is probably okay.

Without taking time to clarify with Urbansquall, I assumed that the CS3 requirement meant that Flash 10 was out of the question. So because I really wanted to add sound to my game, I wasted a lot of time looking into cuttind down the Popforge sound .swf generator into a reasonable size for 4k. Because I was also trying to add level progression into my game, I simply ran out of room, and never got this implemented into my game, but I still spent at least one or two evenings on this, with nothing to show for it. If I had realized I could have used Flash 10, that would have saved me a lot of time and headache, and freed me up to work on some other things.

Something that almost messed me up worse than all of this, is that (largely due to habits from other game competitions) I’m used to the Readme being used for instructions on how to play the game. If I had taken the time to fully and carefully read and understand the rules, I wouldn’t have gotten myself into such a pickle. As such, on the morning of the end of the competition, I realized that this hiccough with my assumptions about the Readme, and, with about an hour left in the competition, I worked hard to squeeze in some simple in-game instructions. This was particularly difficult because I had already squeezed myself about as tightly as I could into 4096 bytes, and didn’t have a lot of headroom for long instructions, but I also had a complex control scheme (involving the arrow keys and two buttons, with several interactions between them) that wasn’t simple to explain.

Thankfully, as mentioned above, I had given myself a 150 byte failsafe in the area of some optional safety code that I had been resisting the removal of. With the clock ticking down, I was able to get the spare bytes, add some instructions, and add it to the game. A few frazzled nerves later, the revised submission was sent and acknowledged, and there was nothing left to do but wait anxiously for the results to come in at the end of the week.

Conclusion

All told, this was a fantastic contest, and I learned so much. I’m so impressed by all of the competing entries, and I’m just thankful that I think I did near my best.

Before this competition, I had only done a few projects in Flash, and I think I can credit the motivation from this competition for now having made me much more comfortable in it.

Thanks again to my supportive family for encouraging my entry, and for Urbansquall for hosting the competition. I’m already daydreaming about the next one! :-D

Pages: 1 2 3 4 5 6

Post Metadata

Date
March 20th, 2009

Author
urbansquall

Category


Leave a Reply