Thursday, August 28, 2008

prototyping with Ruby and Gosu



Now that summer is over and classes are starting again (except now I'm in graduate school) I've decided to become productive again. Go figure.

I'm using Ruby with Gosu to quickly develop prototypes to test out gameplay mechanics.  The first image above is a simple catch game using my boxman character I used in a TGEA game.  Nothing special, just some sprite animation and makeshift rectangle intersection stuff really.  I recently finished developing a cellular automata engine for the Ruby programming language.  You can find the project on GitHub here (I'm still more of an SVN kind of guy, but we'll see how this turns out).  I made this for two reasons: for one I haven't written a C.A. engine before, and two I needed something to test complex rules with for our game idea.  

The game itself is fairly interesting itself in terms of design.  Basically you build a "virus" out of cellular patterns to compete in some pairing with another player to see who's pattern spreads the fastest.  If we go with the iPhone or some other mobile device as the platform for this, then we can bring in another level of viral spread.  Battles can occur in some peer to peer fashion based on locality.  I.E. you can battle people at whatever public area you hang out in.  If we add a server to this mix, then we can track different data on people's virii such as wins, longevity (duration of winning record), spread (real-life spatial), whatever and display this in some form.  

In developing this library with Ruby, I ended up learning a few things along the way.  Mostly getting to know the inner workings of Ruby itself, such as how 

Array.new(N, Array.new(K) {|i| i})

only evaluates the inner block once.  Since I took a course last semester that dealt with functional programming, I can now make use of really cool language tools like lambda functions.  It just so happens that Ruby's functional features are quite robust. 

For my graduate research I am developing a simulation to mimic human behavior in an environment with several different types of sensor networks.  This is to help with an eldercare project meant to bring computational intelligense into automated systems that can detect urgent needs or various lifestyle needs of people living in eldercare facilities.  

By providing formal input describing daily behavior, my system will be able to simulate days, months, or even years worth of data collection by the sensor networks used by the eldercare system.  By doing this, other research that attempts to understand that data can use the input for supervised learning.  

At any rate, so far it has allowed me to start using JSON/YAML parsers such as TinyJSON and Ruby's built in YAML parser.  TinyJSON is interesting since it makes use of Boost's Spirit library to provide a lightweight but powerful JSON parser.  Unfortunately there is a slight lack of documentation for the parser, but with a little elbow grease it's not hard to figure out.


level = boost::any_cast<>::object >::object >(*v);
m_iUnits = boost::any_cast<>(*level["unitpixel"]);

Turns out that the json::grammar::object is a std::map which works perfect for JSON data.  v above is a variant type that is used to hold the entire JSON object, which you can see on the given documentation.  The real trick is pulling data out of array types.  Luckily there are iterators provided and you can cast them similarly as the variant type if you're like me and create arrays of objects often.  

Figuring this out was interesting for me since I haven't had a chance to really dive deep into template programming in C++, so debugging my code was a real treat with that incessant type syntax.