Fixing Rubygame's fragile development model

Deadlines and work-related stress continue to stomp on my head. I have very little energy / motivation left for anything else, lately.

What's that? Go cry, emo kid, you say? You're right, enough of my whining.

Two things are becoming increasingly clear:

  1. I really need to figure out a way to reduce the work stress, and have more motivation for other things.
  2. Rubygame's development model is very fragile.

#1 is not very interesting to you, so I'll talk about #2.

Rubygame's development model is fragile, for the simple reason that I'm the only "active" Rubygame developer. This has been true for most of Rubygame's lifetime, aside from brief periods where some developer would come along for a while, then wander off.

And given the amount of time I've been able to put into Rubygame lately, calling me an "active" developer is stretching the word quite a bit. Really, there aren't any active Rubygame developers. Nobody's actively working on it. It's just sitting there. (Sadly, this too has been true for most of Rubygame's lifetime, aside from brief bursts of productivity.)

Clearly, that's a problem. The obvious solution is to get more people involved, so that even when I'm busy, Rubygame doesn't stagnate.

How would somebody get involved? Maybe like this:

  1. Choose an open ticket that you think you could handle. Or something new. Whatever floats your boat. I'm not picky, I just want to keep Rubygame active and relevant.
  2. Create a fork of Rubygame on Github.
  3. Do the work in your fork.
  4. Send me a pull request.
  5. I'll pull the changes, and if it looks good, merge them into the "official" Rubygame and close the ticket.

The nice thing about that system is that you don't have to dedicate yourself to Rubygame if you don't want to. Yeah, it would be really nice to have a dozen developers making weekly contributions to Rubygame, but not everybody has the time for that. The system would work fine even if you only make one contribution to Rubygame.

Anyway, that's my idea. If it still seems sane in the morning, I'll see if I can write up a call for developers and go fishing.

Too dang busy these days

Alas, crunch time at work and other obligations have meant little to no time for either Rubygame or Rebirth the past few weeks. I'm hoping to get back into it tomorrow, since we just got past a deadline today and things will be winding down for a while.

A few noteworthy items:

  • I'm maneuvering to have the forums from rubygameforums.com moved to forums.rubygame.org. Partly for my own nefarious purposes (Muahaha!), but mostly because the hosting provider for RGF.com is somewhat flakey, and Venut (who set it up) seems to be MIA these days. I'm hoping to get a DB dump from him so the existing posts won't be lost, but it has been almost a week since I contacted him about that... we'll see.
  • Also as part of my evil master plan, I'll be moving the rubygame web site from rubygame.sourceforge.net here to rubygame.org. It's rather due for an update, as well.
  • I've announced the date for the RubyWeekend #2 contest. It will be the weekend of July 25. I'll post more about it as that date approaches.

Vote for your favorite RubyWeekend entry!

The RubyWeekend contest finished up this past Sunday/Monday (timezone depending). We got 7 entries: 4 written in Rubygame, 2 in Gosu, and 1 simple 'game' just using the text console!

You've still got a few days to try them out and vote for your 3 favorites! There are also screencast videos of all the games in action, and post-mortems from the developers talking about their experience.

Despite some organization troubles and short notice, the contest was a lot of fun for all involved. We'll probably have another contest next month!

Working on new event classes

It's amazing how much you can get done when you're not banging your head against Autotest. I made 54 commits today, implementing the RSpec Rake tasks I wrote about earlier, and added 5 event classes, with specs:

  • KeyPressed
  • KeyReleased
  • MousePressed
  • MouseReleased
  • MouseMoved

(Hrmm, I still need to add documentation. That'll have to wait until tomorrow.)

As a reminder, version 2.4 will contain an alternative suite of event classes, as well as a new event hook system. The new event classes make obsolete the old ones, which will be removed in 3.0. So far, the new classes are pretty similar to the old ones, and I expect almost all of them to be drop-in replacements for the old classes.

P.S. It has been fun working with Git, practicing my branching and merging, and making small commits. If you want to check out the new event classes, I'm working in the cleverly-named new_event_classes branch. When I'm done with that, I'll be merging it back into master.

Not digging Github's Lighthouse integration

Lighthouse by itself seems nice. Mostly, I like the simplicity and ease of use, but Github's integration with Lighthouse seemed interesting as well. The idea of closing Lighthouse tickets by putting a special notice in the Git commit log sounds like it might be a vaguely useful feature. (Rather than, say, a useless gimmick.)

But I'm really not a fan of how it floods the Lighthouse project with every single commit I make. There's a commit log on Github, where I can actually see the diff; why would I want a second, crippled, spammy commit log on Lighthouse?

Unfortunately there doesn't seem to be any way to disable sending the commit logs while still keeping the ticket-closing, so I'm just going to have to disable Lighthouse integration altogether.

Conveniently run one spec file from Rake

After my frustrating ordeal with Autotest last night, I decided that if Autotest didn't want to cooperate, I at least needed to set up an easier way to manually run specs for a single file.

This rule allows more convenient access to individual spec files, without the hassle of rake spec SPEC_FILE="spec/foo_spec.rb".

require 'spec/rake/spectask'

rule(/spec:.+/) do |t|
  name = t.name.gsub("spec:","")

  path = File.join( File.dirname(__FILE__),'spec','%s_spec.rb'%name )

  if File.exist? path
    Spec::Rake::SpecTask.new(name) do |t|
      t.spec_files = [path]
    end

    puts "\nRunning spec/%s_spec.rb"%[name]

    Rake::Task[name].invoke
  else
    puts "File does not exist: %s"%path
  end

end

It dynamically creates and invokes a SpecTask depending on the task name you give it. For example, if you run rake spec:color, it will run the specs in spec/color_spec.rb. You can run multiple specs (rake spec:color spec:music spec:surface), or even run specs in a subdirectory of spec (rake spec:foo/bar).

For completeness, I also defined a spec:all task which runs all specs. This is pretty simple, but I'll post it here in case it helps someone:

namespace :spec do
  desc "Run all specs"
  Spec::Rake::SpecTask.new(:all) do |t|
    t.spec_files = FileList['spec/*_spec.rb']
  end
end

Trying and failing to set up Autotest

Instead of writing specs for the new event system, I've just wasted an evening trying to set up Autotest to work with Rubygame's specs. The challenge is that Rubygame is not laid out in a shallow lib directory like Autotest wants, so I'm trying to help it find out which spec goes which which file.

I've read about the dot-autotest file where you can define hooks and mappings to help Autotest out, but I can't for the life of me get a working mapping. Here's one I tried:

Autotest.add_hook :initialize do |at|

  at.add_mapping( %r%^lib/rubygame/([^/]*)\.rb$% ) {
    at.files_matching %r%^spec/#{$1}_spec\.rb$%
  }

end

I'd expect this to match, for example, lib/rubygame/color.rb — the regexp matches that string, yet the hook is never even run, and I have no idea why. And even when I have a hook that runs (e.g. with the regexp /(.*)/), $1 and the other match variables aren't set, which vastly limits the usefulness of add_mapping.

Maybe if I spent several of my life digging through the ZenTest source, I could figure out what's going on. But frankly, I'm fed up with it. It'd be less of a PITA to just manually run the specs, than try to coax Autotest into doing what should be a simple task.

Rubygame is on Github & Lighthouse

I've established a Github repository and Lighthouse project for Rubygame:

Why the switch?

  1. I've beheld the tree of Git, and it is beautiful, with many branches. Subversion just doesn't cut it anymore.
  2. Github kicks ass.
  3. SourceForge's issue tracker has never cut it. It's a user-unfriendly piece of garbage, and always has been.
  4. Lighthouse seems to kick ass, too, based on my initial foray.

Assuming this works out, the Subversion repository on Sourceforge will be "frozen" after committing a note to let people know what happened (as well as an announcement by email, naturally). Of course, I have backups of the whole repository in case things turn south later on. The issue trackers will also be closed, after open issues have been moved to

Eventually I'll be migrating the web site here to rubygame.org. Generally, I'm keen to move away from SourceForge, as I've grown weary of their awkward working procedures and increasing commercialization.

RubyWeekend Game Contest, June 13 - 15

A bit of short notice, but we've having a small game creation contest starting this Friday, June 13 at 20:00 GMT 16:00 GMT, and lasting until Sunday Monday 04:00 GMT . The contest is called RubyWeekend, as a cheap knock-off of Pygame's "PyWeek" (just like Rubygame is a cheap knock-off of Pygame, right?). The idea is to promote Ruby as a viable language for writing games, and have a lot of fun doing it.

The contest starts when the theme is announced on Friday — then you have to write a game with that theme before the contest ends on Sunday!

Think it's impossible to write a game in just 2 days? The key is to come up with a fun and creative idea that won't take a lot of time to implement. You'll also have to manage your time well, not letting yourself get stuck on little details, and deciding when (or if) to sleep! It's a lot of fun, and a huge adrenaline rush!

You're not limited to only Rubygame — you can use whatever you like, as long your game is written in Ruby. That could be Gosu, Ruby-Opengl, Ruby/SDL, Rails (for a web game), or even just a text game with plain Ruby. It's up to you.

Even if you can't dedicate the full weekend to writing a game (especially on short notice, if this is the first you heard about it), you could write a simple little game in an afternoon and evening, just for the fun and experience.

I hope you'll join us in writing a game with Ruby this weekend!

Rebirth & Rubygame, Together Forever

I've decided on the relationship between Rebirth and Rubygame. Or rather, the relationship came naturally, and it seems agreeable, so it's the direction I'm going to go.

In Rebirth 0.1, the View class wraps around Rubygame's Screen class with a different API. As you can see in the source, View just sets the screen mode, then stores the Screen as a class variable. (Right now it doesn't do anything with it, but it will for setting title, etc.)

This arrangement came out of simple laziness — I did the least amount of work to fulfill the specifications of the View class. And it works really well having Rebirth sitting on top of Rubygame. Rebirth can be pure Ruby, and take advantage of Rubygame's features — opening a screen, loading images, getting events, etc. Features that Rebirth doesn't need (Rects, Surface blitting, etc.) it can just ignore.

What this means is that Rubygame will continue to develop on its own, and Rebirth will be a new based on top of it. This is good for both libraries, in fact:

  1. It keeps my interest and motivation up, because I get to work on something new and fresh.
  2. It gives me an excuse to use and improve Rubygame as well, adding new features I need for Rebirth.
  3. It won't interfere with games that are just using Rubygame (no major backwards compatibility breaking).

So, that is the happy news!