Monday, November 21, 2011

Refactor Bonanza

Pride Goes Before a Fall

Those Twitter-enabled readers might remember me bragging about resisting the urge to refactor a system a while ago. Well, turns out hubris is still alive and well. Several days after my proclaimed victory, a use case failed, and four hours of tracing spaghetti code later, I was still no closer to fixing it.

That system, of course, was the inventory system. And the use case was stacking items. Several months of iterative development combined with changing requirements led to a system fraught with confusing methods. Methods with names like "TryFitItem," "CheckFitItem," and "ItemFitsInCapBox." Can you tell what each of those does differently? I can't. And I wrote them!

It turns out those functions were not only confusing to work with, but wasteful of the CPU as well. They did a lot of equipping and unequipping of items, shuffling them around in different containers, all in an effort to see where they fit best. And while all this was going on, the buffs/debuffs for the items were stacking and unstacking with each check. Then, when this rigmarole was over, all I got back was a boolean. Or in some cases, not even that explicit (e.g. a point that might be null). What does this boolean mean? Did the object fit where it was? Or did it stack? Or maybe the user wanted to swap it with the item underneath it?

I decided to refactor. It took several days (~2.5), but it's a much cleaner system now. The methods are more compartmentalized, so each has a clearer function. They do less actual moving of items, and more hypothetical testing of new positions (saving processing time). They do things in a more consistent way. And most of all, they return more contextual information in the result.

New Resolution

I also changed the game resolution from 1280x720 to 800x600. This change resulted from a performance test, but is meant to address a business issue. Originally, the game was done at 720p, with assets all scaled 2x for the retro "fat pixel" look. I figured I could get good screen coverage on a modern widescreen at 720p (even accommodate TV setups and eventual ports to HD consoles, if need be). And for portals that wouldn't allow that size, the 1x size would surely fit (640x360).

However, the 2x scaling takes its toll on some machines. And, as it turns out, nearly every Flash portal out there would need the small version, as 1280 is way too large. However, finding actual numbers for maximum resolution turned out to be difficult. In most cases, sites didn't list limits on their FAQs at all. For those interested, here are the best numbers I could find (or guess, based on existing games' widths or the site's frame size):


It was pretty clear the 720p version wasn't going to fly, even retooling the art to be scaled 2x to improve performance. So I started exploring resolutions compatible with the above, and settled on 800x600. Why 800x600? Mainly because the sponsors I've heard the best things about have that as an upper limit.

There's no way I'd fit everything into this new, smaller size of 800x600 though. Not unless I ditched the 2x scaled look, anyway. So after much hemming and hawing, I decided to bite the bullet and live with 1x scaling. It actually gives me more space to work with than 720p at 2x scaling, which alleviated some GUI issues I previously had. Here's a sneak peek:

Maybe 800x600 is more retro after all.
I did keep the encounter image at 2x size, just because there was room for it, and it seemed a shame to hide a full encounter illustration up in the corner. Normally, I'd rail against inconsistent graphics standards in a game, but in this case, it's the lesser evil.

New GUI!

You might also have noticed some new GUI elements. The status bars now have some snazzy overlays to make them more attractive and "finished" looking. Similarly, the message window was expanded to the same height as the attack mode, and shares its style.

Giving those elements some polish really made a difference, and I can't wait to follow-through with the rest of the GUI. But not until the layout is more stable. Still a few more days of work to go before the resolution shake-up settles down.

Everything's smaller now. Hopefully not too small.

New Font!

I also use a new font in this version. "What's wrong with the old font," you ask? I rather liked it too, but I was unsure as to its use license. After some time looking around for free to use fonts, I stumbled across FontStruct.com. It's an online font creation utility that allows you to draw, letter-by-letter, your own fonts, and then download them as ttfs. And, as it turns out, it doesn't take that long to do. In about 30 minutes, I had a custom font hooked up to my game.

I may still tinker with it at a later date. It's legible, and looks fine, but it's not very unique. Custom fonts can often lend a memorable character to a game. But for now, at least I'm not violating any copyrights or licenses.

Roll your own fonts in 30 minutes!

Creature AI

I also put some more work into creature AI. Creatures now use the visibility methods I worked on previously. And this means they can head towards distant objects (player, enemies, loot, and tracks). I've also started working on AI for choosing the best weapon, though that still produces some inventory bugs. When I'm done, though, hopefully I should get the occasional NPC rifle shot from afar.