It was 10:30 p.m. on February 29, 2008. I had just finished building *Gravitation* Version 1 for all platforms, packaging each build, posting the builds on SourceForge, and composing the web site. That process -- the very tail end of my software development cycle -- takes me about an hour. At that point, I was finished with the release and feeling good.
But then I did something that I really should never do. After testing the downloads, to make sure the files weren't corrupted, I decided to spend eight minutes playing the game one last time before going to bed. At the tail end of this final playtest, I noticed a detail about the game that was not quite right. It was subtle, and certainly not a full-blown bug, but it wasn't perfect.
I'll summarize the defect briefly. At the end of the game, if players continued holding down the movement keys as the title screen faded in, a new game would be triggered very quickly by their unwitting key presses, barely giving the players a chance to notice that their first game had ended. Of course, this was a glitch that most players would probably not encounter. And even for those who would encounter this rough spot, it wouldn't spoil the game itself, but would just make the ending a bit confusing. Should I fix this problem? I was torn.
On one hand, I was tired of working on this game, particularly so late at night after a long day. On the other hand, I knew that my mind wouldn't let him me sleep if this glitch was out there in the world. I simply couldn't bear the thought of even a single person having their play experience confused by this imperfection.
So I set to work, fixing the code and going through the entire build/package/post process over again. By 11:30 p.m. on February 29, I had released Gravitation Version 2.
This experience got me thinking about my own perfectionism. When is a project really done? How much polish should be applied? Is there a law of diminishing returns? Is it sometimes better to ignore a small flaw than to spend a large amount of time fixing it?
The trap of perfectionism is particularly treacherous for computer programmers, since we're saddled atop of Turing-complete programming languages that are capable of doing almost anything. Every bug is fixable. Every behavioral rough spot can be smoothed over with just a bit more coding, a smidgen of extra special-case logic. Programming isn't like carving something out of marble, where if your sculpture's nose is too small, you must either live with it or start over with a fresh block of marble. Our code bases can be massaged indefinitely.
In designing a game to explore this issue, I thought about players tweaking some set of game objects toward a goal, but forcing them to decide how far toward the goal they needed to go. If we give the players multiple sets of game objects and goals, and force them to divide their limited time among these "subprojects," they will need to make interesting decisions about which projects to polish, which to leave flawed, in which to skip completely. This is quite different from traditional level-based game designs, where players must finish a given level before moving on to a subsequent level.
Since the message in this game would be carried by the overall level-to-level structure, the core game mechanic didn't matter all that much, as long as it allowed for some form of progressive refinement. I settled on a rather simple column- and row-swapping mechanic that does the job nicely. Along with supporting progressive refinement, this mechanic's emergent properties are complex enough to be interesting, while not so complex as to be overwhelming. I've never seen this particular mechanic before, but I'm not sure that it's novel. I can imagine a match-3 game employing this kind of column and row swapping.