Friday, November 23, 2007

Kindle RSS Ripper

After trying out blogs and periodicals on the Kindle, I'm left reasonably impressed. It's really neat to pick up the Kindle and find that one of the blogs you watch has an update you haven't read yet. The push functionality is cool, and I dig what amounts to the pay as you go approach to the EVDO bandwidth. I mean, someone has to pay for it somewhere, right? And so what if Amazon are playing the margins for profit, the ARE a business, right?

But what about RSS feeds that aren't on the Kindle service yet? For that matter what about RSS feeds that you don't care about quite so much as to be that up to date? I have a few blogs that I read once in a blue moon, and entertained as I am by them, I can't see shelling out cash for them. Clearly Amazon don't want to trumpet free content when they're offering their upgraded cool stuff for pay, but they've graciously left a trail of breadcrumbs for anyone so inclined to follow.

First off, the format of Kindle documents appears to just be a wrapper around Mobipocket files. These are compiled binary files created by tools available at the Mobipocket site. Believe it or not, there are free versions of the tools there, including a command line compiler.

What are the input files? Turns out they're just plain old HTML. Mobipocket recognize a few extra tags aimed at books (e.g. a page break tag), but otherwise they're just HTML. Reference for the whole thing is available at the site.

So we have XML (RSS) feed documents on the one hand, and a command line compiler that takes HTML files and builds our desired output. Piece of cake!

I've whipped up a little command line utility of my own in C# that will process a list of rss feeds into a set of .mobi Mobipocket books. I'm posting it here for anyone else to try, but I make no guarantees about whether it'll work for you, nor will I offer any support or additional features. I don't have a lot of free time these days, and I'm only likely to work on it further should I need something more of it. Hey, if we're lucky this will inspire someone else to go make a fancier version!

Having said that, this does work reasonably well. So far I've tried it with Kotaku, Slashdot, GayGamer, XKCD.com and a bunch of other sites. If it fails for you on some other feed, I'd be inclined to suspect that it's yet another weird variant of what it means to be an RSS feed. I didn't know that the whole concept was such a mess!

To run this:
  • Download and unzip the RSSKindleSync.zip from here file to any directory of your choice.
  • Download the mobigen utility from the Mobipocket site and copy the actual mobigen.exe file to the same directory where you left RSSKindleSync. You should now have 4 files there: RSSKindleSync.exe, RSSKindleSync.exe.config, feed list.xml and mobigen.exe.
  • Now edit the feed list.xml file in that folder to add all the sites you're interested in ripping. Just copy and paste the existing tag and change the URL parameter for each.
  • Run the RSSKindleSync.exe file and away you go!
  • You should end up with a pile of .mobi files in a /books/ subdirectory under that exe file, one for each RSS feed you listed. Just copy these over to your Kindle's documents directory and you're done.
  • Whenever you'd like a refresh, just rerun RSSKindleSync.exe and all your RSS books will be rebuilt.
Enjoy!

Thursday, November 22, 2007

Amazon's Kindle, Device of Joy


So I've been waiting a decade or so for this thing. I grew up in an area far from easy access to books, and I was a voracious reader. After one point, appreciated presents almost entirely boiled down to new reading matter. Sure toys were great, but books were awesome. In the afterglow that was finishing a good book, I regularly fantasized about a magical book that I could command to show me any book I could think up. In that pre internet era, it was a pain just looking up the rest of an author's work, leave alone actually getting my hands on it.

So here now is the Kindle: an absurdly light, comfortable, easy to use little panel that can call up any one of 90000 books and growing. Sure, it's powered by money instead of magic, and it's surprisingly hideous to first glance, but it works. Damnit, it WORKS.

I'm as skeptical as the next guy, but the pent up lust I have for what this device promises was so strong that I put cash down first thing Monday morning. I practically ripped the packaging apart to get to it, and I'm happy to say that it's a bloody great toy.

The screen is wonderful, and a little magical. It is very comfortable to read off of, and the bizzarely physical nature of its rendering is a fun novelty. It's weird to think of it actually physically moving little elements around to form the picture. It's still all very first gen feeling: the refresh rate is awful, and the colors (think dark graphite pencil on newspaper stock) are clearly the only thing the technology supports, rather than a conscious design choice. But it WORKS.

Speaking of design, the thing is absolutely as hideous as the pictures make it out to be. It looks like a 10 minute quickie prop from a half discarded Buck Rogers episode. There's no defending the thing's looks, from its abundance of gawky angles to its flair-fallen-flat kooky keyboard. Gods willing, Amazon are already on a complete redesign of the form of the thing. But again: it works. The UI is limited by the screen's refresh rate, but they've done a great job compensating for that with the cool mercury slider bar. The giant page forward and backwards buttons are perfectly positioned for me, and the keyboard is quite serviceable for the uses its put to. It's also a lot smaller than the pictures make it out to be.

Book vs Kindle then.
  • Instant on: I can pick up a book at any point and thumb right over to where I left off. I routinely just walk away from a book to answer the phone, or the door, or to greet friends walking by, and so on. I've tried reading on my tablet PC, which fails miserably here. I'm always aware of battery life, and am very much in the habit of remembering to put it to sleep if I think I'm going to be away from it for a time, leading to a wake up wait the next time I want to pick it up. The Kindle on the other hand, I have no such qualms about. I've been using it for days without charging it up (keeping the radio off most of the time), and walking away from it is a non issue: it takes no power unless it's actually rendering a new page. Verdict: Tie.
  • Easy on the eyes: Books are a reflective tech. They rely on ambient light and therefore naturally match the contrast of the rest of your environment, meaning that your eyes don't have to adjust much to look at it. I certainly find far less strain from reading a book than from working on a PC for hours. Laptops, Tablets, iPhones, etc, all suffer the same sort of problem. The Kindle's screen is also reflective, and so as comfortable as a book. As a bonus, when my eyes are feeling a little tired, I can zoom in on the text and read with a larger font for a while. Verdict: Kindle wins by a slim margin.
  • Reading Comfort: Books are pretty small, light things that are easy to hold in one hand and therefore lend themselves to being used in all manner of comfortable positions. Curled up on the couch, lying in bed, lounging by the pool. My Tablet PC can do some of this, but it's just plain too bulky and heavy to lend its self to the one handed thing. The Kindle is as light or lighter than your average paperback, and about the same size. It's more than easy to hold while reading and has the added bonus of being always flat unlike the sometimes unruly curling pages of a book. No more annoying shadow creeping up from the spine if you fail to hold the book open far enough, no wind blowing pages over, no annoying imbalance in weight when you're at the head or the tail of a book. It's also the same size and weight no matter what size the book. No more struggling with that giant space opera epic at the breakfast table! Verdict: Kindle totally wins.
  • Price: The Kindle is WAY too expensive. I bought one, but I'm a nerd. If this is going to sell to everyone in the Oprah book club, it needs to be more like $100. Heck, if it was $50 and sold at airports, Amazon wouldn't be able to manufacture enough to keep shelves stocked for years to come. The actual e-books themselves are decently priced; I've bought a half dozen so far and none have been more than $6. That's absolutely fine with me. But the giant outlay here means books win this battle by a comfortable mile.
  • Convenience: I've moved around a lot in my life. The combination of being a nutcase reader and a nomad has meant that I've abandoned stacks upon stacks of books to charities, old boyfriends and (in the case of particularly dire books) the local landfill. On occasion I've almost wept at the separation; there was this one particular move after the period where I'd discovered Heinlein where I had to get rid of his entire body of work. Just plain ouch. Sure Amazon won't be here forever, and there's some chance that my collection will get bricked at some point, but they've been in business at least 3 times longer than the longest I've managed to hold onto all but a literal handful of books. Kindle pwns this one.
  • Accessibility. Books have become a hell of a lot easier to get at then when I was a kid. Even rare books are relatively easy to find online. The Kindle still has a limited supply of titles, but with Amazon behind it I have faith that more will pour in. I mean, if Amazon can't do it, no one can. Books that are available are absurdly easy to get at. The built in store is a thing of beauty, and already I've ended one book only to desperately bash at the keys to get my next fix from the same author (Neil Gaiman in this case. I hadn't read Anansi Boys yet, and segued into previously unknown to me Coraline). Less than 5 minutes I think it was, and I was sitting in a cafe to boot. I think 8 year old me wants the now me dead. Kindle for the win.
So all in all I'm happy with this evolution in reading. After thinking about it for a while, I find it silly to compare this thing to a book. It IS a book. We're not used to seeing advances in book technology, but this is it. It has plenty of room to grow in every direction, but the device that's available here and now works as advertised and the service it fosters will be the blood that runs the next generation of books.

Ugly as it is, it's certainly not leaving my side for months to come.

Doh!

To everyone who's e-mailed me in the past months since that last post: sorry I didn't get back to you! Life's been stupid busy, and what with the move to the US, I was cut off from any serious internet access for ages.

To those interested in what's become of RPG Zero, it's still sort of alive back there. I'm afraid that despite going for a job that I thought would be more relaxing than the last one (which was an overtime filled nightmare), I'm still finding myself without enough free time to work on personal projects. C'est la vie, eh? I still want to make RPG Zero, though now it's more likely that I'll be doing so in the quiet holiday/vacation moments rather than trying to jam it into evenings and weekends. I'll post here when and if I make any major strides.

Thanks again for all the kind comments and e-mails. And good luck to everyone still working on their projects!

Saturday, March 03, 2007

Pulp Friction

Karl in a comment asked what I'm doing for collision, so here's a brief run down.

I export the levels from Max as a simple XML file with triangles, load that and parse them into a friendly structure. I store all the parsed triangles in a balanced binary tree, subdividing cells on longest axis. I would use an octree, but that requires subdiving for effect, and I haven't yet invested in writing a triangle splitter.

My movable physical objects are all spheres.

After I move any of the physical entities, I do a constraint pass against the level, i.e. for each triangle, check to see if my sphere is intersecting with it. If it is, move me out of the triangle, using the direction I'm coming from, i.e. the direction from where I currently am, to where the intersection happened. This works just fine as long as none of the entities can move farther than their diameter in a single frame.

I do the same thing with any other dynamic physical barriers, but they are represented by boxes.

I also provide ray-tracing onto the level mesh, which allows for queries like, "find the closest point on the level beneath me".

Entity to entity collision is straightforward sphere to sphere intersection tests. Again, works just fine if no one can travel faster than their diameter in a single frame.

To avoid noise, separation between entities isn't direct collision response as it is with the level, rather it is applied as a separating force over time.
In effect, the wolves are flocking away from each other rather than strictly colliding. The thinking here is that it's better to have two wolves intersect briefly rather than bounce back and forth as they're corrected violently each frame. This also means that by and large they can't get each other stuck.

Thursday, March 01, 2007

Let There Be Cowbell



As promised, here's a look at a few pretties. We have a level segment with a new palette, and a new badguy, the froggy. These are the entry level badguys, so they don't put up much of a fight. Still blow up nice though.

I've also snuck in the healing item in the game: mushrooms.

So, coming on from last time's discussion of mesh animation, this update shows more examples of it. All the effects and character animations are done in the mesh animation manner, and hopefully to a consistent style. I still like it, still planning on writing a more efficient Content Pipeline plugin to pack them for me.

The art style is still holding together, I think. There's enough range in it, that I think I can cover all the locales I'm thinking of, and the gradient in the character of the environments I hope to depict over the story. I wish I had some time to sit down and concept out, but honestly at this point it's more profitable to just plow along. It takes an hour or so to model a new badguy. Bouncing back and forth between code and art (ignoring the vertigo), it was about 5 hours to get the frogs up and running from scratch. It's still a discovery process though, so I'm not too hung up on polishing yet. Getting everything working is first priority.

I have the design for the first level laid out now. It happens entirely underground, in a Zelda like dungeon configuration, complete with boss character. I'll stay focused on getting that done before moving on with any other portion of the game. I'm considering putting it up for public download at that point, to get a little feedback on how it feels.

Depends, really, on how embarrassing the whole thing is by then.

Before anyone asks, there's nothing clever about the cave scene. Reflections are the good old fashioned "render everything upside down", and the caustics are nothing more than a bit of fancy texture scrolling, where the x component is a sin wave on the y component. Sometimes, you just don't need clever to be fancy.

I'll be moving home for the next few weeks, so this might be my last post for a while. On the bright side: I'll be getting some new gear when I get to my new place, so perhaps I'll get around to trying some of those clever bits. At present, this PC is pretty much nipping at the limits of its little NVidia Ti4400 graphics card!

Tuesday, February 27, 2007

Zap! Pow! Biff!


A few things have happened since last time:
  • I now have the different firing modes in place. Each of Tad's (Tad, his name is Tad for now) weapons have 3 firing modes: tap for a quick shot, hold and release for a "shotgun" and hold for a while for a berserk blast. The fire gem has all 3 working now.
  • Added support for a bigger variety of effects. Mean, mean friends were saying it just wasn't pretty enough.
  • Built a cave environment.
  • Made froggies.

The vid above shows the attack modes. I'll post another soon with the new pretties.

I think I've reached the limits of the built in content pipeline plugins and it's time to branch out. As soon as I hit another wall, I'm off to write my own importers and processors.

I've grown to like mesh animation. It's crude, but appealing to me. Normally you'd rough out an animation by defining key poses along the timeline, then iteratively pass over the whole thing again and again adding overlapping motions and follow through to get a natural looking motion. Animating on a budget generally means animating pose to pose, and leaving it at that, and rightly enough that suits the mesh animation look better. I simply model the poses I require (using skinning in Max, if it's a complex mesh like Tad), then string them along a timeline in Stutter, duplicating appropriate hold frames.

With my own content processors, I could pack all those mesh frames into the minimum amount of data necessary, and the overhead should be pretty reasonable. Especially as I'm going low poly anyway. Certainly the runtime processing cost is laughably small compared to a skeletal animation.

Live scripting language is absolutely the bomb. Almost all of the logic bar collision is written in Stutter now, and the joy of being able to write player control while actually in the game is intoxicating. It would be quite a bit more work to get a professionally robust version going, but I think I'm going to start recommending it anywhere I work. It's just so worth it. I just need to see if there's some easy way to hook up live asset reloading (in this XNA version) as well. As it is, adding/changing assets still requires me to drop out and rebuild in VS.

In case anyone is wondering why bother with the XNA and C# when I'm off traipsing through my own language... how on earth do you think I got it all up and running so quickly? I'm still well inside month one, and I have the whole kit and kaboodle chugging along. In fact, I had a model on screen, being manipulated by Stutter inside the first few days. This is a product of C# and .Net's excellent reflection abilities coupled with the accessible nature of the XNA libs in GSE. All I've done is written a layer of abstraction above these that lets me speak directly to game concepts.

GLH out.

PS Music for the vid is by Cornelius (god please please please someone make him write music for games), the track's name is "2010".

Friday, February 23, 2007

Baby lisp


So the rpg has come on a little bit. I really ought to come up with a name at some point. For now, it stays RPG Zero.

New since the last update:
  • Tried to refine the look of the thing. I'm going primary colours, sharp contrasts, simple forms, abstract surfaces and everything easy to put together quickly. Also leaning a lot on vertex colouring for the low frequency shifts.
  • Our protagonist can now be hit by badguys, and keeps track of his health.
  • First blush at a HUD, and UI framework to back it up.
  • A chest! What's an RPG without a treasure chest, eh?
  • Refactored the player control to remove some annoying kinks, like sliding while idling.
  • Wrote a *secret* story outline!
I mentioned last time that the scripting language in this thing was a bit... odd. Well, here's a look at what a typical dev session is like.


Seem oddly familiar? It's not really lisp, but it does share some characteristics with it. Chiefly: code is data. I can pass it around, chop and change it, store it and call it later. The scripting language is interpreted, which means it inherently has the ability to inject novel code into the currently running session. Godsend that, when working on a game. No compile waits, you're right there, in the game, where you can see what you're doing immediately.

It's called Stutter.

It's implemented as a runtime interpreter that is plugged into a reflection based dispatcher. I have a class that contains all the intrinsic functions. I then have a few intrinsics for dealing with .Net types directly, cnew (new a C# object), cset and cget (set/get properties or fields) and call (invoke a C# function). These are for... well cheating. My character entity for instance, is a C# based PhysicalObject, that gets initialised and bandied about by Stutter, but lives in the Game.Components update loop.

Why not real lisp? Well, I couldn't find a handy implementation, and I've still a lot to learn about building and implementing the support for an embedded language, so it seemed like the right time to learn. And the right time to experiment. I've taken the things I like about lisp, and screwed around with the formula to give me the things I've always wanted for games. Will it work? Will it be fast enough? Will it be expressive enough? Who knows? That's the whole point of trying.

I did mention this whole thing is one big bout of self indulgence, didn't I?

P.S. Today's vid is higher res than the last one, so you might want to click on over to the bigger Google Video player to see it. Today's music is Billy Bragg and Natalie Merchant doing Way Over Yonder in the Minor Key. Totally love that tune.

Tuesday, February 20, 2007

RPG Zero: Another Start



So Ultrahead, over at Do as I say, not as I do... in a comment conversation reminded me that I've always wanted to make an RPG. Abandoning all the other toys (I have a habit of doing that), I've decided to embark on the adventure.

When I started writing about game programming here last month, I really did want to practice a little altruism and share some stuff with the community. I'm afraid the vanity levels on this project however, make it wholly unsuitable to share as good practice. The sheer self indulgence in the code should warn people away. I really can't in good conscience recommend anyone learn anything from this... the scripting language is an own rolled, interpreted, prefix notated, reflection driven nightmare for pete's sake!

I would like to share though. So if anyone is interested in watching, I'll post the goings on in my RPG land.

I thank you for your patronage,
GLH.

Wednesday, January 31, 2007

Shooter Zero: A data driven sample

So, in the last programming post I tried to dump what I know about data driven architecture onto a rather dense page. Here I'd like to share with you a sample application that might shed some light on what I was trying to say.

The ShooterZero.zip file over on my google pages page contains an XNA project that is a 2D shooter game framework.

The code describes a series of classes that together provide services that a shooter will need:
  • Resource management and a game loop with debugging functions (even a simple console!)
  • An object model, where all elements of the game are Object Instances that are created from Object Definitions
  • A scripting language to define the behaviour of Objects
  • A set of services that the Object Instances can employ, e.g. intersection, rendering, input, etc.
  • A parser that can create Object Definitions and Object Instances
The project comes with 3 XML file definitions for 3 different kinds of shooters.

The implementation here is admittedly very slapdash for lack of time invested, but I believe the principal features of the kind of data driven system I'm trying to demonstrate are evident:
  • Game is setup with parameters read from a data file - one engine supports a variety of expressions by implementing common primitives.
  • Objects in the game are defined using data driven templates, both properties and behaviors - data is parsed into logical collections of primitives.
  • Object instances are created from data - separate structure from content.
  • All the Data is reloadable at runtime - faster iteration time when it comes to implementing content.
So, if you wish, download and have a play with it. Questions are welcome, and if there's enough interest I could write a few more posts that break out the details.

A Dark Day For Gamedevs

An article over at gamesindustry.biz is painting a horrible picture of what's just gone down at Sports Interactive. In summary: a leaked pirate copy of Eastside Hockey Manager has killed legit sales so badly that they've had to can the game. Not any pokey little game either, we're talking a critically acclaimed game. They didn't make their money back and they can't afford to pay the hockey team licences in the game.

Real devs just lost real work. This isn't a theoretical discussion about piracy, it's real actual people who work to make games who have had their livelihood directly affected. No sales means no recoupment, means their investment down the drain. Thank goodness the company can survive the blow and the guys haven't been laid off.

To the pirate to hacked this one: hope you're proud.

Sunday, January 28, 2007

Data Driven Game Architecture

You hear the term "data driven" bandied about reasonably often in gaming tech circles. Why is this? Here I'll present a summary of my experiences in the matter.









Goals:

  • Laziness. We want to write the least amount of code to deal with each instance of a feature of our game. Why on earth write a whole class for a new bad guy if we can get away with a bit of data instead?
  • Laziness part 2, or maintainability. As a consequence of laziness, we want to end up with the most compact form and the least possibility for errors in our instances.
  • Quick iteration. Reloading a bit of data in a running game is much quicker than compiling and restarting. We want to spend time on the game, not the structure.
  • Encapsulation. Games change during development, usually quite a lot. Data is easy to add and remove from projects whereas code can all to easily get entrenched.
  • Devolution of responsibility. The power to actually carry out game implementation begins in the hands of the programmer, but not all aspects of implementations belong there. Data, and tools to edit said data, let you shunt that power to whomever requires it.

Bonuses:

  • Better modularity. We end up partitioning functionality in our code more naturally when we're thinking data driven. As a result, you're also more likely to get recyclable code for next time.
  • Easier serialisation. Writing your save game module can be made easier by a nicely data driven framework: the data to save is usually easily found and easy to mark out.

How to go about it?

  • For a given feature in your game, collect a definition that encompasses all instances of the feature. For example, if you're making an RPG you'll need NPCs. Each NPC might want to be able to engage in a conversation, query information from the world state, be able to retain and be queried on its state, etc.
  • Figure out what portions of your definition will be the variables between your instances, e.g. each NPC will have a different name, a different description, a different storyline, etc.
  • Figure out what sort of data will best facilitate describing those variables.
  • Start out right! If you already know you'll need this, invest in the time to get it right. Sure you can hack in something hard coded to start with, but you'll later pay the price in lost momentum when you least want to.

There are two broad divisions on methods of data driving a game.

  • On the one hand, we have the simple property bag. This is passive data that simply sets up a few variables for game objects. Simple RPG weapons, for instance, where each definition is a name, a description, damage information and some art resource references. My preference for this sort of data is a nice XML file. XML is robust and easy to parse, there are plenty of decent raw XML tools to leverage (especially if you write a schema to go with it), and there are plenty of mature XML code libraries to work with. That last part is particularly important as it makes a painless transition to a binary format, should it prove necessary, trivial. XML isn't perfect, but it's easy and it's there.
  • On the other hand we have the more complex behavior bag. This is an extension of the property bag where we also add some scripted behavior specialisations to each of our instances. Enemies in a shooter for instance: where each enemy is defined with some art resource references, and callbacks that contain code fragments to describe their AI. There are a lot of ways to implement this, a virtual cornucopia of choices. You have all manner of embeddable scripting languages like Python or Lua that are quite mature now, and plenty of experimental smaller ones if that's your bag. Depending on your exact requirements, rolling your own might even be an option. There's a lot to say for domain specific languages.

Things to watch out for.

  • Don't get carried away. Do your homework first, and make sure that you really do need to data drive a feature. There is some overhead to pay in terms of implementation time, and it's not a cost worth paying if all you'll do with it is define the one instance that never changes!
  • Remember performance. You should absolutely be willing to pay some performance decrease in exchange for data driving, as obviously you're trading that for a quality upgrade from the faster design iteration. Be careful not to be disastrously generous with this trade though; as with all things be pragmatic about the end result. Above all do not fall into the "we'll fix it later" performance trap. The industry is littered with horror stories where teams have leaned on a scripting language only to spend half a year backpedaling out of it to get the frame rate back to 30, or get the memory footprint back down to the release configuration.
  • Beware the lure of generic! When building your data driven system, it is intuitively tempting to continue to generalise the implementation. In fact, as you continue to work, you'll keep getting struck with "Hey, this is just a slight specialisation on that other thing!" Be careful here! All problems in your game are implementable in an ultimately generic structure: the programming language you're writing the game in. Hold fast to the idea that what you're doing is in fact specifying groups of solutions to remove the redundancy of implementing their variations generically! In other words: if you end up embedding a scripting language into your C++ game and then writing nothing else but script for every feature of the game... all you've done is swapped programming languages. This is not necessarily bad (and possibly a topic for another time), but it's not an action towards the ideal we're discussing here.
  • Continuously evaluate where you are. The whole point here is that you're optimising how you write the game. If you end up haemorrhaging more time than you otherwise would have, you've made the wrong choice. Often it's too late to back out, but learn all you can from the experience.

Sunday, January 14, 2007

XNA game structure thoughts

I've seen a few posts and articles around the net with recommendations on how to structure an XNA game, for example this great post at Cornflower Blue.

Most of these revolve around the same idea of building an own rolled Game Component collection class as the backbone for your game's partitioning, e.g. Startup:GCCollection, LevelSelect:GCCollection, InGame:GCCollection, HUD:GCCollection and so on. The collection usually implements at least Update and Draw, propagating the calls through the internal collection, and in most cases is actually derived from Game Component its self.

I'd like to propose a slightly different approach.

Back to the original reasoning for the problem:
  • XNA games want to stick to the Game class's methodology, i.e. Initialise, get LoadGraphicsContent and UnloadGraphicsContent called at the right times including any adapter malarkey, make sure Load is called before Draw, and conversely that Draw is never called when unloaded.
  • The most obvious and arguably the easiest way to do this is to implement Game Components. Bonus: sticking to Game Components should make code more recyclable!
  • Games tend to be easy to partition, usually with pretty huge chunks belonging naturally with each other, e.g. the level select screen's background and OK button belong together, while neither appears when a game is in progress.
  • Micro managing each Game Component would suck. Adding and removing each at every transition is error prone, and there may be any number of other operations that need to be done to them as a group that would similarly suffer.

These definitely seem to point at having a collection class around to hold the groupings, but here's where I diverge: why do more than the problem requires? Why reimplement Update and Draw iteration over the collection, and in the process actually lose the Order and DrawOrder functionality? Who's to say you won't want these interleaved between the partitions, e.g. Portions of the HUD group rendering and updating in between portions of the game world group?

What I reckon we really need is just a collection through which to issue orders to all its members. We're looking for more of a set really. So I propose something like the following:

    class GameComponentSet : List<GameComponent>

    {

        GameComponentSet( Game game )

        {

            this.game = game;

        }

        private Game game;

 

        public void Activate()

        {

            foreach ( GameComponent g in this )

                game.Components.Add( g );

        }

 

        public void Deactivate()

        {

            foreach ( GameComponent g in this )

                game.Components.Remove( g );

        }

    }



With a few of these we can manage our logical partitions as groups, but we don't chuck the functionality that is hidden away inside the Game class.

While Activate and Deactivate are pretty plain here, they serve as entry points for all manner of verification. For instance in Activate, you could check to see if the component is already in the game's Component Collection, and deal with the situation as you see fit, effectively adding in a bit of late checking to see if a Game Component is mistakenly in two sets at once.

Specific to each game, we could add other registration functions and properties here as well, e.g. RegisterPhysics to add all the Game Components to your physics manager, or RegisterUI to pass them onto your UI manager. Obvious additions would be the Game Component Enabled and Visible properties. Sure they may end up as just simple function/property wrappers around foreach loops, but as with the above Activate sample, it's always handy to bottleneck this sort of thing just in case you need to address it later.

Clearly we can also derive from GameComponentSet and make specific versions, e.g. UIGameComponentSet, PhysicalGameComponentSet, AIDrivenGameComponentSet, and so on.

Confession: The above simple sample deriving from List<>, while serving as an easy illustration, isn't entirely robust. The problem lies in the being able to change the collection after you've called Activate. Further evolution of this class would probably want to hide the collection implementation internally, and validate for this.

The only problem we face now is how to control the unloading of graphics content for our sets. Frankly, I have no clue how this is supposed to work. The function its self is not public, and it seems that the only way to invoke it is to lose the graphics adapter. I've taken to adding my own public interface addition to classes derived from DrawableGameComponent to chain the call over to the protected version. If anyone knows how this is meant to function, could you please shed some light here?

Finally, while admittedly it is more runtime work to add and remove all the members of the list individually rather than enabling or disabling a single entry point to them, bear in mind that the cost should still be really small, and rarely paid: how often do you reckon you'll want to turn entire modes on and off! For smaller sets, the difference should be so small, that its perfectly viable to use the same scheme more often, e.g. for HUD mode changes like overhead map on/off.

Saturday, January 06, 2007

Mooncasting: First mechanics!


Joy!

Just before I pop out of town for a week's holiday, I get to spend a day on my own toys. Life is good.

So I'm motoring along on this Mooncast project. Since the last post on the subject, I've written most of the main mechanics. The video illustrates the following:

* Buildings UI.
* Castle spawning plebs (here cheated to take no time for speed of demonstration).
* Plebs being reassigned to different buildings.
* Effect of staffing on the firing speed of cannons.
* Effect on fog of sending out scouts from the aviary.
* Blowing enemy buildings up!

Next task is to spend some time on the flow, i.e. start screen, begin, middle, end. Need to pay particular attention to the progress reporting while in game. I reckon that the right side of the screen will have mini icons for enemy buildings that have been spotted and nuked.

A note on the XNA so far: still loving it. Nothing has gotten in the way, and C# continues to be lovingly supportive. There are quite a few omissions in the XNA libs, but compared to all that has come before, this is a massive step forward.

Oh! And note: the music in the background of the video is the most excellent "One Thousand Tears of A Tarantula" by Dengue Fever. Absolutely music to code by.

Thursday, January 04, 2007

The Moral Combat trailer and Jumbled Jack


It's a trailer, and I'm absolutely not going to comment on someone's work without having seen the entirety of it. Suffice to say that I'm looking forward to watching it and seeing how he's pieced together this hot button topic.

No, this post is to address a specific quote from the trailer: Godverdomme, but I’m tired of hearing Thompson’s pearls of wisdom. We don’t recognise violence as a virtue? Really? Quick someone tell the military where the “will to kill” is a prime learned virtue, or sports fans who egg on boxers.

It is precisely because society is filled with violence-is-a-virtue memes that we find so much entertainment in fulfilling that self image. We want to be badass action heroes because we grew up being told that badass action heroes were bad as. And we’ve done that ever since David badassed Goliath.

I’m all for changing that culture, but it’s not going to happen overnight, and it’s certainly not going to happen through censorship, soft, self imposed, morally outraged, outright stamped, enforced or otherwise. Censorship doesn't challenge anything, it's just plain head-in-sandery.

If you really want to change our culture of violence, you need to create media that presents a different world view. You have to tell a different story, and a more compelling one at that. But no, Jack. Being against something is a whole lot easier than being for something, isn’t it? Being a destructive force rather than a creative one comes naturally doesn't it? Can’t charge if there are no windmills, eh?

Meanwhile, the least damage I can think of anyone causing while trying to live up these pervasive violent memes is acting them out in a video game.

Tuesday, January 02, 2007

Novelty: when did this become a dirty word?


I've persistently heard the oddest disparaging comment made about the Wii recently: "It's all just novelty. The Wiimote is just a gimmick"

WTF?

When did being new become a sin? For some reason I thought it was the goal: show people what they haven't seen before. Is "Racer X Part 4 Autumn '07 Tournament Edition 1.74 Extreme" really the path we want to go down? Is it really OK that the main attractions are the minor refinements instead of the mad gambles?

I say viva novelty. I, and others I've queried on the matter, have conversely found that the Wii's novelty is making everything old... new. Zelda is for all intents and purposes still Zelda, but everything feels so fresh with the new controls. Every little movement is a joyous discovery. It's almost like getting to start all over again, and Lord only knows how many times everyone's wished for that.

Whilst perusing the gaming shelves, I find myself furtively glancing at games in genres I would normally not give the time of day to. Like some sort of gaming pervert I'm now bloody flirting with anything I can shake a Wiimote at.

Luckily though, I don't really need to defend novelty much: the DS happened. It received the same disparaging comments about its dual screens, microphone and pen input. Despite that, this past Christmas it was the tearaway lead in sales.

Stop fighting it: Novelty is where it's at.

Elebits


So I got me some Elebits last week. General impression: Good fun!

The principle is very straight forward: the world runs on Elebits, these little adorable puffball creatures. Something's gone a bit off and the Elebits are behaving bizzarely, leaving everything without power. Your dad, currently away from the house, is an Elebits researcher. You decide to take matters into your own hands, grab his capture gun and start to hunt down the critters in your home.

The game works like an FPS of sorts. You shoot your capture ray at the Elebits, they get sucked in and you get power. The capture ray can also manipulate objects much in the same way that the grav gun did in Half Life 2. Elebits are shy retiring things and can be found hiding under or in objects, requiring you to basically make a mess of your environment to flush them out.

The electrical power you collect by capturing the Elebits goes towards various bits of electronics that come to life once you pass their power requirement thresholds. Proceeding to then turn these electronics on causes them to spew a different breed of Elebits that when captured upgrade your gun. An upgraded gun lets you manipulate heavier objects.

The core fun here is a balance of making a mess to flush the little buggers out, and sharpshooting them: so basically two things the Wii is bloody brilliant at.

Shame then that the package isn't left at that. In an effort to introduce more "game" to the proceedings, Konami have slapped in some unwelcome features. Well, at least unwelcome in my book. Some of the later levels come with additional rules applied to them. Two of the least fun are "don't make sounds louder than X decibels" and "don't break more than X shatterable objects".

Both of these run counter to the core fun of the game, preventing you from shredding the environments for fear of breaking the rules. Both are also very fuzzy: you're never certain what volume of noise any given action will generate, and in the chaos of objects flying about you could accidentally domino something over out of view. Both are just plain fun dampeners and very poor design decision to my way of thinking.

Luckily they're not pervasive, and once you've passed them it's back to the good stuff!

Visually the game is charming enough. Aurally everything is copacetic as well.

Honestly, if Katamari Damacy hadn't come along and pretty much defined true, unbridled mechanical and aesthetic zaniness, this would be golden. As it is, knowledge of better out there leaves you feeling that there's a sort of restraint while playing the game that can only be the result of not enough time spent polishing it. Somehow the whole thing just fails to make the jump from fun to sublime in the same way that Katamari Damacy or Rez did.

You feel this restraint in the objects that don't fit the collision system (looks like it only does convex hulls, but there are objects with large cavities in their silhouettes), in the music that fails to crescendo (sounds like they were composed without having played the game, so they loop indefinitely rather than aim for the time limits), in the story presentation that seems to lack soul (the same sort of non committal feeling that you get from bad Disney movies that are written by committee), and in the graphics that vary in detail from object to object (looks like there may have been a shift in target midway through). This is all a shame, because I like the concept so much, and when it works it works so well that I'm convinced it could have been an all time great if it were given the loving attention it needed to grow up.

Ah well. I was still thoroughly entertained by the whole thing, so I'm happy enough with it. Perhaps Konami will have the will to finish what they started in a sequel. Until then, most certainly rent this, and if you're a fan of the weird and wacky, you absolutely must consider treating yourself to a purchase.