Edit: This was initially intended to be just one post, but after detailing some history on the project, it has grown quite long. I’m going to be splitting it into two or more parts for the sake of organization and sanity.
Some preface to this to outline the history of this project over the past couple of years. So about 2-3 years ago now, after playing this excellent flash game which has finally gained the recognition it deserves, I started designing some programmer art in the form of a very small pixelated ninja as well as some samurai enemies. The idea was to create a game in homage to N, but to focus on very different elements (combat, stealth), including a “ninja grappling hook/ninja rope” with mechanics lifted from Worms.
As noted above, initially I started out drawing very small bitmap images of my main character and some enemies. The idea was to go ahead and build a simple 2D parallax scroller. This was going all well and good, and I had assembled frames for probably 5-10 animations. At this point, I was starting to get burnt out drawing sprites, which I’ve always found to be rather ineffective at capturing motion in two dimensions. The project got moved to the back burner for a while, and I basically lost interest for the next six months.
Eventually, I was playing around with Inkscape and managed to build a much nicer, vector based ninja character. Initially the idea was to simply replace my older, much lower resolution bitmaps with the newer, differently styled character in the simple parallax scroller engine. Soon, however, I became dissatisified with this idea for the same reasons that sprite sheets have always left a bad taste in my mouth.
So I decided then that, hell, why not just rasterize the loaded SVG file and animate it with a simple bones system. I outlined some basic guidelines for the project.
- The pipeline would ideally be: Inkscape -> .svg file -> engine, with as little or no intermediary steps as possible.
- I would utilize as many libraries as possible for the core “plumbing” of the engine and the SVG related functionality.
- Whatever rasterization library I decided to use must be fast enough to allow re-rasterizing the SVG vectors at least once per frame.
- Libraries would ideally be cross-platform, or at least work on Windows (I am partial to Visual Studio…sue me).
- Most crucial of all, whatever library would be used to load SVG files MUST allow me to access and change the values of path segment control points.
These guidelines turned out to be the cause of the project’s very long term back-burnering. I evaluated dozens of libraries, code snippets and projects over the course of the two years between me realizing these requirements rather limited me and the present.
Initially, I settled on Cairo, and actually got a fairly workable prototype, that allowed me to render my level and character, and I even got movement and basic collision working. However, I quickly found out that Cairo’s rasterization process is horrendously slow, allowing me to rasterize and render only 1-2 very very simple (talking like… move to, line to) paths per frame. Very soon after that, I found out that Cairo tries very hard to disallow the user of the library from accessing any internal representation of the path data. After fiddling with Cairo for a couple of months, I ditched it entirely and the project went back to the dreaded back burner.
Fast forward a year or so, and so began my attempts to use QT4 for rasterization and rendering. First thing to check: Is it fast enough? QT4 gets the green on this, it can rasterize and render hundreds of paths per frame. Perfect! Second thing to check: Can I access the path data? Hellfuckno. QT4 tries very very very hard to abstract almost every detail of what really goes on from the user level library programmer. Third but relatively minor issue: licensing. I would be unable to sell the game even if I completed, without purchasing a QT license. A good friend that owns one offered to publish the game for me if I ended up using QT. Great, I thought, now I just have to change the QT lib so I can get at the data I need.
Two weeks or so of fiddling for an hour at a time, and I hit the roadblock for QT, which was that my changes to the lib were essentially returning garbage data. The guys at Trolltech support were AWESOME and given that I wasn’t even a license holder, and I was poking around in the lib itself, I’m suprised they helped me so much. Infinite kudos to Trolltech guys, you are awesome. Alas, project again goes on the back burner after Trolltech is stumped by the odd behavior as well.
Fast forward again some, I’d found a great little vector rendering lib called ShivaVG based on Khronos Group’s OpenVG. I checked my first two Important Factors in Evaluating a Vector Rendering Library for a Game Project, and determined that 1) Shiva was indeed fast enough, rendering the rather complex (and famous) tiger.svg example at a decent 70ish FPS (maybe more, might have had v-sync). The second factor, access to the underlying path data, was a no brainer, because ShivaVG contains absolutely no loading functionality. The tiger’s head was comprised entirely of arrays in a header specifically for it.
Great! I thought, now all I have to do is find a good library to load SVG files. So I poke around, and nothing really surfaces, so I dig deeper and basically come to find out that a good lightweight SVG loading library written in C/C++ actually doesn’t really exist at all. There are some standalone libs written in Java, Python, C# etc., but none in C/C++.
Project, back burner, back burner, project. You two should get comfortable, it’s going to be long wait.
Tune in next time for part two, in which I detail the current status of the project, as well as the nifty things I’ve built to support it.
Here is the programmer art ninja character in his semi-final state (he may get more detail/patterns at some point):