Sep 26, 2011

Crafty: Gaming Engine for Javascript

I started fiddling with this Javascript gaming library called Crafty, which allows you to build simple video games using DOM or canvas elements. Up front I like it better than gameQuery since it allows you to use canvas, but also because it seems to be much more of a framework rather than just a collection of jQuery extensions for gaming.

The most interesting thing about the library though is the use of components, which are essentially an implementation of Ruby's mixins in Javascript. A large number of built-in components support fancy things sprites, physics and input-related components that make an entity (such as a player) automatically respond to the arrow keys on the keyboard.

You can even define your own components. For example, you could define a component called FollowsMouse which means the sprite will follow the mouse cursor.

The main issue so far is that the documentation is sparse and the examples are not at all up-to-date. When you create an entity, you do it like this:

obj = Crafty.e("list", "of", "included", "components");

However it turns out that the capitalization style of components has changed:

// examples say to do this:
obj = Crafty.e("2D", "canvas");
// when in fact you do this:
obj = Crafty.e("2D", "Canvas");

These types of problems are very difficult to track down, since there is no failure notice when a required component doesn't exist. Instead, the system just ignores it and your entities don't render. I typically follow the adage, "the bug is not in the library, despite how much it seems like it" and yet, sometimes the bug is actually in the library (or in this case, the documentation).

There is probably a few other hiccups, maybe I'll make a few tweaks to the library and send it over in hopes they'll merge a patch in.

Sep 12, 2011

Ruby's instance_eval and Structured Configuration Files

Recently at work I was setting up a section of the program involving a user-configurable GUI element. Initially I thought about using something like XML to handle this, however if I went that route I'd have to manage parsing the XML through some library, traversing the XML tree, and create some sort of GUI element based on what type of node it was, what the attributes were, etc.

On top of that it was highly likely that the requirements for this GUI system would change and the level of sophistication behind the GUI system would increase - buttons would need to do more complicated tasks that could potentially be arbitrary. Having a hard-coded system in C# would not be feasible since tweaking logic would require a re-compile and an application restart.

I decided that since the system already had an IronRuby install built in, perhaps I could do this configuration file in Ruby as well. Given an XML configuration file that looks like this:
<group name="Buttons">
<line>
<button text="Cool Script">
<something_crazy_and_awesome />
</button>
</line>
</group>
I could translate this to Ruby that looks like this:

group "Buttons" do
line do
button "Cool Script" do
something_crazy_and_awesome
end
end
end


On top of that in order to use this configuration file in a program I don't actually need to parse the file, I can just execute it within the context of different objects. For the dialog box that allows the user to set up the configuration I can just execute the Ruby code within that dialog box object and it will automatically create the elements that allow the user to change the configuration. Then in the part of the application where the user actually uses the configuration, I can just execute the file again but with a different definition of group, line, etc. that construct the proper GUI elements.

This is not just applicable to GUI elements, you can use this for anything that uses some sort of structured configuration. Rake uses this to great effect with tasks. But how would you go about implementing this pattern?

Turns out it's really simple using instance_eval. Here's an example that constructs the GUI element (this is in
IronRuby so it uses .NET for GUI construction):
class GroupBuilder
def initialize parent, name, &block
@group_box = GroupBox.new(name)
parent.Controls.Add(@group_box)
instance_eval &block
end

def line &block
LineBuilder.new(@group_box, &block)
end
end

class LineBuilder
attr_accessor :panel

def initialize parent, &block
# in the GUI environment we use a panel for adding things
@panel = Panel.new
parent.Controls.Add @panel

instance_eval &block
end

def button text, &block
ButtonBuilder.new(@panel, text, &block)
end

# ... anything else that can be placed in a line ...
end

class ButtonBuilder
def initialize parent, text, &block
# create a button
btn = Button.new(text)
# bind the click event of the button to execute the
# Ruby code within the block
btn.Click { self.instance_eval &block }
parent.Controls.Add btn
end

def something_crazy_and_awesome
# do something crazy and awesome
end
end

class ScriptProcessor
def initialize control, script
@control = control
instance_eval File.read(script)
end

def group name, &block
GroupBuilder.new(@control, name, &block)
end
end
To do all this stuff, you can just create a ScriptProcessor object, pass in a .NET control and a script filename:

f = Form.new
ScriptProcessor.new(f, "my_config_file.rb")
f.Show


For each type of nested element you can create a class which define a method for the various types of sub-elements that you are allowed to have. Each of those methods will then handle the processing that needs to happen when the system sees an element of that type.

I think you could probably do this without classes and just use lambdas, but I think the code is clearer when you have objects since it is very explicit as to what each object is for.

Doing this with C# is a bit trickier since C# doesn't have instance_eval, but it turns out you can have a bit of a hack in order to get it to work quite well. I'll write up a quick post about this at a later date.