This last fortnight I’ve been making a bit of a developer screw-up.
Two weeks ago I set out to port one of my old games to my newfangled cross-platform system, to test the process in advance of doing it for Captain Stretchy-Arms. This was a resounding success – it took just one day to port the game.
Add another day to do some play-testing and make the iPhone controls silky smooth. So far so good.
Add another couple of days to add audio (the original game never had any). Still reasonable.
“Right.” I said, “All this needs is some user interface to handle things like starting a new game, setting the difficulty, and so on. What would be the best design for this? Ah! I have a good design…”
“I’ll make this panel slide up when the user drags it. That will be great. Well I need something to handle the dragging, and the button layout moving, a slider control would be good too, and it needs to work cross platform, and with my existing scene-graph system…”
“Sounds like I need some kind of generic GUI system. (But it’s ok, because can use it for all my games!)”
All of a sudden I’ve created for myself one of the most stupidly hairy problems in software development: the GUI system. A GUI needs to handle layout, input handling, event firing, and rendering, all in one messily interdependent, tightly coupled package.
(The fact that almost all the third-party solutions were barely useful on their own, let alone useful for my purposes, perhaps should have tipped me off that this was a bad road to take.)
So anyway, I procrastinated for a bit (another bad sign). Fortunately my idea of procrastination is to polish my game, so it wasn’t a complete waste.
Then I spent this last week trying to untangle the design mess that is writing a GUI system. Now, 1000+ lines of code later, I have the passable core of a GUI system.
Which I am now going to delete.
Partly this is a “sunk cost” thing. Even with the effort already spent on the GUI system, it’s probably just as fast, if not faster, to slap some hard-coded input handling on a static image and be done with it, than to polish up my GUI system and use that to build my interface.
Far more important, however, is the improved agility of the “slap it together” method. You may think that having a fancy GUI system would make developing new stuff easier and quicker. In fact the opposite is true. Here’s why:
Say I have a simple UI – just some buttons. In this case I can just throw some hard-coded input handling and an image or two together and call it a day. It’s easy to do, so it doesn’t really need all the features of a GUI system behind it.
But if I want some kind of fancy UI – for example a panel that slides up nicely when the user pulls on it – I still have to code it. And if I have a big, fat “system” in place, then I also have to code all the bindings to make my UI fit into that system. And then it becomes tightly coupled to that system, if I ever want to reuse any of it. (And let’s not forget, making things reusable is itself at least several times harder than simply “making things”.)
A far better plan is to just hard-code things, and then break out the juicy reusable bits into lightweight, limited-dependency primitive structures and functions as needed.
Of course – I already “knew” all this beforehand. So the deeper question is: how did I manage to not notice, for an entire week (plus a stern reminder from my friend Niklas), that what I was doing was actually kinda dumb?
I could start going into depth and talking about how immediate mode designs are preferable to retained mode. And about how my scene-graph (explained here) is retained mode, as necessitated by Silverlight, and how annoying that is. But I have a game that’s a few buttons short of finished that I need to work on – stay tuned for the playable demo…