🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

The Hacktins Diet

Published August 08, 2004
Advertisement
Throwing together the Java Project That Cannot Be Named following making a dozen small Flash games, I gave some thought to my development process. I gave the process even more thought upon seeing my client's development setup, which consists of networks of CVS servers and WIKI's and XML and build-scripts used so thickly that they're even compiling freakin' Flash apps from the command-line.

I didn't even know it was POSSIBLE to compile a Flash app from the command-line. Pressing + was simple enough that I never even gave it a thought.


I remember TANSTAAFL covering similar ground a couple of months ago, so I grabbed his list.

His original list for database applications was as follows, in order of importance. . .

Robustness
Maintainability
Extensibility
Elegance
Speed

Applied to his smaller projects, he reordered his list as follows:

Robustness
Elegance
Speed
Maintainability
Extensibility

Looking at his list, there's not much I'd change, although I might move "speed" above "elegance" when working with speed-strangled platforms like Flash and J2ME. There are a couple of factors I'd add, though.

Perfection (as in lack of bugs)
Repeatability

Although I suppose Perfection is just one aspect of Robustness. Both of these factors would exist near the top. Interestingly, I've recently given up entirely on the whole "make a great game engine and then use it for a series of games". My latest crop of Flash games has had nearly zero reuse of code. I do, however, use the previous code-base as "inspiration" for my next game rather than as a base of operations.

For example, in my Flash games I considered but didn't bother writing a point class with a robust function interface (distance between points, comparisons, etc) in favor of just using X/Y variables and pulling in functions as necessary to do stuff to 'em. If I need a distance formula, for example, I remember writing one for a previous game, and I just cut-n-paste the thing in from the other code. I know it works because it worked in the previous code. Yeah, there's the possibility that I might someday devise a superior distance formula and will have to replace it in more than one location, but thus far that hasn't outweighed the disadvantage of having a "fatty" codebase full of functions that aren't even used by the app, requiring me to sift through several source files to find what I need.

I've also gone for the "minimal calling interface" technique recently, which is based on two simple maxims. . .

If a function is only called from one place, then it shouldn't be a function. Fold it into the calling code. If an object isn't instantiated multiple times, it shouldn't be an object.


While the object part isn't a maxim that can be followed universally (Java, for example, often requires that certain objects exist), it actually appears to be working. I'm hacking together small and relatively bug-free programs and am having more fun doing it.

I ain't gonna even try to evangelize this technique, though. It's only useful for a very narrow set of applications (small stuff written quickly with few enough function points that it can be comprehensively bug-tested without much trouble).

Now then, back up to my previous list addions:

Repeatability - The ability to "repeat the success" of your previous projectlet, using the previous project as inspiration rather than codebase. If you can make a second game that's tigher and less buggy than your previous effort, then you're apparently doing something right. Don't let anyone tell you otherwise.

Perfection - Patches are a lousy idea. They only work for a very narrow game-market (gamer-oriented desktop titles). If you're developing for novice users or consoles or handhelds or cellphones, patches are either impossible or will be ignored. Your game had better be 102% bug-free when it ships or you'd better plan to write a lot of "I'm sorry" responses to all the emails you're going to get from people telling you that your games are garbage.

Now then, perfection is the alter-ego of maintainability. If perfection is Mister Spock, maintainability is that alternate-universe Mister Spock with the pointy goatee --somewhat similar, but mostly polar opposite. Maintainability assumes that your code will be revisited after it's shipped, and that's not a very good assumption. Get your code right the first time, and you'll have the luxury of being able to move on to your next project.

Extensibility is pretty-much pointless. Look at all of the enhancements that have been added to Windows Solitaire and Minesweeper since 1991 if you need an example of the worth of extensibility. Again, make your game fun enough from the start, and you won't need to extend it. Instead you'll be able to sell people a whole new even-more-fun game when they eventually tire of your original offering.


Funny thing is, all this talk is 180 degrees different from how I used to think even five years ago. I can show you a fine example of a beautifully written cross-platform game engine for Windows/Mac/PocketPC that I wrote a few years ago "the right way". It's maintainable and extensible and bug-free and is such a joy to read that I want the code carved on my tombstone when I die. . .and I used it to write one game that I never finished. If I'd spent all that time writing individual games, I would've at least finished a few.

OTOH, I've been writing my Flash and J2ME games "the wrong way" without OO techniques and monolithic blocks of code and a code-library built as cut-n-paste clipart rather than a handbuilt game engine of objects. . .and those games are much better than the half-game that was built "the right way".

I feel like that doctor who discovered that eating nothing but bacon can make you lose weight. Maybe the dark-side of the force is really the right way after all.

Problem is, this technique requires a lot of trust in yourself and your abilities. Thankfully I've got that. Also, my client knows that I've got the field-experience to get a project out the door, so they stand aside when I prune out giant chunks of their code and fold together dozens of functions down into one monolith in the name of efficiency over maintainability. I do have the luxury (and the ego-fueled cajones) of inviting the technical leads to empower themselves to look elsewhere when I turn their hand-tuned object model upside-down.

Thus far it's worked. The original "object template" upon which the game was written was about 2,500 lines of code which compiled to about 12k of .class files. The completed game is about 2,100 lines of code that compiles to about the same size.



I was worried that my technique was gonna backfire when my game crashed spectacularly on the S60 phones (Nokia's 3650 and N-Gage series). Turns out that the S60's functions to get a substring from a string is very broken and takes down your app if your source string is more than 196 characters, forcing me to write an "improved" (meaning "not broken") version of the function.
Previous Entry EH?
Next Entry Ooooh, bump maps
0 likes 1 comments

Comments

rcarey1
Hey, that's exactly how I write code... NOT!

That sounds like a great approach for the type of programming you do. I only wish that I could follow such a system.

I used to follow two simple rules of programming:

1. You never have enough memory
2. Your program is never finished

Advances in tech have eliminated rule #1 for the type of stuff I write. So that only leaves #2.

And to this day, I really don't consider any program I've ever written to be really finished. There's a little something I'd like to do to each one of them that I'm pretty sure I'll never get to do.

Rick--
August 09, 2004 07:50 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement