|« Apple, Simple and Elegant||Checking Your Digits »|
Sometime near the end of the previous millennium, Neinhalt Sieger accepted a programming at a small software company that built Java-based games. Although today we realize that Java wasn't quite the ideal platform for videogames, back in the 90's it was all the rage. If your game wasn't made in Java, it might as well have been with made out of wood and rolled with a stick.
Neinhalt was brought on specifically to work on a game called "Machine Man." The game's concept was completely original and nothing short of revolutionary: the player controlled a hero with a gigantic mouth that was trapped in surreal maze inhabited by four rather non-friendly ethereal types. The goal was to consume a vast amount of small, dot-like pills (the larger ones which made the hero able to consume the enemies as well) while avoiding the ghost-like ... err, ghosts. The only problem with Machine Man was the computers that wanted to run it. They were far to slow, leading to low frame rates, poor input responses, and skipping sound. And Bob, the lead developer of Machine Man, was no longer around to fix it.
To develop highly-interactive videogames in Java, the senior development team decided to build themselves their own set of cutting-edge libraries and a framework that would form the basis for all of their games. Machine Man was one of the first games to use this revolutionary platform. Management was confident that the problems with Machine Man lay in the game code itself and asked Neinhalt to focus on that and not their game framework.
Apart from the usual horrors of no documentation, a wide variety of magic numbers, and plenty of code duplication, the implementation of Machine Man was quite straightforward. It made absolutely no sense why the game would run so slow. All it did was move a few sprites around on a still background using a cutting-edge Java library. Going against his boss's advice, Neinhalt dove right in to the game framework.
The framework's main graphics library was centered around a sprite engine that was described, by its authors, as "very flexible." The library pivoted around a Generic Sprite Manager that managed instances of the innocently named "Sprite2D" class. And by manage, I mean delegate: the Generic Sprite Manager required that each sprite be responsible for drawing itself, detecting collision with other sprites, and so on. And what might the code for the Sprite2D class look like?
public class Sprite2D implements Runnable, Cloneable
For those who are not familiar with Java, the Sprite2D class was directly derived from the Runnable class. This means that it has the ability to create its own threads. As we learned in Flossin' My Threads, multi-threaded programming is used more often than it should be and is often done plain wrong. This was certainly no exception, as the Sprite2D's member variables show:
protected Thread animThread = null; protected Thread blinkThread = null; protected Thread moveThread = null; protected PointProducer moveProducer = null;
Yes, you guessed it. Each sprite instance spawned multiple threads to handle rather trivial tasks such as animation, blinking and moving around. The authors had taken the concept of Object Oriented Design to the extreme and given sprites their own spark of life.
Controlling the sprites was done using a PointProducer that generated movement points on the fly. Accessing these new points was done via:
You can imagine that the 'synchronized' key-word could be found plentiful in this library because it is Java’s own version of a mutex which enable multiple threads to safely access data without running the risk of race-conditions. Interestingly, the part where sprites would detect collision using a bounding-box was not protected at all:public synchronized Point getNextPoint()
public boolean intersects(Sprite2D sprite)
Using this advanced, "extremely flexible" library, a quick count of Machine Man's threads leads us here:
Main application: 1 thread 1 animated Machine Man sprite: 2 threads. 4 animated Ghost sprites (blinking when eaten): 16 threads. n (at least 4) animated "Power" dots: n*2 threads. m (at least 20) regular dots: m*1 thread(s) 1 Bonus Item: 1 thread
As you might imagine, the amount of thread switching and synchronization that would occur using this system was (and still is) mind boggling. For any level in the game, there was at least 50 different threads running or waiting for a time-out. Can you imagine this beauty running in your browser from 1997? Or even being the basis for another arcade game such as Space Invaders?
After discovering the legacy Neinhalt had inherited, he saw no other option but to rewrite the entire system from scratch using a single thread and a cell-based internal representation. Everything went fine and resulted in a major improvement in stability and frame-rate. Sounds worked, the Machine Man hero actually moved when you pressed a button, and the game could run on just about any machine that supported Java. It was quite an accomplishment: they had finally reproduced a 1970's game using that latest technology and modern computers.
When Neinhalt turned in this much-improved game, management was not impressed. "Errr," his boss said, "this is too smooth and does not have the same feel of the original Machine Man. We need the game to be identical to the old one, just be able to run on all computers. We'd like to run a contest where people can compete with each other and send in their high-scores. Some players will have the current version, others will have the new version."
In the end, with a sore heart, Neinhalt added scores of code to delay user input, reduce frame rate, and skip the sounds. And again, Machine Man was where it was, only actually able to run on most computers.
A year or so later, the bubble burst and the senior developers left to form their own company. Rumor has it that they are still developing games and still trying to perfect their "Sprite Threading" technology. In fact, they've moved on to cloning games from the 90's and are getting very close to releasing Rad Dudes, a game where The President is captured by Ninjas. And if you've got a dual-core processor and a lot of RAM, you just might be a rad enough dude to rescue the President.
As for Bob, the original architect and designer of Machine Man and the game library, he left the games industry a while back and is now writing software for medical equipment.
|« Apple, Simple and Elegant||Checking Your Digits »|