LD14 April 17–20, 2009

DoomDrive Postmortem

Since I want to learn to write good blog posts, I would appreciate any feedback about which parts of the following post you found interesting. I tried to make it not dull. Hopefully you’ll learn a couple of new game design tricks or something. And if you’re not a programmer, just ignore any code, you won’t miss much.

The wiki mentioned that I should keep a log of some sort as I develop my game. I decided to write short entries in a txt file, then thought I would post it all when I was done. Now that my game is finished, I thought it would be a good idea to expand this short log into a full commentary-type thing of my Ludum Dare 14 experience. I will describe the development of DoomDrive in detail in the hopes that someone will find this interesting. Maybe this will make up for not doing a timelapse. Note: In this post, all times are EST and entries from the original log.txt file are italicized.

SF’s devlog

The first real language I learned was C++, I started learning it at age 11 when my older brother gave me a book about it. I didn’t know anything about compilers then so I couldn’t even write a program until much later, but I absorbed the information with great interest anyway. I love C++ for its speed and the amount of control it gives me over my code. When choosing graphics and sound libraries to start learning I did a few comparisons and settled on OpenGL with GLFW helper tools, and OpenAL. I haven’t had too much trouble with these (though my OpenAL knowledge is limited) and they’re what I know best so they’re what I used to make DoomDrive.

Car sketch

Saturday morning (18apr09)

2:40 – Forgot about LD for the past couple days, remembered it just now.
The contest began at 23:00 on Friday, so it was 3:40 in. I had decided to start developing a game (unrelated to any contests) a week before. It was to be my very first serious game (a space shooter, heavily inspired by the rather obscure Hell Fighter). I’d done enough half-projects experimenting with the aspects of game design – code structure, physics, graphics, art, sound, game theory, etc – that I knew I had a good grip on making games… I just hadn’t done it yet (other than a GameMaker game I made at 14, and of course Tetris). My problem was I never felt like doing anything. But over the past month I’ve been working on my mindset and setting clear goals and all of that personal development nonsense, so I finally felt ready to begin coding my first game ever. I did. Then I found out about Ludum Dare from browsing java4k-related stuff, realized it was gonna be the next weekend, and wondered if I should try it. I voted on the first three rounds, still unsure if I would participate, then kinda forgot about LD as I concentrated on coding my space game. I remembered it at a convenient point in time, thought “now or never”, checked out the theme, and immediately started thinking up ideas. Well, it didn’t take long to come up with one…

3:05 – Idea: Drive a 3rd person 3D car around a forest and ramp off rocks to get away from the wall. I haven’t done much 3D in OpenGL. I will most certainly get stuck on bugs until it’s too late. Whatever.
My conceptual vision also involved pools or rivers of water that you had to jump over by driving off cliffs. It just seemed fun in my head so I went with it. I was a bit pessimistic about it. It might have been because the idea of making a game in 48 hours sounded so absurd; I always thought a decent game would take at least a month to complete. More probably it was just a safeguard against being disappointed when I failed to live up to high expectations for myself.

5:05 – Should I sleep? I hand-coded a car model and not much else is working yet.
My idea meant mostly procedural, randomly-generated content. I love procedural, but the car model would have to be designed by hand. I began drawing it out as soon as I picked out the idea, because that seemed like the most natural thing to do at the time. Since it was so simple, I just punched in the numbers in a const array, remembering to keep vertices of quads in clockwise order (I later found out counterclockwise is preferred). The model (and the game idea in general) was probably influenced by Twisted Metal 4, a PSX game I played a LOT as a kid. My favorite car was Orbital.

Ambient lighting effects

Check out those ambient lighting effects. I chose these colors in GIMP. I thought the car should be a different color but the light gray sorta stuck.

5:30 – I’m making elementary math errors because I’m sleepy, so I will rest before continuing the game. Night.
I think this was when I was trying to figure out OpenGL lighting. I dunno why I did the most graphical parts of the game first, probably because it was what I would have to look at for 48 hours, and it’s more fun to code a pleasant-looking game. I never programmed lighting before but I figured I only needed simple stuff so I could learn it in time. I seem to understand complex ideas pretty quickly, at the expense of poor memory of concrete information, like names of functions, or the fact that Ludum Dare starts today. I think it helped that I slept twice during the compo, so that I worked for what felt like three days instead of just two. The best ideas happen in bed, and I like to think my brain is subconsciously thinking about things while I sleep.

Saturday

13:20 – I AM UP! I’ve been coding in my dreams all night long, let’s see if that helps me any.
That night I had the odd experience of watching a half-dream where a programming problem appeared as code before my eyes, and I solved it without consciously thinking about it. I think it was a premonition.

Incorrect lighting

This seems incorrect somehow.

16:20 – Stuck on a dumb lighting problem like I expected to. Losing motivation. I’ll just ignore the problem for now.
17:05 – I couldn’t ignore it. The problem is lighting needs normals that I haven’t worked with much and mine are kinda wonky.
I made the mistake of trusting some lighting tutorial example code that seemed wrong at first. Wasted too much time on this and felt dumb afterward. I never did get directional lighting to work, which would have made sense since I wanted sunlight. I just did a point light that’s a fixed position from the camera. It looks about right. I didn’t even bother with specular or smooth shading, I knew I wanted the simple flat look when I first thought up the idea.

XYZ arrows are colorful

MERRY XMAS! Note: This screenshot does not demonstrate proper debugging procedure, don’t try to understand it.

Foggy hills

Yeah fog! The car just hovers so far. I made a hazy sun by rendering the inside of a huge cone a fixed position from the camera (like a skybox) with the center almost white and the edges sky blue.

17:50 – FIXED IT! Now on to making game mechanics.
I believe I was messing with the car speed and turning and friction around this time. I obsessively tweaked these throughout development, up until the very end. I’m glad I did because the controls contribute a lot of the feel of an action game, though I still think it could be made more fun. You’ll find that I left in the code to tweak game constants if you press a number key or insert/del/home/end/pageup/pagedown and look at the stdout. I did something like “float SPEED=tweakvars[1];” in the game loop, ran the game and adjusted the value with those keys, and when I settled on a value I changed tweakvars[] to initialize accordingly. It’s a primitive system but it did the job.

Impaled car

The entirety of my collision detection code:
car.z<groundHeight(car.x,car.y)

19:10 – Well, at least it looks fancy. I’m gonna eat dinner.
21:20 – Time to figure out perlin noise terrain, then I will have awesome screenshots. My morale is back up and I’m doing way better than I expected, although I don’t think my forest is gonna have any rocks or trees. It’ll still be fun to drive around hills.
By this time I had a fairly clear vision of where my game was going.

21:40 – I’m humming tunes. I hope I don’t go insane from non-stop coding. I will listen to noise music for a while. I don’t know if doing that has any mental effects that are beneficial to programming games, but noise usually helps me clear my head.
Also tried trance. It seems to help at first, but becomes a distraction once I’m in the zone. I took a reasonable amount of breaks, but other than that I had been coding nonstop that day AND the day before (my space game), so I was already getting worn out.

Scratch work

Here you can see me trying to figure out vertex orders and terrain slope calculations. This is just scratch work so it’s probably wrong. I only write in cursive so people can’t read it at a glance (it’s actually less efficient than print).

22:35 – OH SEGFAULTS! My goal is to finish the terrain and the car “physics” before I go to bed so I can add the actual wall and maybe a little sound tomorrow.
Spoiler: The car is actually a single point. It does physics by controlling z height based on things like slope of the ground at x,y – the game is essentially 2D. The terrain is an array of z values. The car is either on the ground or flying. When not flying, the point follows the slope of the ground. When it crosses an edge between triangles, it checks the angle at which it hit, so that if the ground is curving up the car slows down, and if the ground is curving down the car ramps off into the air. However, there’s a problem in that this angle checking doesn’t happen when you land (only when you drive across an edge), which means if you’re flying and you land on the very tip of a hill, your forward velocity will not be updated to account for it, and you will get pushed up the slope way too fast, causing you to fly really far. This is a gamebreaker that I intend to fix in a postcompo version. (Note: The physics are actually an inaccurate fudge I came up with by just guessing at how the car should behave, and adjusting it to be playable. The postcompo version will be much better.)

A beautiful view

The game doesn’t change much visually from this point on. Though I wanted to tweak the colors at the end, I didn’t have time and decided that was just polish for the postcompo version. Blue ambient with orange diffuse light worked pretty good. I noticed from using Hammer (the HalfLife 2 map editor) that shadows should be rendered blue (not gray) when sunlight is yellow – complementary colors.

00:05 – EPIC SCREENSHOTS! Just the car physics left now.
You can see that the procedural terrain gets generated as you drive. It’s stored in a 2D circular buffer, which was a little confusing to figure out how to do, but is very efficient (a single array on the stack). Random hills were accomplished with perlin noise. I made some with varying roughness factor (using perlin noise to vary it) roughly in the range 0.0 to 1.0, raised it to the fourth power to flatten out low areas (fourth power is called “quatric”), and of course scaled it to a proper height. The noise function returns a random value seeded by x and y position, so the infinite terrain stays the same every time you play. I figured if it changed all the time people wouldn’t be able to make maps of the best routes. No, no one would be that dedicated. I hope.

01:20 – But I mess with the camera instead. Getting sleepy.
The camera was another thing I tweaked all throughout development. My photographer side definitely had a hand in this. But again, I’m glad I worked so hard on it, camera problems are frustrating and awkward for the player. What bothers me is that you never get to see the awesome epic wall of fire in all its glory until you die, unless you turn around like I did for my official screenshot, and there’s no reason to do that. I considered adding a rearview, but what’s the point if it’s only there for looks? Maybe I’ll add an attract mode that shows the wall from a better angle.

02:10 – Decided on “Doom Drive” for the name. Physics will have to wait til tomorrow. I am falling asleep. Night.
04:10 – Ate, washed, went to bed, couldn’t sleep, but got some ideas. I always get ideas in bed. Ideas: I will reward airtime with a proportional amount of boost. The terrain will get more and more intense over distance, as a difficulty curve.
I knew I was going to bed way too early, but I was so tired of coding that I thought I’d fall asleep right away. I’m glad I got the boost idea because until this point the game was about finding the flattest (most efficient) route, and I wanted it to be about RAD AIR!

Why am I floating

Why am I floating

05:05 – My car is floating aughhhhh oh no
05:25 – YEAH GRAVITY!
In my exhaustion my log entries have degenerated into basic feelings about what was happening at the time.

06:30 – God, there are so many bugs with driving backwards and stuff. Hmm, 16 hours left. Going to bed for real now. Night.
If you’re gonna use something like negative velocity values for driving backward, make sure to REMEMBER that when you do calculations. It can get frustrating to get stuck on a bug where your car falls through the ground when you drive backward. Humorously, before I added flying, gravity, and fixed the backward movement, the game played a lot like Big Rigs.

Sunday

14:40 – Slept nicely. Final stretch, here we go.

Concept art

Worst concept art I’ve ever drawn. The music was actually gonna be just a repetitive trance beat, but making that sound good procedurally would take way too long for me, as simple as it is. I’m really sad I didn’t get to adding scoring, at least a timer, but I thought it would require displaying fonts, which I didn’t have time to figure out when I realized I had to.

Burninated! This is the first firewall (looked less refresh linesy in-game). Here the fire looks like crap because it’s a lit material instead of a plain color. Fire isn’t supposed to have shadows on it.

16:55 – Finished the firewall and boost mechanic. If I add a HUD and tweak the wall speed I will have a working entry.
19:35 – Woo, it’s playable! I will add boost effect and cam shake for fun, then submit.
DoomDrive has three kinds of fire: the enormous wall of destruction, the boost flames coming out the back of the car, and the car burning as it tumbles into space when you lose. They’re all just triangles with vertices that are randomized each frame. The boost flames are each a single triangle, but if you ask me they make a pretty effective flame. I like my burning car flames way better than a lot of the graphical fire I see in commercial first person shooters like HalfLife 2. Then again, I was never much into realism. Cam shake is the best thing ever. I knew the wall of fire wasn’t giving off quite the feeling of horrible doom and despair I wanted it to when it caught up with you, so I came up with cam shake to fix that. I think it worked.

Second firewall

These fire colors were a little too cartoony. I like everything to be desaturated and sad.

21:45 – 1 hour 15 minutes left and I am as finished as I will be. The game now features driving a car in 3D around rough procedural terrain with a wall of fire chasing you, a boost meter that increases with air time, with fog and a procedural noise algorithm I developed a while ago for sound effects. It’s almost over…just gotta see if it compiles on Windows. I’m sick of coding, but I’m really happy with what turned out.
Oh yes, the audio. I’m kinda into noise music, and I’m totally into procedural generation, so one time I made a procedural noise synthesizer that could be controlled by moving the mouse around a square window, the x and y values mapped to the two controls. It seemed obvious to reuse some of that code for sound effects for intense fire. Ogg audio demonstrating the noise synth.

22:45 – 15 minutes left. Submitted linux version. Gonna go try to compile on Windows. Wish me luck.
I ended up working on final touches for an hour. At this point I was in a bit of a code trance, completely exhausted from the past two days and starting to get apathetic.

00:15 – Last entry: One hour fifteen minutes past the deadline, Windows version compiled. Though it probably has crappy sound. Whatever. I’m done.
It only had crappy sound on my crappy windows box and apparently worked fine elsewhere, besides being lagged due to the way I tried to fix a problem with audio skipping in between buffers. Thanks to DrPetter for helping me get the right OpenAL libs since I couldn’t download the SDK on dial up.

END OF LOG

Wireframe

Holes in my car

Some of my vertices turned out to be in the wrong order after all. Shoutouts to my good friend in Devon, without whom I probably wouldn’t have figured this out in time.

All in all

DoomDrive flew in the face of my own expectations for it. I’m happy. However, I’m friggin sick of coding, so I don’t know how long it’ll take before I recover enough to do a postcompo version. I want to make the game feel complete, though. I got this far, why not finish it off?

Ludum Dare has been a good lesson in getting the most bang for the buck. Things like fog effect, random triangle fire, cam shaking, are all very simple to implement, but add a lot to the game. Also, I learned you don’t need a full blown physics engine to have physics, as my single-comparison collision detection demonstrates. I never thought it was possible to make such great games in such a short time. This is definitely a motivating realization.

DoomDrive is the first serious game I’ve ever made, and I think it’s safe to say I’m gonna be doing more action games in the future, hopefully for a living.

It’s been beautiful, guys. On to voting.

Tags: postmortem

Comments

22. Apr 2009 · 03:34 UTC
I don’t know why but I love seeing paper designs, makes me want to get off my butt and do those too.
Simon
22. Apr 2009 · 19:00 UTC
Far more interesting than a timelapse. Thanks!

Post version update.

I made some small post version fixes, namely correct viewing angles when entering/exiting portals.

And now portals no longer have a push effect, so velocity out is the same as transfered in.

Being post fixes this version cant be judged on, due to the fixes effecting gameplay slightly.

You can grab it here:

PORTWALL LD.zip

Schlepping a canoe across the Andes…

Or, to put it more succintly, port. For the questionable joy of those of you wishing to combine your passion for dropshadows, love of BSD, and desire to vote on LD entries: you need wait no longer! I have assembled an OS X port of Put the Ball in the Bucket. Proof:

A confession: I don’t really use the ‘unlikely purple nebulae’ background; I just turned it on for Zomg Running On A Mac appeal. This is exactly identical to the contest windows version, so feel free to use it for judging.

Of course, if you prefer your operating system to hail from Washington State or Finland, rather than California, you can still get the Windows or Linux (i.e. python+pygame sources) versions.

Tags: mac

Comments

Cosine
21. Apr 2009 · 20:55 UTC
Restarting shouldn’t remove the pieces, and the physics shouldn’t be in effect (affect?) until you start. Other than that, nice looking.

A more recent build

This is a more recent build of my Ludum Dare 14 entry. It includes several bug fixes, a significant improvement in the AI, and a new enemy type. The visual effects have also been toned down to the point where it should be almost possible to tell what’s going on.

I think at this point the most significant issues with the game are the unreliable level generation, lack of optimization, and the steep learning curve.

Play the game

Comments

21. Apr 2009 · 13:00 UTC
I think you should post it to newgrounds…
21. Apr 2009 · 13:57 UTC
PS: This build made the game more ‘interesting’ but at the same time it’s frustrating. You could make it playable once more by removing the “purple thing upper limit”. otheriwise it’s too unbalanced towards red.
22. Apr 2009 · 06:58 UTC
Well, never mind that. I didn’t realize I could place the green things.

Win32 build is now available

I fixed the build scripts and libraries so that it can create Win32 builds again.

It’s still not much, but if you are interested in judging it for the compo, check the link at:
GBGames Presents a Very Unfinished Game: Walled Off

I do plan on finishing this project so that it has some semblance of game play. I really liked what I was going for and feel pretty down about how little I accomplished.

Bunny Press source code

I forgot to include the source code in the original release, so here it is.

superflat’s Balls Of Legend: Postmortem

 

I suppose the thing I’m most happy with is that it the first compo I’ve entered which wasn’t a massive crunch to get in on the deadline.  I was enjoying a nice cup of tea by 10:30pm.  Heres are some fun development facts:

– The game took about 12 hours.

– I used Photoshop and Logic Pro.

– I wrote it in BlitzMax with lashings of OpenGL.  

– It formed by ripping apart the level editor for my iPhone game, which also uses the same orthogonal perspective.

– The graphics were based on another game concept I’ve currently shelved, a Rez-at-light-speed interactive music game called ‘Tempo’.  

– I don’t like the bounce sound either.  Wish I’d spent more time on it.

– I have loads of ideas to expand on it, from springs that fire you down corridors to one-way floors, switches and doors, powerups that enable you to open up new paths, crushers and electric fences you have to jump.  

– I’m keen to try it on the iPhone, where the tilt determines the angle of your next bounce.

– I’m especially keen on trying a two-four player mode, which could be both co-operative and competitive (both bounce on two switches to open one door, but the first through gets the best loot!)

Anyway, thanks for having me Ludum Dare.  I’m sure I’ll enter again sometime.  And post food pics / timelapse shots which I had no idea about until after I’d finished!

 

Updated Wallcraft – Minor Changes and upgrading Guide

Made some changes based on suggestions from voters.

 

  • Fullscreen mode can be activated with tab key, window can also be maximized.
  • Menu now controlled with arrow keys and selected item chosen with enter instead of using the mouse.
  • Minor bug fixes.
Updated version and the original version made within the time limit can be found here. http://gamejolt.com/games/rpg/wallcraft/65/ Guide to upgrades: Castle / Upgrade Guide: Sword – Strength, how much damage you can deal with your sword. Cross – Health, how much damage you can take. Raising health is the only way to refil it. Magic… thing – Magic! Does twice the damage of your strength. Magic has limited ammo and must be  rifilled at a castle. Magic can also be fired at the wall to slow it down slightly depending on your  strength. Square/Little Dude – Soldiers, they slow down the wall when deployed. Upgrading at one of these  castles gives you an extra soldier. Coin – Money, each upgrade cost 10 gold. Gold is aquired through killing monsters. Upgrades are necessary if you want to get a good score. While the enemies will get tough if you  upgrade, you still can’t last long with out them. The soldier upgrade is needed to slow down the  wall, which will grow faster than you quickly without them. But buying soldiers will still make the  enemies you fight more powerfull, so you need to upgrade your strength, health, and magic as well.

 

Corrected link — if you want it

Sorry about that. The actual download link is http://dl.getdropbox.com/u/972220/secret_knitter_LD14_Wall.tgz

That’s what happens when you wait til deadline minus 30 minutes to figure out where to upload. Thanks to a commenter on the “How to submit” entry, I was able to sign up for a dropbox account, upload my game and submit a post with a link — all  before the deadline!

Um…did I mention that the link was incorrect? I didn’t have time to actually read the documentation on how to post a public link; just shot from the hip.

You don’t have to bother with  this entry, if you don’t want. The artwork is minimalistic (I’m still stuck on the Minimal theme — man, you should’ve seen the game I produced for that one; although way over the time limit), gameplay is hardly there — you can play one level, but it always lets you win.

I will make fixes, artwork, packages (of the fixed game for windows, mac). But all of this, later.

I’ll post a post-mortem, and food pictures (Large chai, raspberry coffee cake from Allann Bros cafe — Free Plug — do I get free coffee now? Aw, nuts!)

Mostly, I just wanted my profile to show that I finished _something_ for a change.

Most importantly, I had fun.

Deathbeam Postmortem

Long post, more after the jump, but the headlines in summary:

  • Learning from past mistakes
  • Step #1: Add tile mapping
  • Step #2: Add collision detection
  • Step #3: Add physics
  • Step #4: Evolve game concept
  • Step #5: Iterate gameplay
  • Step #6: Build-out and polish
  • Step #7: PAAAANIC!
  • Step #8: Deep sigh of relief… followed by panic

Learning from past mistakes

This was my second Ludum Dare, and I learned some lessons the hard way in LD10:

  • Coding for games is not the same making a game
  • Make sure your toolset includes everything you need to make a game
  • Make sure you are comfortable with your tools
  • In 48 hours, a simpler idea that you are sure has good gameplay is better than a creative one that might have good gameplay if you do it right
  • Art and sound is secondary to gameplay

All of these seem obvious to me now, but I failed on all of them in LD10. The end result of my work was something that vaguely resembled a game, had some gameplay elements, but wasn’t actually a game you could really play.

I spent far too much time trying to come up with a good idea, working on art, and learning Gosu. I didn’t have any sort of map editor and spent most of my time coding tools and base code to do a game. I had a lot of previous experience doing chunks of game code and technical experiments for games, but had never finished a game before, so I got blindsided by a lot of things (no scoring, no win conditions).

So, learning from my mistakes for LD14:

  • Didn’t have base code for Pyglet, but I had an idea how to organize things. Many concepts from LD10 for code layout were applicable.
  • Knew I was going to use Python, Pyglet, and Tile Studio, and had used them before. Having experience here was a huge plus.
  • Came up with a simple idea right away and didn’t deviate from it. It didn’t feel innovative, but I was pretty sure the gameplay would be fun.
  • I tried not to make ANY art except when required to test gameplay, and used polygons+color for test art (which ended up being the final art).

My initial concept was to have a tall building filled with personnel. Aliens attack it: their ship is firing a beam down through the building killing people, aliens are busting through windows on jetpacks. You kill one, steal a jetpack and fly around saving people and shooting aliens.

Step #1: Tile mapping (3 hours)

DAY1 NIGHT

I wanted the game to be tile based, so I fired up Tile Studio and wrote an exporter to save directly into Python code. This way I could just import the Python file and write a loader. Loading the tile images and splitting them up was easy with Pyglet.

I didn’t wanted to create 16×16 tiles, but wanted them to be scaled up to 64×64. It took a while to figure out how to set the textures to GL_NEAREST in Pyglet (not hard but it wasn’t immediately clear).

Late night coding killed my progress because my brain wasn’t working. My map was exporting with (0, 0) = top-left, +y down. Pyglet has (0, 0) = bottom-right, +y up. After spinning my wheels for WAY too long, I ended up just reversing the row order during loading and the problem was solved.

Step #2: Add collision detection

DAY2 MORNING/AFTERNOON

Tile Studio allows you to place edges in a map cell to mark collisions. I wanted to support collisions on the top, bottom, left, right, and on bottom-to-top slopes. It didn’t take too long to get the first version working. Unfortunately, the initial collision detection had a lot of bugs.

First problem: you would get pushed out of the tile in the wrong direction (run into the side, popped out the top). I changed it to only collide with edges that opposed their velocity, and that fixed that.

The second, bigger problem was that I was only checking the movement end position, instead of checking the whole line of movement. On certain edge joints, players would would fall through. Bounding volume collision for the movement would take too long, so I had to find another way to fix it.

I struggled for quite a while, but ended up solving it with a hack: I added extra edges on the interior cells people fell into, and ran collision detection twice every frame for the player. The player would still fall through, but the first pass would push him up out of the incorrect tile, and the second pass would push him back out where he was supposed to be.

Although ugly, the solution worked really well — and hey, LD is all about hacks. 😀 The final release had a bunch of collision detection bugs, but that was due to me forgetting to place edges in most of the last third of the map in the rush, not due to the hack.

Step #3: Add physics

Now that I could collide, I started writing some simple physics. I spent WAY too long tweaking this. Originally, you would only use the jetpack bursts, and were to walk a lot (think Halloween Harry). I spent a lot of time tweaking the jumping and walking.

That sucked — because I ended up getting rid of jumping and walking once I added the jetpack. One day I’ll finally learn the lesson about not polishing a product early.

Step #4: Iterate game concept

After adding the jetpack and a simple death beam (that didn’t kill anything, but moved), I started flying around the test map and realized that something was off.

The vertical building for a map was just not going to work, for a couple of reasons:

  • The beam’s horizontal movement v.s. your vertical movement didn’t make sense.
  • Walking and jumping were boring after getting a jetpack
  • There wasn’t enough room to cut loose with the jetpack inside
  • It didn’t look like the inside of a building, and I didn’t think I would have time to do enough art to make it look like it

I decided to change the map to be outdoors, and have the user flying left to right, instead of bottom to top. The gameplay could stay mostly the same, except the user would use the jetpack most of the time and would have infinite fuel.

Step #5: Iterate gameplay

DAY2 NIGHT/DAY3 MORNING

I was getting really scared that the concept wouldn’t work since I didn’t have any gameplay yet. I went into overdrive hacking together some temporary tests, and added a civilian pixel that I could grab and pick up and carry around, with the beam chasing me.

The movement felt great, but I didn’t feel enough pressure that beam was right behind me about to kill me. The beam was to your left, but your were constantly moving to the right, and didn’t see the beam. There was nothing slowing you down to keep the beam close to me.

I bounced this problem off of Entar and he threw a ton of ideas at me. Two of them really resonated: tunnels forcing users to backtrack, and turrets. Both were super simple and didn’t much code; tunnels were just part of the map, and turrets just sat in one spot and shot.

I threw both in and it made a HUGE difference. Suddenly it felt like you were fighting a battle. The crappy turret aim ended up hitting the civilians I was carrying instead of me most of the time; but, this ended up being more fun, so I made the player invulnerable to turret fire. You can actually use him to block shots if you’re really good.

I didn’t have a way to actually rescue people, and it still felt like the beam was secondary to dodging the turrets. These two problems solved each other: I added a delay to the rescue platform before it teleported people away. The moment that I saw a pile of pixels get fried by the beam right before they teleported out, I fell in love.

Step #6: Build-out and polish

DAY3 AFTERNOON

Now I had the core gameplay, and spent the rest of my time editing the map and finding ways to make gameplay last longer. It was still too easy to fly to the end of the map, so I had to find ways to force players stay in an area longer.

At one point, while carrying a bunch of humans, I accidentally flew past a tunnel entrance and kept going. I ended up flying a race against the beam to get to the top because I was moving so slowly — BARELY made it over the edge before the beam fried me. I felt myself really getting sucked into the gameplay in that moment.

I ended up changing the area I was working on to force the player to fly up the cliff face, and added civilians nearby that (by that point) people would want to pick up. This ended up making most players share that experience of racing the beam.

I also spent quite a while mashing font code. Rendering fonts in Pyglet was easy, but the 2x scaling I was doing with the rest of the world made the fonts look TERRIBLE when rendered. I had to do some GL trickery to render the fonts unscaled, but allow me to still specify in-game coordinates and have them show up in the right spots.

Step #7: PAAAANIC!

I looked at the clock and realized I had an hour until the deadline. I didn’t have an ending for my map, and there was a massive chunk of unfinished copy pasted tiles that had not been tested. I finished that area as quickly as I could (but not well — which is why the last area is missing so many collision edges).

I hadn’t figured out how a round of gameplay should end, except that the player should escape. Since the jetpack was so prevalent, continuing the trend seemed appropriate. I started drawing a graphic for a big rocket, but a tiny voice in my head was yelling very loudly YOUHAVENOTIMELEFTWHATAREYOUDOINGSTOP. I ended up just making the rocket an even larger pixel.

The biggest heart-stopper was that I didn’t have a way to restart the game on death. I tried a panicked hack of just calling Game.__init__() on my main class again. It yielded spectacularly bad results:

  • Accidentally bound the restart to key down instead of key press the first time and inadvertently creating a massive amount of Pyglet windows to the point that my computer hard locked.
  • Recreated the player each time it was restarted, and having four players flying around picking up people at once.

Luckily, with slight tweaking it ended up working. Once that was done and I added a win/lose screen, I started prepping for release. Unfortunately, I had never looked at packaging for python, so it took me a bit of beating on py2exe and py2app to figure out how to get the game released.

Step #8: Deep sigh of relief… followed by panic.

After posting my final entry, I ran around testing on computers to make sure it ran. I quickly found that apparently it lagged horribly in spots on every computer except my dev box. Nothing I could do about it, but at least the gameplay was still possible even with the lag.

(After quite a bit of debugging, it ended up that this was due to a combination of smoke particles colliding with tiles and python not being run in optimized -OO mode.)

I also realized that I hadn’t added any instructions. My test graphics ended up in the final, and they were so minimal, people might not know what to do. I threw together some HTML instructions with graphics showing what each thing was.

Once that was done, I walked over to the office to pick up my laptop, and my brother was playing the game with a few co-workers. It was AWESOME to watch people playing a game I had just finished, having fun with it, and competing heatedly with each other… nothing better.

I’ve learned a ton from the experience and it’s renewed my passion for game development… I can’t wait for the next competition!

Tags: postmortem

Comments

21. Apr 2009 · 21:46 UTC
enjoyed reading this. I love all the similarities of your LD dev cycle to mine… and probably many others.. especially the PAAAANIC! stage.. 😉
23. Apr 2009 · 17:53 UTC
Nice postmortem. :)

easier Windows version

Big thanks to jlnr for rubyscript2exe-ing my game (latest gem update killed the good old packager)

Here is the new simple Window version (no need to install Ruby or download my huge zip)

I’m not sure how my previous Windows link got mangled, here it is again for anyone interested.  This one includes source, though they all do in one form or another.  You can check the Resources inside the OS X app for the source and the rs2e basically tars up the scripts and unzips when ran, though that doesn’t really enable you to check the source that way 😉

tombed II

people who like my entry might enjoy this unofficial sequel a comrade of mine made using my source. it’s more of a puzzle game, often requiring planning and careful timing. it’s also a lot harder.

Tags: unofficial sequels

Response to comments

Hey, everyone who commented on my entry! Thanks so much for playing and commenting!

I felt it would be good to respond, so here’s some quick answers to the comments.

(1) Sorry, I was too busy making fancy-looking graphics to do the reset button ><

(2) Sorry, I couldn’t finish the music in time, so there’s no sound! Once I regain some energy I will release a new version with sound. I think this game has legs.

(3) Yeah, the wall-switching is a bit cumbersome. I guess this is where memorization comes in – if you know the pattern beforehand or can read it quickly, then you know which wall colours to use and can set it up pretty quick. Not sure if that’s bad design… You can actually just hold down a shot button and move laterally across the wall to change all the circles at once, by the way.

(4) Sorry, there wasn’t a help screen, or it would be more obvious that there are three weapons (Z, X, and Z+X), and that each corresponds to a different colour for wall-switching. Edit: I haven’t encountered any problems with the wall-switching – maybe my explanation was unclear? An animated tutorial might help.

(5) shrt, it seems you have one of Those Keyboards. I’m not sure what the exact reason is, but some keyboards (like the one on a laptop I once used) seem to not want to register a combination of a letter and certain arrow keys at the same time. So you can’t press Z, Down and Left together. Best I can do is to put in 360 pad support, and possibly other pad support too, in the remake.

(6) All told, if you actually use all the bombs, you have 12 shots of the superweapon. This is (in theory) enough to clear the Horrible Rush Of Enemies before the boss, and kill the boss, without firing a single conventional shot, and being invincible about 90% of the time. (Edit: Assuming you don’t die before the Horrible Enemy Rush, that is.) C launches the superweapon when your wall is up, and re-summons the wall when it is offline. I was actually worried that it would be a game-breaker, but it seems it… well, wasn’t. If you’re having trouble, use more superweapon!

(7) There’s a semi-hidden trick to the game. You can operate either the spread shots or the laser simultaneously with the missiles. To do so, hold either the Z or the X key to fire the spread or laser, and simultaneously tap the other key (X or Z). This increases your firepower very substantially, but also makes your movement speed erratic, so threading a path through bullets gets a bit tougher.

(8) Have you ever encountered flying monks that *weren’t* attacking you? 😉

Edit: (9) Muku, your comments were completely spot-on. I wonder if you were reading my mind! Yes, I realized a couple of days ago that I should have added a readme with instructions – will try to remember to do so next time. Yes, I am actually considering a more extensive remake/expanded edition with SNES-style blocky sprites (after I finish solving the more obvious issues). Yes, I did think about adding one or two ticks of acceleration, but my experience in the past has been that adding excessive acceleration to a shmup causes the player’s movement to feel sluggish – that’s probably something that can be solved with tuning though, so if I do a more extensive remake I will seriously consider it (thanks to your feedback!). Finally, the wall mechanic currently relies heavily on memorization (you switch the wall between waves to prepare for the upcoming wave); in the remake I am thinking of giving the player the choice of 2 different “wall modes” – manual and semi-automatic – where the former is the same as the current wall, and the latter is easier and more responsive but also far less flexible.

Tags: LD14 - Advancing Wall of Doom, shmup, wall girl

Late non-entry: Compactor

This isn’t an official entry, since it’s way too late. You can see what I was trying to achieve and why I missed the deadline here and here. I thought I’d post what I’d made, just for fun. This is the product of about two laptop battery charges (~2.5 hours), and one hour to polish, fix the odd bug and package .. so in total it’s about a ~6 hour game made using Processing.org. The game takes 1 min to play, and I’d say most people will be able to beat it on their first or second try.

Chances are, everyone is far too busy judging the record number of on-time entries this year .. but if you are curious, you can see the details and play the game here.

Tags: late, processing, screenshot, starwars

SuperShred – Postmortem

Since it’s been a few days, I wanted to write up a postmortem on my LD48 #14 entry before I forgot too much.

Background

I didn’t think that any of the final themes were very good, or at least, anything I was in the mindset to tackle last weekend.  When the theme Advancing Wall of Doom was announced, I was sort of disappointed.  I hadn’t come up with any ideas for it, even though it was a front runner earlier in the week.  I think I sat down and watched some TV for about an hour and a half before I even started coding anything.  I flipped through the program guide for any ideas but nothing.

The idea can be literal, and I think most people created games with a wall in them.  Advancing Wall of Doom has been done in many games as an actual wall, so this wasn’t a bad design.  From the start I decided that I didn’t want to use an actual wall.  Figuratively, the AWoD is just something that you cannot stop from coming.  You just continue until you cannot continue anymore.  In lots of games, this wouldn’t be any fun, so if you can survive for a period of time, you win.  In a way, Tetris is an AWoD.  You can do what you can to keep the wall (i.e. the top of the well) as far away as possible, but eventually it gets closer (pieces fall faster) and you have less room to maneuver.

Mechanics

I knew that for this LD, I wanted to do something very, very simple.  I had two birthday parties and one playoff NHL game to attend to, so I didn’t have a full 48 hours.  I remembered an idea I had for a typing game, and decided that an AWoD would make a good way to push the user to type faster.

Gameplay is simple.  The wall moves from the left to the right as the phrases come from the right to the left.  If they meet, the game is over.  Since this is a typing game, a shredder played the part of the wall.  It starts off slow and as the user makes mistakes, the shredder picks up speed.  If the user can complete ten phrases without ending the game, they will get a short reprieve by setting the shredder back to the default advancing speed, but it will never ever stop.

Coding

I mapped out a couple objects that I would need and started getting them working.  First the phrases, then the AWoD disguised as a red box.  I progressed a bit at a time, getting the phrases to move, the wall to move, then for them to interact.  Input was probably the trickiest.  I used the KeyEvent VK codes, and they don’t tell you what character was input, only what key.  So it will tell you that the user hit ‘G’ but it doesn’t tell you if it’s a ‘G’ or ‘g’.  You have to check for the presence of the Shift key.  For the alphabet and numbers, it wasn’t a problem, but it got sticky for a couple of the symbol characters.  For some reason, the VK_QUOTE or apostrophe key and VK_BACK_QUOTE or backwards single quote were not actually showing up when I hit those keys.  After fussing with them for an hour, I ended up ‘hacking’ a solution together than just checked for the input I was getting from those keys.

By the end of Friday, I had most of the idea done, it just needed something to make it a game.  One of the ways you can do that is add points.  So I came up with the idea that you would get a point per character and maybe some bonus for completing the phrase.  As I was beginning to code that, I figured stats on your successful streaks would be great, and then realized that you should get more points the better you are doing.  Instead of one point per character, you got your current successful typing streak.  So that works.

I started working on the graphics for the wall and settled on a box with teeth on one end.  I drew some teeth and photoshopped them onto the box. By the end of Saturday, I felt that I had a reasonably fun game that looked decent too.  Did I say Saturday night?  I meant Sunday morning at 5am.

Sunday, after four hours sleep, I fixd the two keystroke bugs and add some actual phrases for the user to type. Along with those phrases, I created the WordKeeper to keep track of them, and added a PopupText class to manage the popup text that shows up when you do good or bad, or complete the stage.

So I managed to complete most of what I wanted to do.  Of course, there is always polish that could be done, but because I had some things to do on Sunday, my time was limited.

What I Did Well

I think I did a great job at scaling down the game.  I didn’t need a lot of graphics.  In the past, I’ve spent a little time drawing some art and photoshopping it and while that may take a lot of time, I didn’t have to worry much at all for this compo.  I do miss the art style from my last compos though, so I’ll try to use them next time.

Input is usually one of the pain in the rear things for me.  I have to come up with a scheme that is intuitive, but I also have to take that input and figure out how to use it.  In the Roads compo, I had to learn how to use the mouse to steer a car on a road and make it seem legit based on the speed of the car.  I wasted a lot of time on that.

Sound effects.  Oh man.  Dr. Petter’s sfxr tool rocks for this one.  I think I spent less than five minutes generating sounds that I felt fit what I needed.  They’re simple and very Atari 2600-ish, but they offer great feedback while playing the game.  I tried his music program, but I lack talent in music and should probably try to learn it outside of a compo.

This was the fourth competition that I’m using the same general basecode.  I’m getting used to it and making changes here and there so I don’t have to waste hours trying to figure out how to do basic things for every compo.

What I Did Wrong

Surprisingly, not much this time around.  I had three things that were planned for the same weekend.  One birthday party each day, and a playoff hockey game Sunday night.  I knew that if I didn’t get the game mostly done by Saturday night, I wouldn’t have much time to complete it on Sunday, so that’s what I aimed for.  Sunday was mostly spent doing the last bit of features and polished a little bit of it.

I would have liked to have made the stat display actually look better with some kind of graphical overlay.  It’s really the only part of my game that I think looks boring.  Sure, the shredder could be better, but it’s ok the way it is.

Some of the phrases submitted with the final entry are really long.  They should have been split up into two or more.  It also might have been easier for the player if I put the entire phrase un-scrolling on the bottom of the window so they could look at that.  I think one of the voters already realized the maximum WPM you can get is around fifty since the phrases scroll is constant.  Another way to fix it would be to speed it up if your recent WPM is past a certain threshold and slow it down if it’s not.

What To Do Next Time

Next LD competition, I still want to scale down, even if I have more time that weekend.  With what I did in the time I had for AWoD, I could really make it great with another six or twelve hours.

I want to continue with my basecode and work to make it more robust of a base.  I see things that other people are doing and I know I’ll never be able to do them if I don’t build a better foundation and skip the mundane basic code.

Conclusion

I’m really happy with this compo.  This was my fifth competition, and the third where I actually submit a final version.  I’d like to continue as this is a great way to keep skills sharp and perhaps learn something along the way.  See you in August for LD48 #15!

Tags: advancing wall of doom, ld48_14, postmortem, supershred

Comments

22. Apr 2009 · 05:08 UTC
Great Postmortem,

Timelapse for Extinguish

Assembled out of more than 10k JPEGs, totalling almost 2GB O_O.


http://www.youtube.com/watch?v=r5iXb51buMs

Tags: compo, timelapse

Comments

winferno
22. Apr 2009 · 23:09 UTC
Hey, how did you embed the YouTube video directly on the WP site?
LunarCrisis
23. Apr 2009 · 01:49 UTC
You have to ask an admin to do it for you, since wordpress strips out the tags for anyone else. You have to make sure not to edit the post after they embed it, though, or else it’ll be re-stripped and you have to ask again =)
Cosine
23. Apr 2009 · 19:07 UTC
Nice timelapse. Also, I liked the 11/8 song. 😛

Quick fixes & scores

Shortly after the compo I fixed up the menu images, flickering graphic bug and added something to track your progress as requested by some people I showed the game to. As most of my comments here have been requesting score tracking. I thought I’d share the updated link with you chaps in case you want another go at finishing it. Usually it just frustrates you with how close you came. I still haven’t finished the game but I have it on good authority that 3 people have.

Get IT here.

Tags: update

Compo Process Feedback

Hey everyone.

Since you’re all busy busy playing and voting for entries, I thought I’d open up a thread to collect some suggestions. We’ve already seen many great ideas come up in IRC, but they should really be written down. So, any thoughts on the voting process, submission process, or anything to improve how we run a compo, drop a comment to this post.

With such an big turn out for April, it looks as if we’ll have to start taking things more seriously to manage the growth. If you’re a PHP+Database+Wordpress guy (gal) that wants to help us out, stay tuned.

For now, I’d like your thoughts. Respond away.

– Mike Kasprzak (PoV)