domingo, 28 de março de 2010

Engine growing pains

Where did I left off? Oh, that's right:

After playing around with Chipmunk for a while, and implementing a few of the features that I want for one of my projects, I can do little but recommend it as a great physics library, very easy to code with, with great performance, and flexible! Allowed me to prototype some more complex features I want to add (destructible objects) with ease, and its structured in a way to allow to adapt it to many game mechanic scenarios. Some tests I did on an older computer showed it performed better than Box2D, but it was a superficial test, so I won't back up that claim :)

Having a fine physics engine at my disposal, I decided I needed to create a level editor to easily start laying down levels; so, I needed a GUI. I looked around for a barebones lightweight GUI that would integrate well into Allegro, and went with the recommendations for GUIChan. It was indeed easy to integrate and use, and allowed me to design a GUI that let me add floors, walls and connect them with joints. This gave me an incredible sense of achievement, motivation, and the project started feeling more like a game and less like tech development, which was great. And doing levels in it was fun :)

From this point, the code to connect the several engine parts was becoming a bit muddled, so I took a break to refactor it, and from there decided I needed to integrate scripting into the Engine, to allow for easier prototyping (I frequently realize that doing something that will apparently take a long time pays off in the long run, as it simplifies greatly the work and speeds it up after it is integrated and working).

I looked around for available scripting engines, considering Lua, GameMonkey, Angelscript, Squirrel (I rejected Javascript as I don't quite like its syntax). I had some experience working with Lua, and it's generally the, but Wolfire's reasons to their choice for scripting engine sounded quite reasonable (most importantly to me, C++ native integration and syntax), and the Internet showed me that AngelScript was showing a lot of promise, so in I went.

I can say from my experience, integrating a new and unknown library into a project always involves some degree of time needed just to become acquainted with it's workings and quirks, and for integrating a scripting library, it takes quite a lot of time. After this initial period of figuring AngelScript's binding format and details, it was very rewarding to see my "main" function reduced to a few lines and the main code running from a script file, from there having access to all of my engine, being it graphics, gui or physics :)

The next step was to integrate Hardware Graphic Acceleration into Allegro's drawing routines.
I have been an Allegro fan for quite a few years, since I was exposed to Johan Peitz's excellent games "Alex the Allegator", "Operation Spacehog" and "Icy Tower", which I played extensively and all used Allegro).

It presents lots of great features for quickly prototyping games, but being a library with a long legacy (from early DOS days), nowadays it requires a few add-ons to have important features, such as Jpeg and Png loading, and hardware acceleration for graphic rendering (and subsequent benefits from hardware rendering, such as fast transparency and lighting effects).

With these being features I need for my projects, I looked into integrating hardware acceleration into Allegro, based on available libraries. The most obvious options were AllegroGL, which allows making OpenGL calls directly from Allegro (but requires knowledge of OpenGL, of which I possess but am quite rusty on:) ), or OpenLayer, which nicely covers all of OpenGL's technical stuff under a simple API. So, OpenLayer it was.

...happily I went to integrate OpenLayer. Everything was going well, until... I wanted to load a Jpeg. OpenLayer natively allows png loading, but provides no support for Jpeg. "Ok", I think "I'll just the jpeg loader which I had previously included, it let's me load jpegs into Allegro fine".

Turns out it wasn't so easy. OpenLayer was not doing well with me making non-Openlayer Allegro calls, which were necessary to load jpegs, and was not being capable of obtaining the data I passed onto it after loading from the image file. Looking around the web for some help or a solution made the problem obvious: OpenLayer once had a forum/mailing list, but is now discontinued; all the help I could get would be from Allegro's forums, but I could not find any information related to the problem I was facing, and to add the fact that OpenLayer had not been updated since 2007, I figured it was better to try another approach: move on.

I went for a walk on the cold night air, to think it through, ponder my choices and come to a sound decision. Removing Allegro would involve refactoring most of the engine (and possibly losing the chance to use GUIChan), which would take extra time. However, with what I knew at the time, it was something I needed to do.

So I looked for alternatives, from "game libraries", to "graphic libraries" to "game engines" (the difference between a library and an engine being that a library is code that integrates into other code, generally in C or C++, and an engine provides a more or less "complete" set of game necessary features such as graphics, sound, input, and collision/physics and is interacted with trough a scripting language, which allows for faster prototype/game development but is less flexible to adapt to your needs and probably slower than a game engine customized by yourself).

So, for the switch from Allegro to another library, I went with Simple and Fast Multimedia Library (SFML), an excellently documented (tutorials are the best documentation ever!), with a live community, great and simple API and feature complete for what I needed.
I also considered using a 3D engine (Irrlicht, which I have some experience with and found very fast, unlike Ogre3D, and is used by Soldat's Michał Marcinkowski to a similar end that I would use), or an already available "game engine", such as "cocos2d", "angel-engine", "indielib", "love2d", or 2dboy's "rapid-prototyping-framework".

Fortunately, SFML's great design and easy to follow documentation, and the fact that I already had the design for my engine decided and thought out made the reimplementation quick and painless. I strongly recommend SFML as a 2D game development library :)

So now the Engine is composed of:

SFML - Windowing, Graphics (Hardware accelerated), Input, Image/Font/Sound loading (and much more :))
GUI - still to determine (possibilities: CEGUI, cpGUI, GUIChan with SFML wrapper)
AngelScript - for Scripting
Chipmunk - Physics library

P.S: at the time I was thinking/looking for alternatives, I totally forgot that Allegro's recent branch (which will become Allegro 5) has included hardware acceleration and png/jpeg loading, which were the main features I needed to add. However, it's always refered to as "work in progress" and "unstable" and there weren't many Internet references to it, so it's probably best to avoid it for a while, and keep SFML as my current engine.

So currently, I'm working on an animation system and resource management. Next, re-exposing the new engine to AngelScript, and finding a GUI. Then, defining and adding game objects including both visual and physical representations :) And from there, a game level with most/all game features in it (and naturally, starting work on graphics).