Programmer Extraordinaire: Technical Aspects of the Game
Original Link (now dead) - http://acdm.turbinegames.com/featuredarticles/?action=view&article_id=147
Programmer Extraordinaire: Technical Aspects of the Game
By Alicia Brown
If you've ever been curious about what makes the world go round, now you can learn more about it. Specifically, you can learn more about how, technically, it all works in the world of Dereth - at least, from a "weenie's" point of view. To understand that statement, and to learn more about the technical aspects of this much loved massive multi-player game (MMP), read on about the inner world of srand, our very own "Programmer Extraordinaire."
In a recent interview with her, we gathered so much interesting material with exceptional detail that we decided to let it all out not in just one but in a series of articles. Here, we asked her to tell us about various elements involved in the technical side of the game - how all the pieces interact and what's involved in getting them all working together, as well as her part in the whole thing.
Srand on the technical aspects:
I'm primarily a game systems programmer, which means I work with the game systems code. Here at Turbine, we call this the "weenie" code. (There's a long and probably apocryphal story about this, but boiled down to its essentials it embodies the idea that - compared to graphics, physics, networking and whatnot - game systems is the easy stuff, the "weenie" tasks. Our game systems programmers have taken this to heart, and tongue-in-cheek are known as weenies, just as half our game systems code is presently weenie-this or weenie-that. They're on the Weenie Team and sit in the weenie area of the building, etc.)
From this point of view, there are three important pieces to the code - the client, the server and weenie code. Weenie code is the interesting things - allegiances, death, magic, creature AI, crafting and all the good game-specific stuff. Server code includes anything server-side that isn't weenie, like the aforementioned physics and networking and the bits that keep track of game objects and handle inter-object messaging. As the Lead Programmer on the ACLive Team, I have to have some understanding of the server code, but I rely heavily on the server team to handle any problems that arise in that area. Thankfully, our server technology is pretty good and reasonably stable. Likewise, the underlying framework of the client is pretty well settled, and my responsibilities there mostly involve fixing bugs in specific panels or adding new game-specific features - not easy, given the antiquity of our client, but not rocket science, either.
So most of what I do is in the realm of weenie code. Game systems are really all about the interaction between game objects. When you attack someone, for instance, your game object is sending attack messages to their object, which resolves the attack - decides if you hit it and how much damage you did. "Wait!" you say. "The defender decides that? What if it cheats?" Well, just remember that all of this is happening on the server. So you press a button on your client, which fires off an attack message to the server. On the server, your game object sends a message to the defender's game object, which resolves the attack. We can trust the defender to do this because we have complete control over the server version of the defender. When the defender has resolved the attack, a message is sent back to your game object, which forwards it on to your client, letting you know what happened. The defender, assuming it is a player, also sends a message to its client (creatures don't have clients, of course).
Probably the most challenging thing about weenie code is its asynchronous nature - which can be a bit difficult to illustrate without getting too technical. But I'll try.
Because game objects can interact even when they're on different servers, the messaging is not always instantaneous, which in turn means that other things can happen in between. For instance, taking the example above, let's say when you attack someone with a bow at range, you're on one server while they're on another. The attack message you send actually gets forwarded from your server, through the backend network, to theirs - which then delivers it to their game object. This can take time, but neither your game object nor (more to the point) your server can just "freeze" while waiting for the response, since that would pause everyone on your server! So, while waiting for your attack to be resolved by the defender, you might also be attacked - by, say, a mite. Now you have to resolve that while waiting for your result to come back. If the mite attack kills you, you'd be at your lifestone, possibly on another server entirely, by the time your attack result returned. In that case, your old server needs to forward the message to your new server, which means another short but very real wait.
So while these waits are much too short to be noticed by players, they are plenty long enough to cause complications from the computer's point of view. It means we have to be careful, every step of the way, about verifying that we're using the correct and current information: We need to be certain that the player hasn't died unexpectedly at some point, that they still have the object they were trying to wield, that the creature they were attacking is still within range ... it means a lot of point-by-point sanity checking - and this vastly complicates the code.