Monthly Archives: July 2008

Is having a physics engine wired into the base of your game engine madness?  Clearly the opposite extreme, waiting until the game is well underway and then bolting a physics system on is pretty close to my definition of madness, but I’m not shure if the other extereme is equally un-sane.

My reasoning for wanting to do something like build on top of a physics library from the start is that you can unify many systems that might otherwise grow into less-than-optimally-compatible interfaces.  I’m thinking specifically of movement in a game world.  Normally we teleport our objects around at 30-60 fps giving the nice illusion of fluid movement.  Of course you occasionally jump over a solid object if you’re moving too fast so you then step back and start interpolating the movement and eventually end up with something fairly close to a physics library, at least in terms of determining collisions.  So why not just start with the physics lib from day 1 and build your collision detection, vectorized movement, etc. on top?  Then when you actually want physics based behavior there’s no need to figure out how to integrate some external library, everything is ready to go.

I liken this to something like metaprogramming in your language.  If you start off with Java and then decide later, “gee I really need to hook into every method in this one class and do some logging”, well, have fun getting to know Mr AspectJ.  If you’re in a language like Ruby, the metaprogramming is built in just waiting for when you need it.  The unfortunate side effect though is that you’re paying for the metaprogramming facilities even when you’re writing Java style OO, one reason Ruby is so much slower than Java.  So would sticking in a physics system make Gemini 100 times slower?  I don’t think so, especially since the facilities of a Physics library mesh so well with things we already need in a game engine, like the aforementioned collision detection.  Time will tell to what factor of incorrect my assumption is though (I’m usually off by more than 3x, *sigh*).

My current candidate for a fast physics lib is Chipmunk.  Written in C it should be pretty easy to hook up via JRuby’s FFI system (which wraps JNA and soon JFFI).  Thanks to Gemini’s awesome behavior system we’re fairly certain we can swap out Spatial for PhysicsSpatial and no higher level behaviors needs to know that the x, y, width, height are coming from a Chipmunk spatial struct vs local variables.  Of course the collision behavior would need to change to use the physics lib, but the nice thing is everything else is insulated.  You can could easily write higher level behaviors that depend on some sort of collision behavior, completely ignorant of weather they do their voodo via primitive shape intersection tests, complex physics based simulations or the divining of chicken entrails.  That last one is still a work in progress.

So, am I crazy to attempt such a thing?  Has this been done already?  Any war stories that you’d like to share?

500 bouncing balls

250 bouncing balls

Some of my previous posts regarding Gemini seemed to have garnered some attention thanks to someone posting one of them to DZone (thanks whoever that was).  So, since there’s no official home page with nice docs and tutorials and such I decided I would just keep a more public journal of the development progress of Gemini until those things are actually warranted.

So, to bring people up to speed on this Gemini thing.  It’s a JRuby game engine that sits on top of the Java based Slick library which itself uses OpenGL via LWJGL (that enough layers for ya?).

Gemini’s secret sauce is the idea that your game logic should not be in a big monolithic while loop.  Of course your game needs the basic game loop ingredients of checking for input, updating the game state and redrawing the scene but is a big while loop really the best place for all that?  So we started with the idea of game objects as the basic “thing” that exists in the world.  Game objects in reality are really just empty containers for you to attach behaviors to, without any behaviors they aren’t really much of a “thing”.  So, game objects via behaviors become the centerpoint of the game development effort.  To that end game objects support the idea of adding and removing behaviors and behaviors understand the idea of dependencies.  With that in place, you can create a game object that has a sprite, can move around and collide with other things and has callbacks for all its events in just a few lines.

class Ball < Gemini::GameObject
  has_behavior :UpdatesAtConsistantRate
  has_behavior :BoundingBoxCollidable
  has_behavior :Sprite
end

Now, this doesn’t tell the Ball object, what sprite to use, what to do on updates, what sorts of things to collide with, etc. Behaviors add methods to the game object they are attached to; methods that we can use in the load method to set up all our properties.

# the x= and y= methods are added by BoundingBoxCollidable which depends on
# Movable2D which depends on Spatial which provides the x= and y= (phew!)
def load
  collides_with_tags :wall
  preferred_collision_check BoundingBoxCollidable::TAGS
  self.image = "ball.png"
  self.updates_per_second = 30
  self.x = rand(640 - width)
  self.y = rand(480 - height)
  @vector = [rand(5) - 3, rand(5) - 3]
end

Those self.= calls are there to force the method to be invoked instead of creating and assigning to a local variable. So with that done, the only pieces left to get a bunch of balls bouncing around on the screen is to say what happens on each updated (the tick method gets called by the UpdatesAtConsistantRate behavior) and to say what happens when the ball runs into a wall (defined by anything with a :wall tag).

# The on_ callback system is instance level and thus would be added to the load method
on_collided do |event, continue|
  vector[0] = -1 if x > (640 - width)
  vector[0] = 1 if x < 0
  vector[1] = -1 if y > (480 - height)
  vector[1] = 1 if y < 0
end

# The move method was added by BoundingBoxCollidable which depends on Movable2D
def tick
  move(x + @vector[0], y + @vector[1])
end

So, plenty of hard coded stuff that we plan to swap out for a relational positioning system (0 = left side of screen, 1 = right side of screen) and the collision handler could probably be a bit prettier but it’s a start.

So where is Gemini today?  Well, certainly not in a position to make an actual game with.  There’s infrastructure for our concepts of behaviors and game objects, there’s an internal message queue which allows game objects to communicate asynchronously and in a totally decoupled manner (it’s also going to be used for stuff like input handling). The next two components to start hacking on are the input system and a basic GUI system which my associate Logan Barnett will be heading up.  Beyond that there are lots of places to hit up for performance improvements including but no limited to moving various parts over into Java based libs.  Certainly something computationally heavy like a physics engine would be a great candidate for Java, and thankfully there are several to choose from (plus all the C based ones that have simply been wrapped in Java).  So the future is bright, we can already move a good number of sprites around doing collision detection with zero optimizations and the behavior based system appears to have long legs in terms of allowing us to implement everything from keyboard input to playing sounds to moving as part of a cutscene as part of a behavior.

Wouldn’t it be nice to live in a world where you can wake up one day and have some project of yours just magically run 50% faster? Well my friends, JRuby is a world of mystery and amazement. In the past few days the JRuby team has been working feverishly on their Java integration rewrite. Along the way Charles Nutter managed to clean up the number of layers a Ruby call had to go through to get to Java. The net result: my test case for Gemini that I posted about earlier when from a frame rate of 27 fps to 40 fps. None of my actual code changed, I just swapped out the jruby.jar for a newer build. Swapping them back takes me back down to the 27 fps range. So, mana does fall from heaven occasionally, at least in JRuby land.

Joss Whedon is my master. Yes it’s true, I’m just a sucker for anything that man produces. So I was delighted to view last night the first episode of a 3 part series by Joss named “Dr Horrible’s Sing-Along Blog”. For anyone who’s every seen the musical episode of Buffy “Once more, with feeling” you’ll feel right at home here. The next episode comes out tomorrow and the third on Saturday. But get it while it’s hot because on Sunday they convert over to paid content either through iTunes Music Store or eventually a DVD version (which I will of course buy immediately). So, if you have ever enjoyed Buffy, Angel or Firefly then you’ll heartily enjoy Joss’ unique brand of comedic drama in Dr Horrible’s Sing-Along Blog.

I’ve been working with JRuby to build high level systems on top of powerful Java libraries for about 2 years now.  My most successful endeavor has been Monkeybars, a libarary for making Swing a lot easier to use.  My other project has been in the game development arena.  The project name is Gemini, and although it’s not nearly as advanced as Monkeybars, I was able to get to a significant point over the weekend.  Yes, here in all its glory, the simple “crapton of sprites bouncing back and forth demo”.

1000 dukes bouncing back and forth on screen

Now you’re probably saying, big deal, I can do that in like 40 lines of code in <insert favorite programming language/framework> and no doubt you would be correct.  What’s interesting about the way Gemini does things is in how it gives you an extremely flexible way of compositing together your game objects and your application as a whole.

The code to get this going using Gemini is pretty straightforward.  We have a game state that is loaded by Gemini when it starts up.  That game state then instantiates 1000 of our game objects and they proceed to load their images and care for their own logic of bouncing around on the screen.

Here’s the code in main.rb that kicks off the app:

require 'gemini'
Gemini::Main.new("Test game", 640, 480)

And here is the state that is loaded by default when Gemini runs: main_state.rb

class MainState < Gemini::BaseState
  def load
    @sprites = []
    1000.times {@sprites << Duke.new}
  end

  def update(delta)
    @sprites.each { |sprite| sprite.update(delta) }
  end

  def render(graphics)
    @sprites.each { |sprite| sprite.draw }
  end
end

Finally we have the Duke class that was instantiated in the MainGame class:

class Duke < Gemini::GameObject
  has_behavior :Movable2D
  has_behavior :Sprite
  has_behavior :UpdatesAtConsistantRate

  def load
    self.image = "duke.png"
    self.updates_per_second = 30
    @direction = :right
    self.x = rand(640 - image.width)
    self.y = rand(480 - image.height)
  end

  def tick
    if x > (640 - image.width) || x < 0
      @direction = @direction == :right ? :left : :right
    end
    self.x = x + (@direction == :right ? 1 : -1)
  end
end

Apart from some hackish ternary ifs in the Duke class I think the whole thing is pretty darn readable, especially considering all that it is doing. As you can see, everything is extremely declarative including those has_behavior calls in the Duke class. Those nifty bits of metaprogramming bring in all the crunchy goodness of the class and make the x, y, image and updates_per_second methods appear. Movable2D gives us a move method and also pulls in the Positional2D behavior that provides the x and y methods. UpdatesAtConsistantRate gives us an update method that calls tick at the rate specified by updates_per_second. Finally the Sprite behavior gives us the image method and the draw method that gets called in the MainGame class.

Most of this is bare bones at the moment. What if you don’t have the UpdatesAtConsistantRate? When update is called you asplode. Same for Sprite / render. So clearly a more flexible game state is needed, probably involving the game object behaviors auto-registering themselves with the game state to be called during an update/render cycle. But as a whole I’m quite happy with the way Gemini is starting to shape up. Next on the agenda is getting keyboard mapping hooked into the RecievesKeyboardEvents behavior so you can control duke, then we’ll have what could pass for a real game.

I wanted to get a sense of my test to code ratio today for one of my projects and knew that the *nix command wc would give me a count of all the lines in some files, but the man page didn’t seem to have any information about filtering those lines.  Thankfully this is *nix land where we are encouraged to slice and dice our own solutions.  So, grep to the rescue.

My initial attempt was to filter out empty lines and lines that had some number of spaces followed by # (the comment character in Ruby), but I failed to find a combination that would work so I settled on a two pass grep solution.

grep -v '^[ t]*#' ./lib/**/*.rb | grep '[^ t]' | wc -l

The -v option for grep says to match lines that do not match this pattern.  So the first grep pattern matches a line that does not have zero or more spaces followed by the # character.  The ./lib/**/*.rb is the “file” to check.  Now a lot of *nix utilites can take what’s known as a dir glob, a pattern that describes a list of files.  In this case I want every file and subdirectory in the lib directory that ends in .rb.  The second pattern does somewhat the same thing but simply matches a line that does not consist entirely of spaces and tabs.  Finally the wc -l gives a count of just line numbers (vs words like it normally reports).

So now I can get a count of non whitespace, non-comment lines in my app (the lib directory): 1615

Then the number of lines in my spec directory: 1561

Hmm, not so hot, guess it’s time to get back to spec writing.