Hello all, I've recently been working on a game development project in Clojure which is now starting to bear fruit. I thought people here might be interested, and that it would be worthwhile to share some experiences and perspectives.
The project is a steampunk-themed strategy game, and a playable in- development version is available here: http://mikera.net/ironclad/ Overall, I think Clojure is a fantastic language for game development. Some thought on what makes it really compelling: 1. Immutable data structures work surprisingly well for games. I represent the entire game state with a big defrecord, and the main engine loop is basically: a) Get commands from player / AI (e.g. "Move unit from A to B") b) Convert each command into set of atomic updates ("Remove unit from A", "Add unit to B") c) Apply updates sequentially to the game state d) Trigger any feedback to player e.g. animations, sounds 2. Concurrency support has been very helpful. With immutable game state, it has been trivial to separate the game engine from the renderer from the AI calculations - each effectively gets to operate on its own "snapshot" of the entire game state. This can be a big headache in many game engines that have to mediate access to a single, mutable game state. I can also see even greater benefits when I finally start adding some multi-player features. 3. High level, functional programming works great for rapid, iterative and dynamic development. Of all the languages I've used, Clojure has probably been quickest in terms of time required to add a given new piece of functionality. For example, the map generator code probably only took about 30 minutes to write, pretty good for a fractal landscape generation system! 4. The Java interoperability support is fantastic - definitely counts as one of the "killer features" of Clojure. I've been able to reuse a lot of Java code libraries, both my own and standard libraries such as Swing. As an example, I have a well optimised immutable persistent 2D grid data structure in Java (basically a very efficient, spatially partitioned map from (int,int) to Object) that I have been able to use pretty much seamlessly in Clojure thanks to extend-protocol and similar. Some interesting observations / discoveries / surprises in the process: 1. The game worked first time on Mac and Linux, despite having been tested exclusively on Windows. Great kudos to to both the Java platform and the Clojure libraries! 2. Reflection is *really slow*. After getting 20-100x speedups from eliminating reflection warnings in the AI code, I now treat any reflection warning in code other than one-time setup code as a bug to be fixed immediately. Finally, here are some things I think could be great improvements to Clojure in the future from a game developer's perspective: 1. Better support for primitive parameters / return values / unchecked arithmetic - in performance sensitive code, these are pretty much essential. In a few cases in the graphics and AI code, I've had to drop back to Java to get the performance I need. 2. It would be great to reduce the amount of memory allocations. Yes, I know memory is plentiful and GC is very cheap, but it's still not as cheap as stack allocation and any noticeable GC pauses are not good for the player experience in interactive games. For this reason, I find myself using reduce and indexed loops a lot more than I guess would normally be idiomatic, and conversely tend to avoid some of the lazy constructs and functions that generate sequences. While Clojure is great for a strategy game, I'd probably hesitate to use it for a real-time 3D game. 3. I think it would be great to have better support for circular references - perhaps a two-pass compile? The reason this is particularly acute in game development is that different subsystems have quite a lot of inter-dependencies. AI evaluation system needs to understand game state/engine so it can evaluate a position. Game state/ engine needs to understand units so it can manipulate them. Units need to understand AI evaluation system so they can decide which actions to take...... obviously it's possible to work around all this, but it's a major pain, adds complexity and means that you need to structure code to manage dependencies rather than in logical modules (which would be easier to manage and maintain!) Would love to hear thoughts, and particularly any other experiences people have had in using Clojure for game development! Mike. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en