Sunday, 10 November 2013

My games - "Warmup" game, or Hat & Axes

Ludum Dare is a very popular game development competition, that is already in it's 28th iteration. As Ludum Dare's website says:

Ludum Dare is a regular accelerated game development Event.  Participants develop games from scratch in a weekend, based on a theme suggested by community.
Ludum Dare was founded by Geoff Howland, and held it’s first competition in April of 2002. Since then the community has run more than 22 regular Events, several dozens of practice competitions, collectively creating many thousands of games in just a weekend each.
The event attracts developers from all sides of the industry. Students, hobbyists, industry professionals from many well respected game studios, as well as many independent game developers.
For many people, it can be difficult to find or make the time create a game or prototype for yourself. We’re here to be your excuse.

 Part of the Ludum Dare tradition is to create a small game before the competition, to test your development skills, and to make sure the tools you are going to use in the main event have been set up properly.

Since I was going to participate in Ludum Dare #23 in April 2012, I decided to follow this tradition, and I must say I succeeded in testing new ideas to use in the upcoming challenge while also developing new techniques I have been using in my games since.

Click here to download the game. There are both Windows 32 bits and Linux 32 bits versions. Both include the source code.

One of Ludum Dare's rules to inhibit cheating and also to further learning through seeing other persons development process is to always record the screen while you create the game, creating a timelapse. I was afraid that I would screw up while timelapsing the real thing, so I also timelapsed the warmup, as a sort of "training" or test. Below you can see the result:

It was very interesting to watch myself programming things (and making some mistakes) after I had recorded this video. Still is.

From my computer's clock in the bottom left corner you can see I started at 22:43 PM and I finished 04:42 AM, six hours later, of continuous programming! I was very proud of myself. The following code snippet illustrates this:

// Math!!!! I LOVE MATH! MATH IS FREAKIN' AWESOME (by the way its 04:22am)
double Distance(int x1, int y1, int x2, int y2)
     double a = std::fabs(double(x1 - x2)) * std::fabs(double(x1 - x2));
     double b = std::fabs(double(y1 - y2)) * std::fabs(double(y1 - y2));
     return std::sqrt(a + b);

The development actually went pretty fast, considering the game turned out very complete.
In the image above, you can see: the player, a coin, a pile of coins displaying how much money you have, hearts indicating health and an axe-throwing troll. There is a ladder to the left, but I did not have time to add ladder physics to the player's movement, so it does nothing.

The coins are the coins of the Brazilian Real, our national currency here in Brasil (Brasil is actually spelled with "s" since president Venceslau Brás during WWI, I wonder where he got this idea à_á ). The coins have their actual values (1, 10, 25, 50 and 100 centavos). The objective of the game is to pick up every single coin in the level, while avoiding being hit by the axes thrown by the trolls.

My friend Vander did the sprites for both the player and the troll. Also the axe. He often does pixel art for my games. One bad decision was to use the sprite dimensions for hitboxes. The axe sprite has transparent borders, making hit checking extremely poor, and even more since the axe rotates. I should have used circle collision for the axes.

Vander also originally uploaded the game to Ludum Dare's website. He suggested the name "Hat & Axes", which I promptly accepted, even though we still call it the "warmup game".

While there's an entity system going on for the coins, the axes and the trolls, the player itself is treated separately, and player data is contained inside a "struct":

struct Player
     int x, y;
     int width, height;
     int yVelocity;
     int oldYVelocity;
     bool standing;
     bool facing;
     bool doubleJump;
     bool canDoubleJump;

 One interesting aspect is the canDoubleJump boolean. In this game it's always true, but I have since used it to implement an acquirable ability. Being able to time the double jumps is essential in some parts of the level.

My older games used to simply close without a warning whenever the player died. In this game however I was inspired to add proper death and victory screens. I won't spoil the victory screen, but take a look at the sheer creativity in the death screen.

One of the most original aspects of the game, however, is the sounds. I did them using Audacity to record myself making noises into a headset. This "narration" turns out to be pretty amusing (there is voiceover on victory or failure, check it out).

Another tool I used was my HTML/Javascript map editor. It's source code is actually bigger than this game's source code. My map editors always turn big, ugly and buggy.

While sharing this game to my friends, I met a compatibility bug for the first time in my programming history: in Windows 7 the trolls didn't show up, making the game quite boring. At first this puzzled me really good, but when I tried to build this in Linux and had the same problem, I quickly realized it had something to do with differences in the memory model. Both Windows 7 and Linux will set uninitialized variables to 0, while Windows XP will leave whatever was in the memory before the program started. This is a huuuge security vulnerability and also a programmer's pain in the ass.
Turns out I had forgot to include this line in the troll's class creator function:

alive = true;

Since in C++ booleans are merely integers treated as false when their value equals zero, and true for all other values, in decent operating systems the trolls would be created already dead, while in XP whatever memory garbage turned into "alive" would keep them alive.
This very well sums up the entire experience. Taking part in Ludum Dare and creating a small game in very little time is very interesting, and I recommend it. Another Ludum Dare tradition is to write "post mortems", which are insights into what went right and what went wrong in the development process. I guess we can call this post my warmup game's post mortem.

No comments:

Post a Comment