Ron Hiler:
March 4th, 2000
March 8th, 2000
March 14th, 2000
March 26th, 2000
April 9th, 2000
April 15th, 2000
April 29th, 2000
May 15th, 2000
July 14th, 2000
March 25th, 2001


Ron Hiler's Plan File

Current Book: Temple of the Winds(Terry Goodkind)
Current CD: The Very Best of Meat Loaf (Meat Loaf and Jim Steinman)
Current Games: Asheron's Call (Microsoft), BattleZone II (Activision)
Current Programming Task: Turn Generation Sequence

March 14th, 2000

Today's Episode:
The Interconnectedness of the Code
or The Tao of Manifest Destiny
or From Fleets to Player Messages, and Back Again

This is going to be long. And probably fairly incoherant. Even for me. You've been warned. Proceed at your own risk. I refuse to take any responsibility for those who read further. Do not adjust your monitor. I have full control over the horizontal, the vertical, the.... Oops. Wrong medium. Okay.

I want to talk about how jumpy things can sometimes get. By "jumpy", I mean the programmer (that would be me) moving from one thing to another in quick sequence, and when it is a good idea to resist this tendancy, and when it is a good idea to jump right along with it.

When programming a particular task (such as the main map display, just to have a "for instance"), there are about a million side paths that can pop up. Just off the top of my head, for the main map display, I could have worked on player borders, the map chooser, terrain info display, fleets, cities, resources, improvements to the terrain generation routines, player starting positions, and labelling, just to name a few. All of those things are directly related to the main map display. Each one of them will have their own set of side paths that could be taken.

You might think it would always be a good idea to stay focused on the task at hand. And in general, you would be absolutely right. While working on the main map display (to keep to our "for instance"), I ignored all of those side paths, pretty much. Usually I just wrote a stub routine for them, and left it at that (a stub routine is just a call to a function which does nothing but return to the calling function. It's just a way of letting me know something needs to be done here, but it can wait until later). In many other instances I have stayed focused on the task at hand. You have to, most of the time, or nothing will ever get done.

Eventually, though, you reach a point in the project where the interconnections can no longer be ignored. In order to get meaningful results out of the current programming task, you have to shift over to work on another task for a while. Indeed, sometimes these other tasks simply cry out to be finished.

If the words "Object Oriented Programming" just entered your head, as in "Hey! Aren't you violating the rules of OOP?!?", then you are thinking too low (and also, you know way too much about programming!). Yes, MD is being programmed in pretty strict OOP style (I draw the line in some cases. For example, if a structure would be perfectly adequate for holding some data, I generally refuse to turn it into a class just because OOP says I should). But I'm speaking, not of the code and the classes, but of the overall tasks. Think of those black boxes on planes, that record all the data during each flight. The box itself is like a C++ class. It's self contained, doing all of its operations independantly of what is going on around it. But it does still need to interact with the outside world. If it can't receive data from the plane, then it is useless. Same thing goes for the overall tasks in the MD code.

So let's get to a "for instance". If you look at the current Status Screen, you will see the next thing on the list to do is display the fleets on the main map. I've gone over before all the items needed to get a fleet to display on the map, and I don't want to go through all that again (check Deja under our newsgroup if you want to see it). Now, I've had "dummy" fleets on the map before, but they didn't consist of anything. They had no units in them, they had little relation to the data in the files (other than their location). Essentially, they were nothing more than graphical markers on the map, tests of the fleet drawing routines. Well, that won't do. We're going after our first Alpha version here, those fleets have to consist of something, and they have to use data coming out of the player files.

Fleets consist of a collection of units. A unit is a design created by the player using a unit template and unit components. So, the first thing we need to do to get a meaningful fleet is to have meaningful player designs. There are a couple of other things, but that is a good start. How do we get meaningful player designs? Discounting the first design, which is set for the player (by the New Game Creation Routines), these are created by the player. In order to create them, they have to know two things. What templates are available to them, and what components are available to them. These parameters are set from the Player File (the Player File is created by the host during turn generation and sent to each individual player).

Where does the Player File get them from? Well, it gets them from the Host File (the Host File is the master file, which has the final say over what players have, what they get, how orders are implemented, etc.). During turn generation, the program looks over the Send File (the Send File is created by the player when they save their game, and is sent back to the host). The Send File is essentially a series of requests to the Host File (I would like to research this item next, I would like to build a city here, please allow me to create 15 of this type of unit, here is a unit design I'd like to have build access to, etc.). The host file looks at what the Send File is requesting, in terms of research, and sets any research which has been completed that turn. It adds this to a list of previously researched items for that player, and stuffs all this info into the Player File. The Player File is nothing (more or less) than a response of the Host File to that players Send File (I've seen your requests, hereis what I can give you this turn). Confusing? Try programming it, heh.

Okay, the Player File tells the player, through the program, what is available to them to put together a new unit design. Let us assume they do so. They then save the game. A Send File is generated, and within this Send File is a request for a new unit design. The Send File heads back to the host, who collects a Send File from each player, and hits the Generate Turn Button. When that happens, the Host File starts processing requests, and it comes to our hypothetical new unit design for our player. In theory, if the program is working right, this design should be valid, in that it uses a template and components which are currently available to the player, and the player is within their unit design limits. Thus, the Host File should declare the design valid and allow the player to put it into city production queues. But, this is a multiplayer game, and certain safeguards must be put into place to insure this. Before the Host File says it's okay to start building a new design, the design is thoroughlyscrutinized for all the above factors.

What happens if a design is found to be unsound (ie a "hacked" design)? Well, obviously the Host File invalidates the design, which means it is deleted and removed from all the city production queues. One of the last steps is to add a message to the player in their message queue (it says something like "Due to a previously undiscovered engineering flaw, the xxxxx design was declared to be unsound. Your factories, reluctantly, have pulled the design from production."). If you are playing by the rules, you should never see that message (hopefully!).

But wait! Now we have a player message to deal with. You might think that the infrastructure to deal with player messages is already in place. After all, the first Player File (as generated by the New Game Routines) certainly contains player messages. Indeed, because of this, much of it is in place. But there is an essential difference between the first turn Player File (from the New Game Routines) and subsequent Player Files (from the Turn Generation Sequence). That difference is that, with the first turn, it is simple to create the variables which go into the Player File. We know exactly what units the player has, what designs, what messages they should get, what techs they should get, etc.

But the Turn Generation Sequence needs to deal with all this stuff on a much more general level. Just looking at the player message queues (which is what we were speaking of), any number of different messages need to go out to the various players, each with their own parameters. Much more tricky. As I write this, when you open a Player File created by the New Game Routines, it opens up fine (if you have the demo, you've seen this). Opening a Player File generated by the Turn Generation Sequence, on the other hand, crashes the program (which is exactly why I haven't updated the status page yet. As soon as I fix that little detail, I will). I'm working on it....

The routine to deal with generalized player messages has been written. They are being sent out to the player file in good order now. With that done, validation of player designs from the send file can be gotten to, and this is well under way. From there, designs are stored and sent back to the players. This part is done as well. From there, with designs finished and working, we can get to units, which are built from designs by cities. And again, we're going to get into a whole mess of stuff that needs to be touched on to get these working properly (we'll need cities to build em, production queues to put em in, validation of production queues, production points, resource costs, and no doubt a bunch of other stuff that I'm not considering yet).

Putting up the fleets is not so easy as just drawing them on the screen, as I hope you can see from all of this. To do #9 on our Status List, we've had to work on #18-20, 38-41, and 51. In fact, as I look at it, it seems to me that actually finishing #9 will be among the last things we do on that list. Not quite, but probably among the last 10.

Anyway, the point of all this, should there need to be one, is this. It has been my experience that, with the client apps, at least, when I start jumping around like this from task to task, we're reaching the beginning of the end of the project. Now, MD is a much bigger project than anything I've ever done before, so this might all be relative. The beginning of the end of the Alpha of MD might still mean a few more months (hopefully not!). We have a long way to go before version 1.0, but the Alpha, at least, is close.

I was supposed to put up a couple of Bandwagon songs with this update. Since the last update, I had a couple of people request to hear them (well, three, but that's about all the encouragement I need!). I will next update, I promise. I've got 'em made into MP3s, but they're big, and they won't upload for some reason, so I'll just make them again with less quality. They're from a CD of a live show, so the quality isn't all that great in the first place, so there is no reason to use the max quality settings on the MP3 Ripper.

- Ron Hiler (Lead Programmer)

Back to Top