Sunday, 17 August 2014

My games - Ali Baba And The 40 Thieves


Note: In this post, I want mostly to describe motivations, the game itself, the creative process, and rant a little about problems I had, discussion on technical issues will take place in a future post about Game Boy development.

The first week of august in #ludumdare @ AfterNET saw a few of the usual frequenters making efforts at some jam other than the eponymous Ludum Dare 48h game development competition. This was GBJam3, a game development jam focused in Game Boy-ish games. Since there were lots of related talking, I was quickly convinced to also engage in this experience, since the jam coincided with my last week of mid-year med school vacations.

GBJam's rules are the following:

  • You must make a Game Boy-themed game
  • All content must be made during the 10 days of the jam
  • The resolution of the game must be 160x144
  • You cannot use more than 4 colours
As you can see, they are pretty relaxed. But I decided to do the ultimate challenge, the highest form of tribute to the Game Boy, a Game Boy game in it's very truth, a ROM that one can play in an emulator or even write to a cartridge. Since I do not have any experience with GBZ80's Assembly language, I instead opted for GBDK, a set of tools and libraries that enables one to write a Game Boy game in the C language (this latter turned out to be a bad decision, read on to see how exactly).

I was for long cooking an idea in my mind, after rewatching AVGN's Little Red Hood video. You see, a realization that can be made about 8-bit era games, that is very true, was that one of the most challenging aspects at the time was game design. While we grew playing games with established game design practices, the developers of the day were venturing into a new media, so they made many mistakes. Also we must not exclude the laziness factor, in a time in which internet game reviews were distant.

Thus, true 8-bitness is a state that can only be achieved by a game developer if he takes bad game design into consideration. I figured, from Little Red Hood, a list of factors, or rather, a process, that leads to such typical game design.
  1. Chose one relatively well-know canonical material, in special, a well-known story or folk tale.
  2. Design the game not on the actual story, but rather, design it as if you didn't really knew the story too well and didn't bother to look it up.
  3. Base gameplay in repetition and randomness.
  4. Do not tell the player how to play the game or what is the objective and winning conditions, instead he must figure everything on his own.


In those screenshots you can see the playing area. If you want to know what the actual gameplay is actually like, I strongly recommend (rather, beg) you to download the ROM and an emulator and play it. It will be much more fun figuring in your own. However, if you want to skip that, or you played the game and couldn't figure it out anyway, you can select the text below, that has been spoiler-protected, to read what you have to do to win the game.

You must avoid the enemies, which walk around the level in a quite stupid pattern. By pressing the A button, you can shoot rocks, that can use to break vases. When a vase is broken, a snake will appear from the vase for a brief period of time, running around frantically, killing the enemies that are found in its path. Those enemies will drop daggers, which you can pickup. As the story is about 40 thieves, you must collect 40 daggers to go to the treasure room. Then you collect the treasure to win the game. The enemies will also drop crescents, which are the game's extra lives.

Also in these screenshots you can see pixel art made by yours truly. I usually despise pixel art as being too inefficient i.e. too much work compared to other ways of making art. However, low resolution and 4 colors is enough to outweigh those preoccupations. It becomes manageable. In fact, I must say it was quite fun doing the graphics. And as you can see they actually look quite good. Even the very exigent Jiggawatt said that it was quite decent for GB art. The other folks at #ludumdare also helped me a lot, IIRC voxel, awsumpwner27 and vede gave their valorous opinion on the vases, over those many iterations, until it looked right. And hdon warned me, that the light in the interior of the water well was wrong, so that too I could correct.


In the image above you can see a comparison between some art I found on the internet, to the left, and my own, to the right. I made my own versions for two reasons, I could not use content that was made outside of GBJam, and there was a great divergence between the art I found and the rest of my art for the game (mostly in size, look how the cow skeleton is much bigger, and the cactus looks fatter). Nonetheless, this art I found was a great source of inspiration, specially for someone who does not usually practice pixel art.


Note the spinning scimitar on the start screen. That actually takes a lot of the ROM, because it has 10 different frames. That is not pixel art. I used the image above as a reference to make a model in Wings 3D. I then animated this model to rotate in Misfit Model 3D. Here's a high resolution version of the spinning model animation.

Another thing I had the opportunity to use in this jam and that I don't usually use besides pixel art was bad programming practices. The really bad ones, like keeping everything in globals, abusing the goto statement, putting lots of code in main() and avoiding too many functions, putting function definitions in header files... I believe this was all justified, due to the limitations of the platform, there is a performance advantage from restricting yourself to globals, and using less developed forms of flow control. Also a size advantage. In fact, even with my minimalist coding practices the code barely fits into the ROM.

Also about programming, I discovered that the compiler that ships by default with GBDK is utter crap. It's sdcc, but from 2000. There are a multitude of bugs. for's and if's that don't work, mathematical expressions that evaluate wrong, and random compiler crashes that force you to move code around until you solve them. Unhelpful error messages. Weird messages about a modified DOG called EVELYN that has something to do with the optimizer. A real pain in the ass. I advise anyone wanting to do C development for Game Boy to use the newest sdcc for GB version available. Perhaps you can even use GBDK's libs, with some messing around.

The game seems to have been averagely received by those few who played it. A problem is, GBJam does not have a voting system like Ludum Dare, that forces you to vote so you receive votes yourself, and you need a minimal number of votes to appear in the final listing. This is quite stupid. Also about the organization of the jam, Gamejolt is a terrible place to host a jam. It forces you to use 16:9 thumbnails, larger than a certain size, for some reason. It does not let you specify custom platforms for your game. It's voting system is not very good either. I suggest future GBJams should happen in itch.io jams instead.

Now for the most waited moment, the links. Click on the image below to download the ROM, also, please leave a comment if you play the game:
Alternatively, click on the image below to see the game's source code in github:


Saturday, 2 August 2014

My code - AABB vs. triangle collision with least translation vector

Recently, I did one SM64-esque demo while working on some collision code. This in all in preparation to the upcoming development of 3D games. I have now completed my quest into the world of collision detection, and I shall narrate it.

While I previously had working triangle vs. AABB collision, that implementation was of little use to game development due to the lack of a "least translation vector", that is, the minimum displacement that makes two objects to stop overlapping each other.

That implementation was based on this code, by Tomas Akenine Moller. I merely translated his code to Javascript, without understanding it. His code is pretty bad, I must say. It has horrible macros, including defining "X", "Y" and "Z" as "0", "1" and "2" (obviously for accessing elements of vectors). Any decent programmer knows why calling a macro by a single, uppercase letter is very stupid, namely, because then you can never use that letter in your code, ever, without replacing it with the macro. I also looked at some code at this site called Geometric Tools. It is also horrible. The collision functions try to be very good for performance and everything, but then the guy writes a class to do collision detection. For every single different type of collision. Now that's some stupid C++. I, however, am pretty sure of the root of such computer science horror. That is academic code. Written by academics. Who don't know how to write code that is meant to be actually used for doing something actually interesting. Precisely the same reason why they don't care to provide the least translation vector, because they don't know the real needs of game developers. They only care about publishing their clever papers about how smart they are and how much optimization they can fit into their little math puzzles.

However, since collision detection involves quite an amount of mathematics, and we humble non-academic mortals have no time to deal with those, we have no choice but to succumb to those academics. I was advised to look for a certain book, "Real time collision detection", by Christer Ericson. Of course it doesn't tell you about the least translation vector, because Mr. Ericson is an academic and did not research what game developers actually need for collision detection. I then could actually understand what Mr. Moller's horrible code was doing. And then I could make my own implementation of triangle vs. AABB collision detection, without as much bullshit and including the least translation vector (that was actually quite trivial to include, once I understood the vector operations between the separating axis theorem, it was only a matter of normalizing some vectors and including a few dot products).

I then had an almost 500 lines of code long function that of course I had to debug. Now, this kind of thing is horrible to debug, because any silly math mistake like a 0 instead of a 1 or a - instead of a + goes unseen but makes the result completely wrong. And in my case both things happened. I had to add some quick & dirty  debugging to show which axis was claiming to separate to solve the false negatives, and then to correct the errors in the least translation vector. Those last actually required checking the entire function anyway, because one of the possible candidates to least translation vector was longer than it should be and therefore would not appear in the debugging, instead a longer vector would be selected causing the box to jump around due to unnecessarily high displacement.

In the process of debugging, I made this little demonstration of the collision detection. It has a randomly positioned box and triangle, you can move the box around, and it makes the box change colors if it collides against the triangle and also shows the least translation vector as a 3D arrow. You can even move the box around.

But now I am over this horrible episode. Hopefully I will actually be able to create something with this. Except my vacations are almost over and then I won't have time. Oh well.

Check out the github repository of my triangle vs. AABB collision code by clicking the Octocat below:


P.S.: someone that has been asking me about collision detection asked me why I think this is one of the most useful forms of collision detection and why it's more useful than box vs. box collision detection. The trivial answer is that you can make a level with arbitrary geometry in any 3D modelling program and load it and collide the bounding box of your character against it.

Tuesday, 29 July 2014

My code - MM3D loader for three.js


I previously made a MD2 loader for three.js. But the MD2 format has several problems, it's very outdated, it gets enormous and takes a while to load if you many animation frames, and it does not have skeleton data, so you can't attach things like weapons to the hands or armor to the chest or hats to the head.

So since I had no idea of the hell I was bringing upon myself, I decided to make a MM3D loader. That is Misfit Model 3D loader for those who never had contact with this infuriating piece of code. The quality of the model editor's code should have alerted me. It uses unsigned integers as pointers (so it does not compile for 64 bits) and has class declarations larger than 1kloc. A true case of bad C++. Problem is, the specification looked quite trivial!

Now I have learned what lies beneath the surface of Misfit Model 3D model format.

First, the way the model is stored is quite strange, there are lots of unused flags. And the resulting data structures are all disconnected. For example, the vertices. Vertices of a 3D model have attributes like texture coordinates, for example. Instead of having a vertex data structure arranged sequentially, each of those having flags to say which data is available for the current vertex, the data is arranged all over the file, and therefore each element of vertex information has to have a vertex index. This makes parsing the files a lot harder. I call my index variables in loops letters starting from "i", like "i j k l ...". You know a data structure is no good when you have to go all way down to "l".

Second, the specs don't tell you you have to add the default bone translation and rotation values to the animation keys to get the right values, I had to find this on my own.

Third, the specs contained not one, but two errors, the second of which cost me a lot of time, because I had no idea where it came from. I even thought it could be a problem with three.js animation system.

To speak of which, three.js's animation system, specially for skeletal animation, is horribly non-documented. I had to look at a lot of source code to figure out how to generate the bone and geometry data.

But now that this is over, I am pretty happy, because it actually works quite well. I pretend to use it instead of the MD2 loader for any upcoming 3D games.

Check out the github repo below, and the live demo here. Models are: Ronaldo by me, the others from opengameart.org.


Monday, 28 July 2014

My "games" - Super Mario 64 in HTML5 and WebGL using three.js

A small experiment I made in three.js, to test it's capabilities.

Most three.js examples available on the web are very simple and do not show interactivity like the one you see in a videogame. So I chose to replicate Super Mario 64's first level, Bob-omb Battlefield, in three.js and HTML5 technologies.

The art is actually ripped from the original game. The models I got from this site, "The models resource". They all come in .obj and .mtl models, which are easy to load with three.js (one of the examples show how, I modified the MTLLoader to use MeshBasicMaterials instead of MeshPhongMaterials to get the look a Nintendo 64 game). The jump sounds I got from this pack of sounds from SM64 at Mario Fan Games Galaxy. Last but not least, the level's theme I got from this video. I downloaded the audio of the video with Youtube to MP3 and I converted the MP3 to OGG for greater HTML5 usability with this online audio converter.

I really hope I don't receive a good old Nintendo cease & desist letter :D

I am considering releasing the code. I am very fond of releasing code actually, but the code for this demo is quite quick & dirty, a horrible mess. In fact, it's shameful. If I do release the code, I will also create new art, my own jumping sounds, some music from opengameart, my own models and textures... I have some ideas, like replacing Mario with a farmer called Anthony and the goombas with evil brocoli.

P.S.: I actually started this as a test for some collision code I am writing, that's why you can see some collision glitches at the video if you look carefully. As it is, it certainly does not do decent collision testing.

Tuesday, 22 July 2014

My code - MD2 loader for three.js

three.js is a fine library but it suffers from a lack of file loaders. three.js contributors have this naive "we don't need file loaders! we have our own shiny JSON formats!" bullshit. Since I am planning to use three.js in LD30, I decided to roll my own model loader. And as everyone knows, id software's MD2 is the most modern and featured model format ever.

Doing some research on previous efforts in loading binary model formats in Javascript, I found this WebGL MD2 loader and renderer. At first I thought I could simply use this guy's loading code and write some code to convert the loaded mesh to a three.js geometry object, but I was wrong, as his code was quite bug-ridden. So I ended up changing a lot of things.

Summary of changes:

  • First of all, I renamed his inferior snake_case variables to use my superior camelCase standards.
  • I also changed things like a "vertex index" array to a "verticum indices" array, as I mind to use proper latin.
  • I changed the loading with XMLHttpRequest to be asynchronous, as is the standard when loading resources from different files in web development.
  • I changed the binary interface, the original was buggy and no longer mantained, to use jDataView instead.
  • I made it sure that the file is loaded in the correct endiannes (little endian).
  • I rewrote the file ID checking, because the identifier is not an actual string.
  • I don't divide the texture coordinates by the texture size to get s and t as I load them, since some MD2 exporters set invalid texture sizes.
  • I solved a problem with the loading of frame and animation names.
  • I added skin name loading code.
  • I wrote code to convert the loaded model to a three.js geometry.
I changed so much I can't even call my code "derivative" anymore, it's totally different.

You can check out the live demo of the loader here. And you can click on the cat below to check out the Github repo:


Sunday, 20 July 2014

My games - Breakout clone for 6502asm

The screenshot above doesn't look very interesting, as it is from a pretty standard Breakout-style game. However, it will surely look more interesting if I tell you I made this in Assembly, 6502 CPU (the same the NES used) Assembly nonetheless.

More specifically, for this 6502 virtual machine in HTML5. I actually recommend you play the game at this development version of the VM, as it's way faster.

I made this after someone (the logs say bitslap and/or voxel) mentioned this VM in the #ludumdare @ AfterNET chat. Jedi helped me with some issues.

I enjoyed this experience in the lower levels of programming. I may find the will to do another game for this VM, most likely Tetris, and perhaps I may try making a NES game.

Here is the github repo for the game. The code does have detailed explanations, mostly in what I imagine to be C code equivalent (it would be more adequate to say mimetic) to the Assembly code.

Friday, 2 May 2014

My games - Ground control to major Tomashevsky (Ludum Dare 29)

This last weekend (days 25-27th April) saw the 29th iteration of the Ludum Dare 48h game development competition. And it was the third time I took part in Ludum Dare. The first time, I didn't finish my game on time, a game I have yet to speak about here, and so the only thing left from that distant event in 2012 is this warmup game (the week before a Ludum Dare event is the "warmup week" where people create games to test their tools and abilities). The second time I was rather disappointed by my dull submission that can barely be called a "game". At least I had some fun trolling with other people's entries. This time, however, I finally achieved success in both submitting a game and being satisfied with what I had developed.

I recently left my favored combination of C++ and Allegro to focus on HTML5 and Javascript, as I have been thinking and I realized I might be more productive developing games with Javascript's paradigms. Using entity systems based on classes, inheritance and polymorphism in C++ isn't as productive as coding them with the more liberal Javascript syntax. The weekend before I had made my warmup game where I tested those new tools, finding them to be most appreciable. I also compiled a small, that yet turned to be very useful, codebase.

But let's talk about my submission.



http://www.ludumdare.com/compo/ludum-dare-29/?action=preview&uid=11663

The theme, and my interpretation of it

The chosen theme this LD was "Beneath the surface". This was a good thing, as everyone was expecting "Break the rules" and I think "Break the rules" would suck. I was also in the expectation for "Night & Day" (I was thinking of making a game where you are the vampire: WHAT A HORRIBLE MORNING TO HAVE A CURSE) or "You control more than one" (in which case I'd be forced to make something similar to my warmup game).

Since I wasn't expecting "Beneath the surface" I went looking in Google Images for "Beneath the surface" results. They were mostly submarine photography, sunken ships, divers and petroleum well diagrams. None of those interested me. However, I remembered a distant information from this xkcd What if:


However I didn't recall immediately from where I was recalling this information and I started reading Wikipedia's articles on random planets and I saw myself with this:


So I had decided: I was going to make a game about Neptune, and the surface beneath which something would stand would be it's ammonia ocean. In the end, it was good I went with Neptune and not with Jupiter, as it's way more beautiful than Jupiter.

Implementing the theme, or, the plot of the game

As soon as I decided to make a game about Neptune I decided that the player character would be an astronaut. While making his sprite, I decided to make him a cosmonaut instead, i.e. to put a red CCCP on his helmet and make him a spaceman from the Soviet Union. Not only this would make the whole thematic more interesting, it would let me to add russian voices and faux cyrillic.

And thinking of space I started humming Space Oddity by David Bowie, a song I like very much. It was a matter of time before I decided to make it into the plot. Specially the ending of the song:

Ground control to Major Tom
Your circuit's dead, there's something wrong
Can you hear me Major Tom?
Can you hear me Major Tom?
Can you hear me Major Tom?
Can you...
Here am I floating round my tin can
Far above the moon
Planet Earth is blue, and there's nothing I can do....
With this in mind, the cosmonaut would be stranded to Neptune after his communications with Earth (with the Motherland!) failed. Why, if I was using Space Oddity, not to use David Bowie's inspiration too, 2001: A space odyssey? Specially, I was inspired by this scene:


How this appears into the game I shall not reveal, for spoilers. The last effect those sources had on my game is the name, that I changed just before the submission: before that I thought of "Ice giant" in a reference to Neptune and "Red eagle above the blue skies" in a reference to the soviet cosmonaut and the color of such planet. Now that I think of it, those names suck.

Creating the graphics, or, shaping the ideas into the face of the game

As it can be seen on the game creation's timelapse, the sprites and images were all done using very simple GIMP tools, and aren't that great in style: they are quite shallow, in fact. They look good, however, and represent very well what I tried to accomplish.

Some things I learned how to make on the spot. Among them, the space backgrounds, like the one below:


I learned to make those backgrounds in GIMP using this tutorial. Thanks to chickenbellyfin for the game's astonishing visuals.

On one of the game's sprites, to achieve a 3D effect, I used this GIF making tool. It was simple to use and easy to learn on the spot. I think this kind of creativity on making assets is of great use in Ludum Dare, and a great skill to have for one-man-army game development.

Making the game's sounds, or, raising the voice of the game

This was something I saw as an obstacle. Working with sounds is an skill I don't have. Even though I know some music theory, I can't write music. And most sounds and musics that can be generated procedurally are too generic, videogameish or non-serious sounding to complement my game's atmosphere. I decided to go with a minimum usage of sound, and to hope that this would help setting the game's feeling of loneliness and despair.

As fair as sound effects go, there's only the sound you make as your feet hit the ground, the sound of your space suit rupturing when you die and the sound of your jackhammer hitting the ground when you use it.

There's also some amount of  "music", perhaps we should say small musical pieces, on the game's ending. To create them I downloaded and installed the program below from sourcefourge (also on spot!), a simple MIDI keyboard and synthesizer, and hit random chords on the C-major scale until I found something that sounded good. I then used Audacity to record this by setting it's source to Stereo Mix. Again using of that asset creation creativity I said to be useful on Ludum Dare and single guy team game development.


Creating the introduction's communication with ground control was the most challenging and most interesting aspect of the game's sound art. First, I wrote the ground control's dialog in english, and translated it to russian using Google's Translator. Then I went looking for a russian speech synthesizer. This was turned out to be harder than I thought. I though of Acapela, but they took out some of the voices available in it's demo, including the russian male voices. I eventually settled with eSpeak, "originally known as speak and originally written for Acorn/RISC_OS computers starting in 1995", i.e. a piece of prehistoric software. The synthesized speech was ridiculously monotonous and artificial, but this was good as it somehow sounds closer to the stoic words of a ground control operator. Then I opened the speech .wav file in Audacity and edited it to look like a radio transmission, following these two posts in Audacity's forums and this post in OpenGameArt's forum. In synthesis, this is how to make a radio transmission similar to the introduction sounds:

  1. Write some dialog in english
  2. Translate it to russian using Google's Translator
  3. Synthesize it into speech using eSpeak
  4. Open it in Audacity
  5. Apply the equalizer to cut out frequencies above ~2500-3000Hz and below ~150-200Hz
  6. Apply the leveler two times to make the sound "harsh"
  7. Add white noise in another track, same duration as the voice
  8. Apply steps 6 and 7 to the white noise, so it looks like it come from the same source
  9. Adjust the white noise's volume so that you can still hear the voice
The level design, or, creating a solid experience

I built the one big playable level using my own level editor I had created two days before the compo started. It has some minor bugs and annoyances I had to correct on the spot. The saving and loading of levels through JSON in the editor didn't work for some reason. Still, it was a valuable tool, as I could create different levels to test new objects as I was coding them. And when the time had come, I made a good and solid level design in it. The complete level, seemed from far away in the editor, looked like this:



The game's ending quote, or, closing the game with a golden key

I was thinking of using J. Robert Oppenheimer's quotation of the Bhagavad GitaI am become Death, the destroyer of worlds. However, something from the Manhattan project was too american to be used in a soviet themed game (except perhaps the honorable Klaus Fuchs). 2001: A space odyssey famously both starts and ends with a rendition of Also sprach Zarathustra by Richard Strauss. Why, it was obvious: I should use a quote from Thus spoke Zarathustra! (Thus spoke Zarathustra is the title in modern english of the famous book by Friedrich Nietzche, while the song has kept the archaic spelling).

The timelapse, or, my memories of this great experience



By analyzing the timelapse, I made a "time spent on each activity" pie chart, that shows how much work went into each aspect of the game:

Conclusion

Thus was, out of the most intellectually pretentious inspiration, born my LD entry. May you consider this post as it's post-partum (for it's not a post-mortem, for art never dies). Thus we must examine two most important aspects of it's anatomy:

What went right


  • The introduction, that everyone seems to love:
  • The 2001/David Bowie/soviet thematic:
  • The varied gameplay:
  • Amazingly, the level design that I made hastly in the last hours with a shitty level editor:
What went wrong
  • There were some minor annoyances with my untested level editor in the competition.
  • Just when I was finishing the level design, I found some minor bugs I had to correct with a filthy workaround:
  • I had a lot of problems with hosting:
  • There was a bug making the game unplayable in Firefox:
  • People didn't know they had to press "D" to skip dialog, so they either A) Thought they were stuck or the game had crashed; or even worse, B) Thought the game ended after the landing part. This was even though I had took the time to write all controls in the instructions screen, thus proving that people rating LD games have very little will to attempt to find the controls on their own or to look for the instructions:
  • Due to the way checkpoints are implemented, they can leave the player in an unwinnable situation:
  • Players felt annoying to play the game with the keyboard and yet have to use the mouse to click on "Continue" in the death screen:
  • Players didn't like the lighting effects, which were badly implemented, and some didn't perceive that the light affects the worm's behavior:
  • In the chart below, you can see how many times the links for my games have been clicked so far, statistics gathered through the bit.ly link stats option. Still, my game has 39 ratings so far, so it has been accessed much more than rated. This is ridiculous and denotative of lack of will from the Ludum Dare community.
All in all, it was a great experience. I rarely have the opportunity to feel like an artist, but I think this game really is a sincere art form. I am looking forward to making more art in the next Ludum Dare events.

P.S. do not forget to check out the game itself!