October 2013 Programming Projects

28 Oct 2013

Dwarf Fortress Linux Installer

At the beginning of the month I completed Revision 0.3.0 of the df-lnp-installer. Naturally this was followed by two bugfix releases as it made its way out into the real world. The 0.3 branch was a particularly big push for me, though, as I had to learn a lot of new things.

Most importantly, though, I had a realization from the 0.3.x branch that I miss unit tests. When I'm writing Ruby code, like in my RubyPI project, there's a fantastic unit test library built into Ruby that I can use. BASH doesn't include built-in unit test support, much less the POSIX-only shell code I'm writing for Dash. I'm finding that writing unit tests helps me frame the code better, forces me to think about code responsibilities ahead of time, and then on the post-production side, helps me sleep better at night knowing I'll never have to deal with that bug again.

Unit tests also prevents me from deleting users' ~/.local directories. Whoops. So one of my goals for 0.4.x is to add unit tests to df-lnp-installer.

Teaching Myself C... Again

When working on Ruby and Shell projects (my two primary programming languages), I keep running into issues that could be solved if I was only writing in C/C++. For example, I have a couple of video games I'd love to write. For reasons not entirely unrelated to the death of Zork-like adventure games, I can't write these game ideas I have in Shell. But why not Ruby?

Before I can answer that, I need to explain one thing: why I really want my game to use SDL 2.0.

Ryan Gordon, better known by his handle icculus, has been working on cross-platform game development for years. I was hitting up for Linux game ports and installers in high school. Lately he's been working on porting games to SDL 2.0, which came out in May. Just before the 2.0 launch he said this on twitter:

"Moving a game from SDL 1.2 to 2.0 solves so many little annoyances that I've merely trained myself to tolerate over the years."

That by itself is enough of an endorsement for me to want SDL 2.0. But having spent some time looking at the 1.2 and 2.0 API differences lately, 2.0 makes writing modern game features (like simple OpenGL support) so much simpler. Here's a quick overview shamelessly stolen from the Migration Guide:

  • Full 3D hardware acceleration
  • Support for OpenGL 3.0+ in various profiles (core, compatibility, debug, robust, etc)
  • Support for OpenGL ES
  • Support for multiple windows
  • Support for multiple displays
  • Support for multiple audio devices
  • Android and iOS support
  • Simple 2D rendering API that can use Direct3D, OpenGL, OpenGL ES, or software rendering behind the scenes
  • Force Feedback available on Windows, Mac OS X and Linux
  • XInput and XAudio2 support for Windows
  • Atomic operations
  • Power management (exposes battery life remaining, etc)
  • Shaped windows
  • 32-bit audio (int and float)
  • Simplified Game Controller API (the Joystick API is still here, too!)
  • Touch support (multitouch, gestures, etc)
  • Better fullscreen support
  • Better keyboard support (scancodes vs keycodes, etc).
  • Message boxes
  • Clipboard support
  • Basic Drag'n'Drop support
  • Proper unicode input and IME support
  • A really powerful assert macro
  • zlib license instead of LGPL.
  • Lots of old annoyances from 1.2 are gone
  • Many other things!

So why not Ruby and SDL 2?

  1. RubyGame, which I've written a few demo games in (e.g. Pong) and really like, is no longer maintained. Also it's built on SDL 1.2 and there's no chance in hell for a port.
  2. Gosu, the other major Ruby gaming framework, is actively maintained, but it's also built on 1.2. A recent forum thread (I forget where I saw it) said 2.0 support was upcoming but didn't have a timeframe.
  3. I can't roll my own using FFI because, as of today, FFI is no longer maintained. Apparently there was a licensing issue. :(
  4. Ruby is not performant enough for heavy duty game engines. While it works great for many programs, when you don't have a lot of CPU and RAM to throw at the runtime environment, Ruby is significantly behind C in computational and memory-management benchmarks.
  5. Ruby games don't package well. Because Ruby is a scripted language, it needs to have the source files available to read. If you're trying to create a closed-source game, that just doesn't compute. If you're ok with making an open source game, the best packager that's available is Ocra + Releasy, and my experience with it on RubyPI says it's unreliable, at best.

So... I've been teaching myself C. I've found three significant sources of learning

More info on my C progress as I actually manage to complete something interesting.