So I have been pretty active in using Ruby for the past several years. I have found it a great resource for writing less code and producing more results. So why not use it for game development. Build some DSLs or better syntax for writing game logic code. So in this post I am going to run through a couple of ways to accomplish writing a game in ruby by using java for graphics and additional functionality.
So first we start off by needing to package everything up nicely in a single jar file so it appears as though we're just using java. Unfortunately this comes with a bit of a space cost. And that space is that of jruby the complete jar is ~20mb you can find them at
http://jruby.org/downloads so no way to avoid this although you can do something like write an install script that downloads it and then puts your source into it afterwards.
Ok once you have the jar file you will add your code to it and it will become your executable from java.
Make a copy of the complete jar.
$ cp jruby-complete-9.0.5.0.jar mygame.jar
Create a file that jruby will launch called
jar-bootstrap.rb
#!/usr/bin/env ruby
puts "Hello, I am jar-bootstrap.rb from inside the jar file"
Update the jar (
-u) by first modifying the manifest to run a specific java class using option
-e to override the Main-Class entry in the manifest already inside the jar.
$ jar ufe mygame.jar org.jruby.JarBootstrapMain
Then you can use the
-u option to add files to the jar file or update existing ones.
$ jar uf mygame.jar jar-bootstrap.rb
Then viola:
$ java -jar mygame.jar
Hello, I am jar-bootstrap.rb from inside the jar file.
Ok we've entered the ruby~java land woot woot.
Now for lets rubify java to do our game-logics bidding!!!
Lets switch the jar-bootstrap.rb to load our game which we will start in a game.rb file:
jar-boostrap.rb becomes
#!/usr/bin/env ruby
require './game.rb'
Then we make our game.rb file with a simple example of loading a java swing window and rendering loop
game.rb is
#!/usr/bin/env ruby
include Java
import javax.swing.JFrame
import javax.swing.JPanel
import java.awt.BorderLayout
import java.awt.Dimension
class MyDrawPane < JPanel
def initialize
super
setDoubleBuffered true
setPreferredSize Dimension.new(800,600)
end
def paintComponent(g)
g = g.create
g.drawString 'Hello from ruby', 0, self.height / 2
g.dispose
end
end
class MyGame < JFrame
def initialize
super "My Game Window Title"
self.setLayout BorderLayout.new
self.add ::MyDrawPane.new
self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
self.pack
self.setLocationRelativeTo nil
self.setVisible true
end
end
MyGame.new
And with all this we have a simple window to start from but now we can use the power of ruby to rule the world. Uh I mean we'll use the power of ruby to make games...
...to rule the world...
So this is all great but maybe we want easier iterations with our game development because updating the jar all the time isn't that fast. So for development just execute your game.rb file from jruby directly. You can use the original one you downloaded.
$ java -jar ../jruby-complete-9.0.5.0.jar game.rb
Or if you use rvm or rbenv then just execute the game script. And Q.E.D.