Vote for your Favorite RubyWeekend #3 Entries
(June 29, 2009 @ 11:02 PM)
The entries for RubyWeekend #3 are in, and it’s time to vote!
The entries are (in order submitted):
- Ant Frenzy by Garepjotr
- A Tiny World by ippa
- Mite Makes Right by LoganBarnett
- Droplet by jacius
- Free Radicals by shawn42
You can download the entries from the forums, play them, then head to the voting thread and cast your votes!
RubyWeekend #3 Starts Now: "A Tiny World"
(June 25, 2009 @ 07:00 PM)
The theme for the RubyWeekend #3 game contest has been announced: A Tiny World!
If you’re participating, you have until June 28, 23:59 UTC (72 hours from now) to create a game in Ruby that matches the theme. Then, package it and upload it to the RubyWeekend #3 forums.
We recommend taking some time to think about the theme before you start coding. Come up with a good idea for a small game that you can create in just one weekend. It’s good to keep a brief log along the way, since it’s interesting for others to read about, and it can also help you focus your ideas! Twitter is great for quick log entries; we recommend tagging your tweets with #RubyWeekend. Or if you have a blog, post the URL in the forums.
We’re also hanging out in IRC during the contest: #rubygame on freenode. Come join us if you want to chat with other participants! (But don’t let IRC eat all your time!)
RubyWeekend #3 Game Contest: June 26-28
(June 24, 2009 @ 04:46 AM)
After being on hiatus for nearly a year, the RubyWeekend game creation contest returns this weekend, June 26-28!
The contest period runs for 72 hours this time, to allow everyone around the world plenty of time to create a small game:
- Start: June 26, 00:01 UTC
- Stop: June 28, 23:59 UTC
Watch the RubyWeekend #3 forum in the next few days for rules and more details.
RubyWeekend is a friendly weekend competition in the spirit of Ludum Dare and PyWeek. The idea is to create a small original game in a single weekend, programmed in Ruby. The theme of the contest is announced at the start of the contest period, and participants create a game that fits the theme, within the time limit (2 or 3 days). The short time period encourages participants to think small and use their time wisely.
All game code should be written in Ruby, but you can use any Ruby libraries or extensions you wish — Rubygame, Gosu, Shoes, Gamebox, Gemini, Ruby-OpenGL, etc. You could even make a web-based game with any of the many web libraries and frameworks available for Ruby: Rails, Merb, Ramaze, Sinatra, etc. Ruby has a wide (and growing!) variety of options for game programming, so let’s show them off!
Remember to watch the RubyWeekend #3 forum in the next few days for rules and more details.
Rubygame 2.5.2 Released
(May 16, 2009 @ 08:34 PM)
Rubygame 2.5.2 fixes a single, somewhat major bug:
- Fixed: HasEventHandler#handle (and other methods) dealt with NoMethodError exceptions in a stupid way.
Thanks to Kiba for reporting this bug.
Full docs are online at docs.rubygame.org. Source tarball and gem are available for download at Rubyforge and download.rubygame.org, or you can install with gem install rubygame.
Enjoy!
Rubygame 2.5.1 Released
(May 12, 2009 @ 09:18 PM)
I’ve just released Rubygame 2.5.1. This version fixes two bugs, one potentially serious, and one minor.
- Fixed:
Clock.delaywould delay forever if the delay time and granularity were very small. - Fixed:
Clock.delaywould always be “nice” to other Ruby threads during the final part of the delay, even ifnice = false.
Thanks to shawn42 (Shawn Anderson) for discovering and telling me about the first bug.
Full docs are online at docs.rubygame.org. Source tarball and gem are available for download at Rubyforge and download.rubygame.org, or you can install with gem install rubygame.
Enjoy!
Ah, Vacation!
(May 05, 2009 @ 11:02 PM)
Ah, I finally get to kick back and relax: it’s vacation time! I’m avoiding real work as much as possible for the next 2 weeks to a month, and just slacking off and tending to fun things.
Now that Rubygame 2.5.0 is out, the next order of business is to clean up the web sites! Rubygame has moved a few times in its 4+ year history, and has left a bit of a slime trail as it went. (Note: many of the following links will become redirects within a few days of posting this.) Rubygame was first hosted on SEUL.org, then added an Infogami wiki to augment the static site. Then it moved to Sourceforge, and then added a wiki on SF. Then I added this blog to augment the SF site, and then mostly abandoned SF, hosting the source on Github, releases on RubyForge, and docs here at rubygame.org. Phew!
Now I’m getting around to making this an actual coherent site, instead of just a blog, forums, and other random things scattered around. I’m also cleaning up as many of the old sites as I can. I accidently permanently borked the Infogami site a couple days ago by deleting the site template (oops), so now it’s just… nothing. The SEUL and SF sites will become transparent redirects to the new site, which will start off as an updated version of the current SF site (since I’m still happy with my work on that).
After that’s taken care of, I’m going to try to convert this blog and the one over at blog.jacius.info to WordPress, since Mephisto is kinda clunky, plus I’m kinda tired of having to restart Mongrel when something goes wrong on the server. Finally, I’ll probably set up MediaWiki to have a modern, community-editable Rubygame wiki. (Yes, the blog, wiki, and forums for Rubygame will all be running on PHP, and no, I don’t see any irony there. Call me when there’s a Ruby-based blog, wiki, or forum app in the same league as the PHP ones.)
I should also come up with a Rubygame logo. I’ve got a new concept in mind (my motivation for finishing up this one is getting stale), so I’ll be experimenting with that on the side.
This next one is a bit of a stretch, since there are other things I’d like to do, too, but I’d also like to take another stab at the API Documentation app I tried to write last year. I detest having to work with (or against, as it were) RDoc for the Rubygame documentation. Every Rubygame release involves me fiddling for hours trying to get RDoc to format output the way I want, and the final result is mediocre, even when it’s working perfectly.
So, I was thinking of writing a web app to manage documentation. But I made the mistake of trying to do it in Rails (hah, hah, silly me), so the project crashed into a smoking heap of garbage and nils-where-I-didn’t-expect-them. (I guess that’s what happens when you try to ride Rails to someplace it doesn’t feel like going.)
I had been thinking about retrying it with Merb, to see if that was any better, until I heard it would be merging with Rails in the future. I might try Ramaze instead. Or heck, even Sinatra would be better than Rails. A bit more code to write, maybe, but fewer headaches and stomach ulcers. (If I wanted headaches and ulcers during my vacation, I’d go back to work early.)
But, I’m not sure I’ll take on that project yet. After all, I could use the time I’d spend on that, to work on Rubygame 3.0, Rebirth, a game, or some other fun thing!
We’ll see.
Oh, I forgot to mention the most important thing to do during my vacation: have lots and lots of afternoon naps in the sunshine with a cat on my lap.
Rubygame 2.5.0 released
(April 27, 2009 @ 07:41 PM)
Rubygame 2.5.0 is now ready to go!
The main focus of this release is improving the Clock class. Clock now has a more responsive and accurate algorithm for measuring framerate, better support for multithreaded games (set Clock#nice = true), a new ClockTicked event class (for use with EventHandler), and a way to calibrate the Clock to minimize wasted CPU power.
I’ve also written an in-depth tutorial about using Clock, entitled Managing Framerate. It covers several aspects of using Clock, including:
- framerate monitoring (finding out how fast your game is running)
- framerate limiting (setting the maximum framerate, to avoid wasting CPU power)
- calibrating Clock (to reduce CPU usage even more)
- framerate independence (so characters don’t move slower if the framerate drops)
In addition to the Clock improvements, I’ve also added the Screen.get_resolution method to retrieve the user’s desktop resolution (useful for automatically deciding how large to make the Screen). Thanks to Stephen Paul Weber (singpolyma) for the suggestion and for the initial patch!
There are also a few other smaller changes, so you may want to have a look at the NEWS for the full release notes.
Full docs are online at docs.rubygame.org. Source tarball and gem are available for download at Rubyforge and download.rubygame.org, or you can install with gem install rubygame.
Enjoy!
Rubygame 2.5 Tomorrow
(April 27, 2009 @ 02:44 AM)
I ended up having to do some not-so-minor changes to Clock today (to satisfy my OCD rigorous Quality Assurance procedures), so I didn’t quite have enough time to prep the Rubygame 2.5 release tonight. The code is done (pending further review in the morning), it’s just a matter of packaging it up and posting to various sites and mailing lists. I’ll take care of that in the morning.
Rubygame News (2.5 & 3.0)
(April 24, 2009 @ 04:36 AM)
Alright, in typically me-ish fashion, ”coming soon” has turned out to be over a month. A rushed and stressful work project that was supposed to last 4 weeks, has dragged on for 8 due to technical troubles, but it’s finally coming to a close, and I’m taking a much-needed vacation from that, and tending to other things that I have neglected in that time. That means:
- Rubygame 2.5 this weekend. The code is finished, but I’m still finishing up the Clock tutorial.
- Tending to the web site and forums, fixing and cleaning stuff up, and adding more information. Possibly adding a wiki?
- Writing more tutorials.
- Possibly finishing the Rubygame mascot.
- Releasing a few new micro-versions of Rebirth.
- Planning and working on Rubygame 3.0.
Rubygame 3.0? Whuzzah huh?
I’ve been feeling inspired to hammer out Rubygame 3.0, which would be the first break in backwards compatibility in almost exactly 2 years. This will involve cleaning out a lot of cruft and warts that have been revealed over the years.
It will also, most likely, involve finally ditching SDL_gfx for SPriG. I recently stumbled upon SPriG, which seems to be an updated and trimmed down fork of SGE. Overall, it looks like a much nicer library, containing a great many useful features that SDL_gfx has been missing, and I’m looking forward to testing it out.
Assuming it works out alright, you can expect some sweeping improvements to the Rubygame drawing system.
Poll: What Rubygame Tutorials Should I Write?
(March 21, 2009 @ 08:40 PM)
I’m considering about writing some guides/tutorials about specific aspects or features of Rubygame, to help people understand how best to use them.
To help me get an idea of what topics I should write about, I’d like to know which topics you’d most like a guide for. In other words, which topics would you benefit most from, either clearing up confusion or improving your skills?
Vote in the forums, or leave a comment here!
Rubygame 2.5 Coming Soon
(March 21, 2009 @ 07:51 AM)
The improved Clock code is more or less done now (it’s currently in my next branch on Github, if you’re curious). The changes so far:
Clock.waitandClock.delaywork better in multithreaded apps (when given a yield value).- Added
Clock#granularityandClock#yieldattributes to tweak the delay used inClock#tick. - Added
Clock#calibrate_granularity(whee, long English method names) to calculate a good granularity for the current system. This reduces unnecessary CPU usage a lot on systems with accurate timers, especially Linux and Mac. - The framerate monitoring code for
Clock#framerateis much improved, giving more accurate and responsive results. - Added the
ClockTickedevent class. UseClock#enable_tick_eventsto makeClock#tickreturn events instead of raw millisecond times. ClockTicked has methods for getting the tick time as milliseconds or seconds. - Added a new TickTrigger event trigger class. You can use it in your event hooks to detect ClockTicked events.
- You can use the symbol
:tickas a trigger inHasEventHandler#make_magic_hooksto easily create a TickTrigger.
One further improvement I’m considering is caching ClockTicked events in Clock#tick. So, basically, Clock would keep a hash of ClockTicked events for each distinct value (integer milliseconds) and just return references to the existing one instead of creating a new one. That should help keep Ruby’s garbage collector happy.
I should probably create some specs/regression tests for Clock, too.
I also need to look at other changes to possibly include in 2.5:
- shawn42 created a cool method for drawing thick lines that might be worth including, possibly ported to C.
- singpolyma made a function to get the resolution of the user’s display, but due to the sillyness of the underlying SDL function, it only works the way we want it to if there’s not a Screen open. I’m not sure how I’ll manage to impose consistency on it. Maybe have it return nil or raise an error when there’s an open Screen?
- I’ve had a couple event hook/handler improvements floating around in my head, like named hooks and
make_magic_hooks_for(which works likemake_magic_hooks, but with a hook owner other than self). - I might write a brief guide to using Clock most effectively.
Anyway, I have some free time this weekend, so Rubygame 2.5 should be out Saturday or Sunday evening.
Tick Tock, A Better Clock
(March 15, 2009 @ 09:38 PM)
Things have been ominously quiet here on the blog the past two weeks! I’ve been busy with work lately (shocking, I know), but I set aside some time the past few evenings to work on Rubygame.
Yes, working on Rubygame. And if that isn’t enough to shock you, what if I told you there’d be a release coming in the next few weeks, featuring some nice improvements to the Clock class?
It started out as Rebirth work, actually. I had been working on a new clock class, with numerous improvements: less stupid framerate calculation, compatibility with multithreaded ruby apps, and returning ClockTicked events when you called #tick, instead of raw milliseconds. Most of this was actually done months and months ago, as part of the “long lost Rubygame 3.0”. Just as I dug up EventHandler and polished it up, I’ve been doing the same with the improved Clock.
Since I wanted the new Clock to be safe for multithreaded ruby apps, I couldn’t just use the SDL_Delay C function any more, since that stops all ruby threads, not just the current. (This was pointed out to me a long long time ago, actually.) So instead of SDL_Delay, I figured I’d use Ruby’s sleep method. Although it only returns integers, sleep will accept and function properly for floating point numbers, even small ones like 0.1. In those cases, sleep will return 0, which isn’t very useful, but you can get the actual time difference quite simply:
1 2 3 4 5 |
def float_sleep( t ) start = Time.now sleep t return Time.now - start end |
And in fact, this method can be quite accurate on certain systems, like mine:
1 2 |
>> float_sleep( 0.01 ) => 0.010077 |
Not bad, eh? Unfortunately, that accuracy is not universal; it varies with CPU and operating system. Values on some systems can be several milliseconds off. For example, sleeping for 0.01s might actually sleep for 0.013, or 0.016, or even 0.02.
Being a few milliseconds off probably wouldn’t be a problem for certain types of apps, but in a game the delays themselves are measured in milliseconds, and happen many times per second, every second. (An inaccuracy of 4ms per frame can mean the difference between 60 frames per second and 50.) Even worse, it’s not a constant amount that you can compensate for, it’s different each time you sleep, and that means the game framerate would be fluctuating all the time.
SDL_Delay has the same problem, actually, which is why Clock.delay uses a brief spinlock (empty loop constantly checking the time) at the end to get more accuracy. But, trying the same approach in ruby code actually makes the accuracy worse, perhaps due to some overhead with loops, or time checking, or both.
So, ruby sleep was not an option, but I still wanted to find a way to make Clock.delay work with multithreaded apps. Fortunately, Julian Raschke, author of the excellent Gosu game library, suggested an approach: use a loop to break up the SDL_Delay into smaller pieces, and call rb_thread_schedule between each chunk to let ruby keep running the other threads.
Hats off to Julian, because it has worked like a charm! Starting in Rubygame 2.5, Clock.wait and Clock.delay will take an additional optional argument to specify the number of milliseconds between each call to rb_thread_schedule (so smaller values run the other threads more often). It can also be false, the default value, to make them behave as they do in 2.4 and earlier (pausing all threads).
There will also be some other improvements to Clock:
- A better algorithm for calculating framerate. (The current way is very stupid.)
- More options for balancing CPU usage and accuracy, including the option to use Clock.wait instead of Clock.delay for framerate limiting, and an automatic calibration method to find the ideal granularity for the current system.
- An option to have
#tickreturn a ClockTicked event instance, which will have methods for retrieving the tick time as either milliseconds or seconds. There will also be a new event trigger, TickTrigger, to go along with the ClockTicked event.
As mentioned, the new version should be released within the next few weeks, and will be backwards-compatible with previous versions.
Rebirth 0.6
(February 26, 2009 @ 02:01 AM)
I finished Rebirth 0.6 tonight. This version adds the GameObject class, which is the base class for objects in the game and on the screen, such as characters, items, missiles, and so on.
In addition to adding the new class, I also did some more refactoring, and made a new mixin module, Drawable, which handles the OpenGL transformation voodoo for GameObject and Shape.
The demo for this version looks the same as before in a screenshot, but you can now control the box with the numeric keypad! The keypad’s arrow keys (2, 4, 6, and 8) move the box (down, left, right, and up, respectively). Keypad 7 and 9 rotate the box counterclockwise and clockwise. Keypad + (plus) and - (minus) make the box larger or smaller.
It’s not the most impressive demo in the world, but it’s nice to be far enough along that I can control objects on the screen. At this point, it would be possible to recreate Pong with Rebirth. How exciting! ;-D
Regarding the depth issue I blogged about last time, I decided to go with the lazy way. Not because it’s lazy, but because it’s consistent with software like Inkscape / SVG and Flash. After thinking about it, I realized that I’ve been half-subconsciously modelling the graphics system of Rebirth after SVG. Rebirth’s GameObjects correspond to SVG’s groups, and Shapes correspond to the various SVG shapes.
Inkscape and SVG have also influenced my plans for shape styles. Shapes will have “fill” and “outline” styles, which can (eventually) be solid colors, images/textures, and perhaps gradients (depending on how confident I’m feeling about my OpenGL skills). You’ll be able to control how thick the outlines are, of course, and maybe line stippling (dotted/dashed lines).
I do have two small concerns about Chipmunk integration. The first is that Chipmunk has support for circles, but not for ellipses (ovals). Since Shapes and GameObjects can be squished and squashed and sheared, I’ll need to be able to approximate all shapes as polygons, with the transformations applied (glUnproject might help with that). The second is that Chipmunk doesn’t support hierarchical objects, so I’ll need to figure out how I’m going to handle that. Perhaps just make so that all shapes and children of a physics-enabled GameObject form one body.
Anyway. The next version is supposed to be adding the Circle class, but I might do some rearranging and update the plans, since I’ve noticed Rebirth is missing a central class to hold the game together as a cohesive unit. Long ago, I called that class Game, and it held a clock, event manager, camera, and world filled with sprites. I’ll probably come up with a different class name (to avoid confusion with the GameObject class), but the general idea is the same.
Deep Thinking about Shapes
(February 24, 2009 @ 02:22 AM)
I’ve been getting into the real meat of the GameObject class today: drawing shapes and children. Unfortunately, I’ve run into a little tangle that I need to sort out before I go much further.
A brief explanation GameObject first. GameObject is analogous to Rubygame’s Sprite class, in that it’s meant to be the base class for space ships, dragons, penguins, and whatever else you can see on the screen. But it has some important differences.
A GameObject itself is not visible, but rather holds Shapes, which are visible and have colors, styles, textures, etc. Shapes are boxes, circles, lines, 2D polygon meshes, and maybe some other things of that nature. In addition to appearance, shapes will be the base for collision and physics, once I integrate Chipmunk.
Also, GameObject is hierarchical, i.e. each object can have child objects (and those can have children, and so on). The children inherit the parent’s transformation, and can add their own local transformation. So if the parent is at position <-3, 0> (global space) and the child is at <-1,0> (local space), the child will appear to the user to be at <-4, 0>, because its position is relative to the parent. So, you can make a character out of multiple objects (maybe one for the head, one for the body, and so on), or make a katamari ball that other objects stick to and rotate with, or whatever else you want. Thanks to OpenGL, it’s all extremely simple to program.
But, as I said, there’s a snag. Shapes all have depths, to decide which shape appears in front of the other. If shape A has a depth of 50, and shape B has a depth of 25, B is closer, so it should be in front. But I hadn’t thought about how shapes in separate GameObjects relate to each other. Do GameObjects have depths? If they do, and object O is in front of object P, but O’s shapes are deeper than P’s shapes, which shapes draw in front of each other? Or what if O and P have multiple shapes, with their depths alternating like two stacks of cards shuffled together?
There are two ways I could go. The lazy way is to just say that Shape’s depths only apply within the GameObject, so all shapes of the nearer object will appear on top of all shapes of the deeper object. In this case, it’s very simple to do: just render each object in the scene by descending depth, and within each object render its shapes also in descending depth. It’d just be a matter of sorting, really.
The less-lazy way is to say that GameObjects don’t have depths, and only the Shapes’ depths matter. But in this case, I have to maintain a list of all shapes in the scene, regardless of which object they belong to, sorted by depth, and then draw those in order by descending depth. (For those of you familiar with graphics rendering and wondering why I don’t just use the depth buffer: I can’t. Shapes can have partially transparent textures, and those wouldn’t render correctly if I relied on the depth buffer.)
The first, lazy way has a disadvantage, which is the snag that caught my attention and started this train of thought: how is an object sorted relative to its children? Do the children go in front? Or behind? Well, really, you’d want to choose on a case-by-case basis, but then I have to think about a relative depth system. (Hrm, actually, it wouldn’t be too hard – parent depth is 0, children can have negative depths to be in front, positive to be in back.)
Also weighing in is an advantage of the second way: shapes exist in a consistent, cohesive world, where depth is absolute. This feels “cleaner” to me, and it would also allow for neat stuff like having a shadow which is part of the object, but will always appear behind other objects. (To do something like this with the lazy system, you’d need to have the shadow as a separate, deeper object that follows the main object around like, well, a shadow.)
Either way would be fine for most games, so it’s just a matter of deciding whether the effort to redesign things and implement the second system is worth the cleanliness.
I’m going to sleep on it. But if I were going to choose right now, I’d go with the first way. It’s simpler, and has a certain hierarchical appear.
Rebirth 0.5
(February 20, 2009 @ 02:45 AM)
I finished up Rebirth 0.5 tonight. There’s not much to say about it that I didn’t say last time: there’s a new Vector class, and Camera and Shape’s position, rotation, and scale attributes can be changed. This version is tagged as release-0.5 on Github.
The demo for this one looks the same as for the last version, although I did try a little test where the box could be moved with the arrow keys. Shapes aren’t meant to be controlled directly like that, though, so I didn’t keep it. I’ll add it back properly next version, once I implement the game object class.