Thursday, August 2, 2012

Chickenpix!

Long time, no post


I don't think anybody is really following this blog (except some of my most curious colleagues), but let's pretend for a second that I have an audience. I did not post anything for the last six months, mainly because I had nothing technical I considered worth sharing and I do not want this blog to become a diary of my breakfasts or other useless stuff. I does not mean I did nothing: just that the things I did were too small for me to talk about.

For instance, I picked up nurikabe. This is a puzzle game in the vein of sudoku, with rules that are, at first, a bit difficult to understand, but lead to an intersting way to waste one's time. There are parts that make it look like minesweeper (there are numbers that represent a count of something you have to find), others are more akin to the game of go (the black "stream" must be in one piece, so that you have to escape atari). It's nice to play "manually". And of course I wrote a solver, because that's what I do. But nothing exceptionnal to show: only a few heuristics bound with a brutish force search.

Game of nurikabe in progress

At one point, I tried to switch views, and wondered how the site I referenced above could generate all those puzzles. I probably did not spend enough time on that task, and have not come to a working model of how to do that. Nothing to show again.

I worked a bit on my other HTML5 game (a simple tower defense revolving around programmers and the SCRUM methodology, if you want to know). But I did not make enough progress to show it.

And then...


I spotted in the news that the OpenGameArt site was hosting an art & game programming contest during the summer, with open source and free software sponsors (the FSF, Mozilla, Creative Commons). I thought it would be interesting, and I asked a few colleagues if they wanted to participate, to help create team motivation. And so, during the last two months, I spent all my spare time working on that project. We started with a team of about eight people, but we ended up being only two to push any code. I think we did not really succeed in creating enough momentum, and the end result is not really a game, just a technical prototype of what the game could have been. It's called Chickenpix (hence the title of this post).

At first, since most potential coders were fluent in C++, we decided to choose that language over JavaScript. Then we looked for a portable and open source low-level libary that could fit our needs. We kept two of them, ClanLib and SFML. Why didn't we stick with only one? It would have been simpler, but my fellow coder worked on OSX and he could not make ClanLib work on his machine. And on the other side, I worked mainly on Linux in a VirtualBox VM, and SFML was awfully slow when rendering. I also wanted to make a Windows build, but with Visual Studio Express 2010, SFML was a nightmare to link, and I eventually gave up.

For the architecture, I wanted to experiment with the entity-component-system approach. Each game object (entity) is effectively nothing more than a container of components. Those components, in turn, are generally simple data structures containing state information. All the logic is then performed by the systems that are present. Any entity can contain any kind of components, and they can be added and removed dynamically.

The whole cast of characters

For instance, in chickenpix we have a dozen components, among which a Transform component holding the current position, a Mobile component for things that move, a Visual component for entities that need to be shown, and also Animated, Input, Audio, Camera, Scriptable, Collider. On the systems side, there is a Render system, that collects all entities with a Visual component, finds the Camera and displays everything accoding to their Transform. There is a Movement system that does the "physics" simulation, an Inputs system that gathers user input (keyboard and mouse) and calls contollers, a Scripting system that executes scripts.

Talking of scripting, we quickly evaluated the usual open-source possibilities for embedding: JavaScript with V8, lua with luajit and Python. V8 was rejected because we could not find a binary release, we could not make it build on Windows and we simply did not persevere. lua was deemed too "low-level" and unknown to almost all participants. I was all for Python and some other people knew it a little, but I had never embedded it. It ended up easy enough, once the reference count scheme was understood.

Technically, that's about all there is too say. And on the game design side, well... there was not really any time left for that.

Lessons learned


Working with other mildly motivated people, on a short schedule, in the middle of Summer is not the best way to build momentum. The human factor trumps the technical ones.

C++ is not as bad as I anticipated. Mind you, I already knew C++, but it had been a long time since I did anything more than a toy program with it. I was afraid of manual memory management and the associated problems. Lots of logging and some gdb sessions to pinpoint the cause of segfaults was enough to cure those.

Developing on the three main desktop platforms in parallel is not too hard, especially when each coder has a different preference and handles his platform himself. I have no other data point to really compare it to porting only after the first working version is done. I suspect there is a slight advantage with the multi-platform approach because the versions never have the possibility to diverge.

Supporting several low-level libraries was not too difficult and probably had a good effect on the architecture of the code. It forced us to think on a higher level and to provide adequate interfaces.

Entity-Component-System is interesting and has some good properties. But as all good things in life, you have to learn not to abuse it. Having the resource loading facility be a component of a fake entity seems like a hack, in retrospect. And having to switch between several modes of play led us to design transitions between distinct entity managers. I'm not sure it's the best way to do it.

We're not going to compete with Unity just yet.

Embedding Python for scripting is cool. The C API is easy enough to master and very well documented. No need to stress the benefit of scripting for games in general: it transforms part of the logic into "data" and data-driven programs are simply better (easier to test and reason about, no need to recompile for every change...)

Working in a virtual machine is kind of nice (you can switch physical machines by just moving the image) but there are still limitations when developing a game. Graphics hardware acceleration does not seem to work out of the box just yet.

Google webfonts is a great resource for free (as in freedom) fonts, not limited to the web.

github provides excellent tools for collaboration, that I had not yet tried when working alone: wiki, web pages, issue list, downloads. The code statistics and graphs are nice, but they give strange results sometimes (we did not code a single line of Objective-C!).


To all other LPC participants: good luck! Chickenpix has been a nice experience, but the final game will not be an obstacle on your way to victory :)


1 comment:

  1. You have at least 1 audience that is not a co-worker =)

    ReplyDelete