In my previous post, I described the concept and roadmap for my new project, Ambienome. In this post, I’ll be describing the technology (programming language and libraries) I’m using, and why I chose them.
Even though I have seven years of experience with Ruby, and my own game library, Rubygame, already available and ready to use, I’ve decided not to write Ambienome in Ruby. Instead, I’m writing it in Common Lisp, using OpenGL and OpenAL for graphics and audio.
OpenGL and OpenAL were natural choices, since they’re free, cross-platform, and widely supported with pretty much any programming language. I would have chosen these no matter what language I settled on.
GLUT is a very popular and widely supported framework, but I don’t like how you have to shape your entire program structure around GLUT’s expectations, so I quickly dismissed it. SDL is also popular, but my years of experience with it have made me keenly aware of its shortcomings. So, I decided to try GLFW first.
GLFW is pretty nice, like a less obtrusive version of GLUT. I played around with it long enough to create an abstraction layer for opening and closing the window, but then discovered that GLFW currently has no API for setting the window’s icon. That may seem like a minor detail, but it was enough to nudge me into reconsidering SDL.
Two other points in SDL’s favor are that I’m already familiar with it — unlike everything else about this project! — and that SDL 1.3 will have support for multi-touch devices, and possibly multiple mice, both of which could provide some cool ways of interacting with the game. SDL 1.3 hasn’t been released yet (after many years…), but I might try taking a snapshot of the development repository, and working with that.
So, I ported the window abstraction layer from GLFW to SDL (1.2), and added an input event abstraction layer. I’m not entirely happy with it, so I might reevaluate GLFW (or even GLUT, since I’ve read that freeglut and Apple’s GLUT let you avoid the glutMainLoop function). But for now, SDL will be enough while I figure out the challenging new stuff with OpenGL and OpenAL.
One final library worth mentioning is Clutter, which I’m considering using to create the in-game GUI. When it gets to that point, I’ll try Clutter, then look into alternative libraries if Clutter doesn’t work out. As a last resort, I could just roll my own GUI widgets, but I’d rather avoid that if I can.
OpenGL and OpenAL are pretty popular, “safe” choices of technology for game development. There are countless web articles, tutorials, books, and other learning resources available, and many experienced programmers I could turn to for help if needed. Both libraries are available on Linux, Mac, and Windows, and have bindings for many programming languages. There’s nothing particularly surprising or unusual about using OpenGL or OpenAL.
The choice to use Common Lisp, on the other hand, is likely to raise a few eyebrows. After all, it’s secret alien technology powered by excessive parentheses!
Lisp, despite its elegance and power, is not nearly as commonly used for game programming as the C language family (C++, C#, Java, etc.), Python, or probably even Ruby. If I had to speculate as to why Lisp has a low adoption rate among game programmers, I’d cite the usual factors that affect Lisp’s adoption rate in general: difficulty getting started (choosing and installing a Lisp implementation and IDE, finding good tutorials, etc.), the “strange” syntax, Lisp’s reputation as being more academic than practical, and the Lisp community’s reputation (whether deserved or not) for being somewhat elitist and unfriendly. Also, many game programmers are obsessed with raw performance, as if brute-force number crunching was the key ingredient in making a fun game. Those programmers will usually stick with C or C++, and dismiss anything else as being “too slow”.
But, I don’t particularly care about Lisp’s popularity or why other people like or dislike it. I care about having an interesting, powerful language that fits the project well.
- Like Ruby, Python, etc., Lisp promotes rapid prototyping with concise and flexible code, and sustains creative flow in a way “stop-and-compile” languages like C cannot.
- Common Lisp can be compiled to native executables, and I can declare optimizations for those situations where number crunching efficiency is needed, such as generating custom audio data.
- Lisp’s notion of “code as data” should work well with the concept of expressing behaviors as objects, and saving each creature’s behavior in a file.
- Lisp’s macro and package systems should make it really easy to create a safe, simple, and efficient domain-specific language to allow users to define new creature parts and behaviors.
- Lisp is a novel language to me, so this project is sure to be an interesting learning experience!
Before settling on Common Lisp, I also considered CoffeeScript and Clojure. CoffeeScript (using HTML5 Canvas and Audio elements) was very tempting because of the ease of deployment and cross-platform compatibility. But, HTML5 does not yet have a workable API for generating and manipulating audio data, and running in a browser would also limit my options for player-to-player file sharing and multiplayer gameplay.
As for Clojure: it’s a really interesting Lisp, and the ability to use Java libraries and compile to Java bytecode could be useful. But, learning to write a game using only immutable data structures and
So far, I’m really enjoying Common Lisp. I’ve been reading Practical Common Lisp, which is a really excellent resource for learning Common Lisp, and available online at no cost. I’m certainly not a Lisp guru yet, but I can already feel the amazing expressive power and freedom Lisp provides. This is sure to be an interesting project!