Sunday, April 19, 2009

Walla Zombies!

So I've finished my game for the Ludum Dare contest. Today I spent a few hours fixing my graphics to not be so shoddy.


The buildings don't really match up to the scale of the characters, though I'm not really worried about that. As for code changes, I gave both the zombies and player simple momentum for knockback when being hit. For the zombies, this also helped smooth out their movement. I've also put in some simple particle effects on damage. The effect shoots out 10 colored balls which fly out in a random direction and slightly up. They have basic gravity and will bounce when hitting the ground (z=0). For the zombies, I colored them a stale red-near brown. Donuts emit brown, and the player red. This gives a nice effect and really does make the game more interesting. Another small graphical change is that characters turn more red as their health goes down. This is more visually stimulating than modifying the alpha.

A larger update added today is a melee attack. You can see from the screenshot that the character is holding a rolling pin. If zombies get too close to the character, he/she can right click the mouse to swing which will hit surrounding zombies and push them back a bit. This is nerfed to reduce players' attempts to rely on it though, by limiting the speed to 1/5 of a second and only hitting ten zombies(this also reduces some sound effects clutter as I didn't build a sound manager of any sort so sounds are played for every action).

As for optimization, I gave the zombies a timer to stall updating the field which is staggered among all of them. After the initial delay, it will reset to 5 ticks on each count down. This way, with 50 zombies on screen only 10 or so will attempt to update the field at any tick. Adding this did not seem to harm the zombie behavior, and the game no longer crawls after throwing many donuts. The targeting has also been optimized, before they would attempt to update the field for each available target that was close. Now they find the nearest object and update the vector field based on that object only.

All in all, I believe the game is a success. It started as a quirky game with some interesting developmental elements, i.e. vector fields for AI movement.

Almost forgot links to the game.
OS X application
Windows executable
Source
For linux, grab the source and install Ruby+Gosu as per the README (unless you already have it)

Saturday, April 18, 2009

Ludum Dare

So I found out yesterday that the Ludum Dare competition was Internet based (hooray for making assumptions!) and now I'm participating with the Ruby/Gosu crowd. If you are not familiar with the contest, it is a solo contest where you basically get a theme (Advancing Wall of Doom this time) then build a game from scratch (outside of several accepted frameworks for code). My idea is a combination of word play and sleep induced story.

A friend of mine jokingly said something about "walla" which turns out is a word, and a city. As a word, it means the incoherent rumble of voice that comes from a group of people. It is also a city in Washington (Walla Walla). From that, my game is a "walla" zombies in Walla Walla. The point of the game is to survive a horde of zombies by running and tossing donuts (y'know cause zombies like donuts). Don't ask why donuts, I don't know. I was half-asleep when that idea came to mind. Now, the main character is a baker and that just happens to be all that he has on hand.

For mechanics, the zombies move according to a vector field, ala Ronald C. Arkin's paper "Motor Scheme - Based Mobile Robot Navigation". The map is split into 10x10 pixel cells, with randomly initialized vectors pointing where to go. On each update, the zombies pick up this vector and move in that direction. There is a three in ten chance that they will just move randomly, adding noise to the field in case they get stuck, and to make their movement more erratic. If they are close to a target, they will build a local vector map pointing towards the target and update the map. If they are touching (very close) they will "hit" that object, which will either return 1 or -1 if that target is the player or a donut. This way they can gain health from players and lose from donuts. Over time, they will die on their own (starvation) which is the objective of the game.

Because I like making things difficult, I decided on using a simple array based collision map. Normally, this is a fair idea but instead of storing this data in an image or something convenient I just used text. This is mainly because I don't have the RMagick gem installed and don't really want to install it. I would also rather keep my Ruby dependencies to a minimum as I don't want to make it difficult for any judges to run my game. My window is 640x480 pixels, which works nicely with a 10 pixel unit space. This leaves me to author a 64x48 array of ones and zeros. To keep from driving myself mad, I'm just going to limit my game to one map and design that map so that most of the space is solidly open or blocking. From the screenshots below, you can see that the horizontal middle of the map is where most of the action is.

The engine for the game is built on top of Gosu, with a minimal state stack to separate the logic of title sequence, gameplay and credits. Using a nifty trick from another Gosu enthusiast, I've extended the core Array class to catch undefined method calls and feed them into the array elements. This makes it simple to do things such as @objects.draw

class Array
def method_missing(method, *arg)
self.each { |item| item.send(method, *arg) }
end
end
I've also extended the Image class in Gosu just to simplify calling draw with a bunch of re-used parameters, and also to enable simple animations for rotations and alpha changes.

On my laptop (1.6 GHz Pentium M, 2GB RAM, ATI x300 radeon mobility) I can easily have fifty zombies running around. Though this slows down pretty significantly with the vector field updates when you toss out several donuts. There isn't a whole lot I can do about this, as the work is being done in Ruby and I don't really have time to write some C code to fix such a specific thing.

For graphics and sound, I was initially going to use the sprites from lostgarden.com. However, using graphics not made by yourself is against the competition's rules. To cover this, I just traced over my background. Not really a good solution, but I'm fairly handicapped when it comes to art. Sound was built using GarageBand and sfxr both incredibly useful for projects like this.

To introduce the game, I created a title sequence that shows a few screens giving the backstory (the little that exists). After that there is a sequence zooming into Walla Walla starting from a view from space. To do this in 2D, I found several images starting with a picture of Earth, a colored map of the United States, a map of Washington's counties, then a map showing Walla Walla within the Walla Walla county (I'm not making this name up, I swear).

Without any further ado, here are some screenshots.










Sunday, April 5, 2009

shapes and crap

After seeing some animation of circles spawning with random colors and growing, I started making something similar with Gosu in Ruby. After showing some friends it quickly snowballed into supporting multiple shapes, rotations, random selection and cycling selection.

Basically, you need to try it to see what the hell it does.
Number keys change shape,
R turns on/off rotations,
O randomly selects shape, and
C cycles through shapes

file:///Z:/Ruby%20Projects/Circles/Circles.exe

Thursday, April 2, 2009

SDL ain't dead yet!

So I've been working on a clunky 3D OpenGL engine for my OpenGL class any for myself. As far as I'm concerned the class is just there to give me time to work on actually using all this graphics stuff I've already learned. Anyway, I'm planning on having it do a bunch of basic things;
  • load and render an obj file with a single UV mapped texture
  • load a series of images and render as a skybox without seams
  • use a grayscale image to build a terrain, and render with some texture
  • support point and directional lights
  • tie into Bullet for physics
  • use SDL for various bindings
So far I have most of these things set up, I just need some game objects and start using the core of Bullet.

However, I did hit a few snags along the way. Some are just shortcomings of my current implementations, others a bit odder.

Like most of my current projects, I'm attempting to keep my code cross platform by continually building in XCode and Visual Studio and using subversion hosted at Assembla.com. Earlier this week I hit a large snag while using XCode. I had cleaned my project to get rid of several mislinked libraries and unused resources when I discovered that I was getting an EXC_BAD_ACCESS runtime error in some code that had been working just fine for a while. It was in my obj loading phase where I was attempting to push some UV data on a std::vector (like I said, this is a clunky engine). But for some reason this was failing. Oddly enough, I was using other vectors alongside this one in similar ways and they seemed to work just fine.
At first, I figured I just needed to claim some memory before using the vector just to be safe. Of course, reserving and even adding some padding data before-hand just caused the application to crash on those operations. After fondling the debugger a bit I found that the type pointer was either null, missing (what) or otherwise ill-defined. This caused some serious head to wall banging as I couldn't understand how the code even existed without knowing what type it was. I convinced myself that there was a problem with initialization of my data member, so I tried putting a constructor into the initializer list (note, I'm doing all this inside my containing class' constructor and not using a pointer to a vector so this shouldn't be a problem), but to no avail. Finally, I decided to stick this thing in Visual Studio and see what happens. Once I got the solution set up and linking to the libraries right, I compiled and.. it ran. No problems, aside from a few small differences in rendering output due to different graphics cards. So either VS was just being nice to me, or XCode wasn't compiling my code right. I gave the problem some time, and when coming back to it I started trying silly things like changing my order of declarations in the class header. Putting the vector declarations first did nothing, putting some declarations in the middle did nothing, but changing the order of the vectors themselves did something. Turns out, whichever vector was declared last would throw this runtime error. What this means I have no clue, I'm not even sure how to Google for that to find a solution. So I ended up "solving" the problem by adding one more vector member aptly named "fuckme".

Oh, here are some screenshots of the current build showing off a cube of boxmen, a skybox and working terrain. If you look closely, you might notice that the terrain texture doesn't completely match up to the terrain itself. Don't worry, this is just a proof of concept and that image wasn't intended for this use.