Friday, 15 November 2013

My code - SimpleCfg library

SimpleCfg is a lightweight, single-header-file C++ library I created two years ago to suffice all my needs in the loading of small configuration files.

Allegro, the C-language game programming library I usually use, has it's own configuration file routines, but they are very outdated, unable to have more than one file loaded at once, and obviously unavailable when I am not using Allegro. I originally created SimpleCfg for some OpenGL and Winsock programs.

SimpleCfg's usage is very simple (oh the redundancy!). It was greatly and clearly inspired by TinyXML's syntax. In fact, I used to call it TinyCfg until I discovered that someone was already using this name. Little do they know, that my library is even tinier and simpler! The API consists of only two classes: SimpleCfgFile and SimpleCfgValue.

Since one example is worth more than a thousand words, here's a valid SimpleCfg configuration file:

// test configuration file for SimpleCfg C++ library
testValue=0
int1 =2
int2 =22
int3 = 333 // comment

float1=0.5

float2 =1.5
float3 = 2.0 // comment 
string1="First string"

string2 ="Second string"
string3 = "Second string"// comment

Very simple indeed. And the code for loading and parsing this file is even simpler!


#include "SimpleCfg.h"

#include <iostream>

using namespace std;
using namespace SimpleCfg

int main()
{
     SimpleCfgFile file("test.cfg");
     if(!file.IsLoaded()) return 1;
     if(file.GetValue("testValue") == undefinedValue) return 1;
     cout << "int1 = " << file.GetValue("int1").ToInt() << "\n";
     cout << "int2 = " << file.GetValue("int2").ToInt() << "\n";
     cout << "int3 = " << file.GetValue("int3").ToInt() << "\n";
     cout << "float1 = " << file.GetValue("float1").ToFloat() << "\n";
     cout << "float2 = " << file.GetValue("float2").ToFloat() << "\n";
     cout << "float3 = " << file.GetValue("float3").ToFloat() << "\n";
     cout << "string1 = " << file.GetValue("string1").ToString().c_str() << "\n";
     cout << "string2 = " << file.GetValue("string2").ToString().c_str() << "\n";
     cout << "string3 = " << file.GetValue("string3").ToString().c_str() << "\n";
     while(true) continue;
     return 0;
}

As you can see, SimpleCfg is the king in simple C++ configuration file libraries!

And the best thing is: it's completely free and open-source.
Download SimpleCfg.h here.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

My code - Javascript Map Editor

When I was going to participate in Ludum Dare, I knew I needed some sort of map editor, so I wouldn't be left having to create levels by editing values in lines and rows of some big matrix in the code. However, I desired an customized map editor that was highly adapted to my specific needs of fast level creation for the 48h Ludum Dare competition. Therefore I needed to create my own map editor.

I knew this would be rather difficult to make in C++, my favorite programming language, since I never took the time to learn any GUI library. I then decided to create it in HTML and Javascript, since HTML has built-in GUI elements, like buttons, text boxes and drop-down menus.

You can play with the Javascript map editor here. It's entirely contained in a single HTML file with 767 lines of code (!). Note however that it probably does not work in Chrome. It was tested, and works in, both Firefox and Opera. I don't know about IE. E se você for brasileiro olha o título da página pra ver se entende a piada.


Even though I programmed this map editor in HTML and Javascript to run it in Firefox 13.0, I didn't use HTML5 technologies like the canvas tag. This was a very curious decision, since canvas would be the obvious way of implementing the tiles field.

Instead, every tile is a single image inside div tags, with onclick pointing to a function inside the Javascript code that triggers actions into that tile according to the context. Each image has also colored borders, that indicate the block type for that tile.

This was a twofold decision. This avoids the need to keep track of scrolling, by example, because it's automatically created by scrollbars in the div tag. However, this means that every time you create a new map, HTML code for hundreds of img tags must be inserted, and every time a single tile changes, this code must be changed. The result is that this map editor is very slow and memory-hungry. Creating large maps is nearly impossible.

Another twofold decision was to not use any kind of map saving/loading format. Instead, the map editor creates C++ code representing the map to be included directly in your game. Here is a example of this generated code:


#ifndef MAP1_H
#define MAP1_H

// The following code was           
// automatically generated by       
// my javascript map editor.        
// It exports maps directly into    
// C code, voiding the need for     
// map loading functions.           
#ifndef MAPDATA                     
#define MAPDATA                     

#define VOID_BLOCK 0                
#define SOLID_BLOCK 1               
#define LADDER_BLOCK 2              

struct MapData                      
{                                   
      unsigned int width, height;   
      unsigned int tileSize;    
      unsigned int *tiles;          
      unsigned int *blocks;         
      char *tileSet;                
};                                  

#endif                              

unsigned int map1tiles[] =
{                                   
      6,
      6,
      6,
      6,
      6,
      6,
      6,
      6,
      6,
      6,
      [...]
      1,
      1,
      1,
      1,
      1,
      1,
      1,
};                                  

MapData map1 =           
{                                   
      200,       
      100,      
      16,       
      map1tiles,         
      map1blocks,        
      "tile1.bmp,tile2.bmp, [...] tile36.bmp,tile37.bmp;"
};

#endif


 As you can see, every tile occupies a single line. The actual file containing this map has breath-taking 40047 lines of code!

The catch with this directly exportation of the maps is: how to save the map for later edition? Map saving was done in the same fashion as exportation, but instead generating Javascript code, that when evaluated in the map editor page automatically sets all variables to the corresponding map.

However, the Javascript generated this way is so huge that it's nearly useless. Evaluating the code for a big map takes minutes and leaves the browser completely frozen.

Even with all those shortcomings, this map editor proved to be very useful, and I have already used it in 3 different projects, including both my Ludum Dare warmup and the actual game I would submit to the competition (that wasn't finished on time). Do not forget to check it out.

My games - Choplifter

Note: scroll down to the end of the post to find the link to play the game

After playing one great HTML5 game called Mutant Zombie Monsters, I was left with the desire to experiment with those technologies. However, acknowledging my limited capability in Javascript, I knew I should start with some simple idea, perhaps porting some old game long forgotten, that could benefit from a rebirth in the new world of canvas.

Then one day I was looking for some abandonware to play on DosBox, when I found this lovely game: Airlift Rescue.


You are the pilot of a rescue helicopter. Your mission is to fly to a mid-eastern terrorist compound and rescue 64 hostages that are being held in four separate buildings (16 in each building) and fly them back to American embassy. The terrorists have a seemingly endless supply of tanks, jet fighters and chopper-seeking drones to hinder your success.
 
I found Airlift Rescue's gameplay to be amazingly original. I knew I had found the game I was looking for!

Armed with my barely sufficing Javascript skills and many W3CSchools tutorials to enlighten my path, I started my quest. This would be my first HTML5 game and my first port of an old game.

One of the first, and most interesting, design decisions I made was to use only vector graphics. And by this I do not mean .svg files or anything of the like. Oh no. This wouldn't be hardcore enough. By this I mean every single graphic in the game is created on real time with nothing but code. Example:

function DrawBomb()
{
 if(bomb.ready) return;
 var bombX = bomb.x - scrollX;
 var gradient = context.createLinearGradient(0, bomb.y - 5, 0, bomb.y + 5);
 gradient.addColorStop(0, "rgb(128, 0, 0)");
 gradient.addColorStop(0.5, "rgb(202, 64, 96)");
 gradient.addColorStop(1, "rgb(128, 0, 0)");
 context.fillStyle = gradient;
 context.beginPath();
 context.moveTo(bombX - 12, bomb.y);
 context.lineTo(bombX - 12 + 4, bomb.y - 4);
 context.lineTo(bombX + 2, bomb.y - 4);
 context.lineTo(bombX + 5, bomb.y - 1);
 context.lineTo(bombX + 8, bomb.y - 4);
 context.lineTo(bombX + 9, bomb.y - 4);
 context.lineTo(bombX + 9, bomb.y + 4);
 context.lineTo(bombX + 8, bomb.y + 4);
 context.lineTo(bombX + 5, bomb.y + 1);
 context.lineTo(bombX + 2, bomb.y + 4);
 context.lineTo(bombX - 12 + 4, bomb.y + 4);
 context.closePath();
 context.fill();
}

And this is actually the smallest drawing piece. I manually entered every single context.lineTo, every single coordinate of the graphics. Since I was learning to use canvas as I coded, every function is slightly different in it's intricacies.

In fact, in part I decided to create the graphics in this manner specifically because I was learning while I was coding the game. For a beginner to HTML5 like me, it would be complicated to use raster graphics/sprites.

Also, I did this deliberately to upset my friend Vander, who does pixel art and hates gradients.

This decision did have an interesting consequence: nearly half of the code is for drawing things.

Since I was entering each coordinate manually, and also making small subtle changes to the design, I did a mock-up of the game in Kolourpaint (like MS-Paint but for Linux and better), to aid me in the implementation.


As you can see, one of the alterations I introduced was to exchange the "chopper-seeking droids" for balloons. This droid-thing does not make any sense anyway. In the image below you can see the helicopter being chased by the balloon (and also by some tanks):

So the final game mirrors my ideas very closely, even through it was developed in the "quick & dirt", "workaround-oriented programming" style. The code is a mess. Among other things, every variable is global:

var state; // 0 - Hasn't started yet; 1 - Start new game; 2 - Playng; 3 - Game over
var context;
var frame;
var stars = new Array(50);
var copter = {};
var scrollX = 0;
var house = new Array(4);
var people = new Array(64);
var tank = new Array(4);
var aliveTanks = 0;
var tankIndex = 0;
var plane = {};
var balloon = {};
var pressed = {};
var rescuedPeople = 0;
var peopleAboard = 0;
var deadPeople = 0;
var peopleOnGround = 0;
var lives = 0;
var copterBullets = Array(50);
var cBIndex = 0;
var particle = Array(200);
var pIndex = 0;
var bomb = {};
var gameOverFrame = -1;
var wasSPressed = false;
var missile = {};
var gameOverCause = 0;
var finalRescueFrame = -1;

I had some other ideas for this game that didn't make it, because I am lazy and it wouldn't be worth it anyway. Some of those are:
  • High scores, based on time taken and hostages killed
  • Statistics (like enemies killed, etc)
  • Tank bullets (the tanks do not shoot, only follow you, through you can still destroy them with bombs)
  • A fence between the houses and the embassy grounds
  • Machine gun heating (sou you would need to wait for the machine gun to cool down before shooting again, instead of being able to shoot continuously)
  • Ammo
  • Day-night cycle
  • Sound (jet passing, explosions, machine gun, etc)
One of the ideas I had that is actually present in the game is the particles system. Explosions, fireworks and missile exhaust are created with it. Also, I am very proud of the difficulty progression, less frustrating than the original.

You can play the game on your browser here. Tested on Firefox and Chrome, but should work on any browser with canvas support. You can look at the source-code by pressing Ctrl-U on Firefox, or the equivalent combination on Chrome.

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.

Thursday, 7 November 2013

My games - Snake

"Snake" was the first game I created with C++ and Allegro 4, back in 2008. I was then still learning the basics of programming, and today going through the source code is in itself a adventure in both shame and nostalgy.

It's a fairly straightforward Centipede clone, heavily inspired by playing the eponymous Snake on a Nokia 3310 (so oldschool!). Here in Brasil this mobile phone is called the "Tijolão", literally the "Big brick".


If you want to experience this piece of nostalgic beauty, this piece of C++ genius, this piece of art in monochromatic graphics, download the game here. Package includes both source code and binaries for 32-bit Windows and 64-bit Linux.

When you first open the game, you are given the option of which difficulty level to play. The menu below isn't the one I originally created for the game in MS Paint back in 2008. I lost that file when I formatted my computer some years ago. This is mostly fortunate: the old "menu.bmp" had quite doubtful "aesthetics".


After selecting the difficulty you are presented to state-of-the-art technology in game GFX consisting of blue squares over black background.


Points are displayed on the top left corner, and you are given 5 points for each food (blue dot) you eat, until you collide either with yourself or the walls. Basic stuff.

Through not so basic to someone learning C++ from a badly-written PDF hastily downloaded with a 56kbps dial-up connection. Looking through the source code, we can find many jewels of WOP (Workaround-oriented programming).

Here I shall present them, for both my great shame and as a monument to the better programming skills I have today.


Both the foods and the snake itself are represented through the coordinate structure below (please don't mind the comments in portuguese):

struct coord          // struct com coordenadas x e y
{
       int x, y;
};

In this fashion, the snake is simply defined as an array of coords, and the head of the snake is the first element in the array. You'd think I would use something like std::vector or even std::list to create this array. However, 2008 me had no knowledge of such sorcery, so I just declared an static, laaaarge array.

     coord snake[10000];                     // array da cobrinha

You'd also think I would directly use the primitive-drawing Allegro functions to draw the graphics. However, 2008 me managed the unthinkable. I created a 25x25 BITMAP, drew a rectangle onto it and then drew this BITMAP where each coord was, instead of simply drawing the rectangle directly onto the screen.

     BITMAP *ponto;                         // imagem do corpo da cobra e da comida (food and snake's body image)
     ponto = create_bitmap(8, 8);                   // cria a imagem (creates the image)
     rectfill(ponto, 0, 0, 7, 7, 25); // desenha o ponto (draw the dot)
                      [...]
                         for(i = tam; i > 0; i--)    // desenha a cobra (draws the snake)
                         {
                                     draw_sprite(tela, ponto, snake[i].x, snake[i].y);
                         }
                         draw_sprite(tela, ponto, comida.x, comida.y); // desenha a comida (draw the food)

Also, even more surprisingly, I used this BITMAP to draw the walls!

                         for(i = 0; i <= 79; i++)     // desenha a parede de cima (draw the top wall)
                         {
                                draw_sprite(tela, ponto, i * 8, 8);
                         }
                         for(i = 0; i <= 79; i++)    // desenha a parede de baixo (draw the bottom wall)
                         {
                                draw_sprite(tela, ponto, i * 8, 472);
                         }
                         for(i = 1; i <= 59; i++)    // desenha a parede da esquerda (draw the left wall)
                         {
                                draw_sprite(tela, ponto, 0, i * 8);  
                         }
                         for(i = 1; i <= 59; i++)     // desenha a parede da direita (draw the right wall)
                         {
                                draw_sprite(tela, ponto, 632, i * 8);
                         }

This is actually much more complicated than the obvious solution. I can't remember why I thought this was a good idea.

Not only were my programming skills limited, but also my english-language skills. Here's an original anglophone snippet from 2008 me:

                         go = 0;                // now not wented

These and other abysmal thoughts populate the code. Now, I know what you are expecting (or should be expecting). There's something that always lies in the core of all beginner programmers code (at least beginners programming in languages that allow it)

http://xkcd.com/292/

Yes. The shameful, dreaded, "goto". Bringer of spaghetti-code and much despair.

                         if(go == 1)       // se já foi vai para o fim da checagem de teclas pressionadas (if done already jump to the end of input treatment)
                         { 
                               goto input_end;    
                         }
                         if((key[KEY_RIGHT]) && (dir != 4))
                         {
                                        dir = 2;
                                        go = 1;
                         }
                         if(go == 1)
                         {
                               goto input_end;
                         }                         
                         if((key[KEY_DOWN]) && (dir != 1))
                         {
                                        dir = 3;
                                        go = 1;
                         }
                         if(go == 1)
                         {
                               goto input_end;
                         }                         
                         if((key[KEY_LEFT]) && (dir != 2))
                         {
                                        dir = 4;
                                        go = 1;
                         }
                         if(go == 1)
                         {
                               goto input_end;
                         }                         
                         input_end:
But enough of this monstrosity. I conclude here my travel back in time, and I hope you can share similar, intriguing experiences of a newbie past in the world of game development.