My first task of the week was developing a better system of managing silos and information pertaining to them. Up to now, silos had been managed by arrays in the nation controller objects, which then drew that information on the screen. This worked for getting a basic idea of how to place silos and how to draw their areas of belief, and I didn’t need to worry too much about the details of how the silos would work. I could then worry about other, more basic issues. But the old management system was certainly not the best for managing all the information that had to be tracked, from where the areas of belief were to how much the player knew about the location of the silos. I had to design the system from the ground up.
My first approach was creating a ds_map in each player’s controller that would hold all information about the silos necessary. But this would require creating a nested ds_map and manipulating that structure. If GML were like R, this wouldn’t be a bad approach (R is a statistical programming language, and it has numerous methods for storing and manipulating data in a variety of structures; its extremely good for this and I will admit it spoiled me somewhat), but while GML does allow for nested ds_maps, their functionality is limited and I could not use them for my purposes.
However, even if it were possible to implement my original idea, the method I actually implemented is vastly superior. I realized that I had no good reason for not creating a silo object and having each player controller create and interact with these objects. In fact, working directly with the objects rather than trying to store the same information in the controllers would be far simpler, especially once the nukes start flying and silos are being destroyed. All that was needed was a ds_list which would contain the ids of the silo objects. I would call a script that would create a silo and give it all the information it needed about its controlling object. This method worked well.
Espionage was next. In the completed form of the game, spies discover information about enemy silos for the player, and silos had to be randomly selected from the enemy’s stockpile (the random selection is important for reasons I will explain later). The player has a ds_list of the “serial numbers” (which are only the reference number of the silo in the enemy’s list of silos) important for espionage purposes and for ensuring that the spy does not discover an already known silo, and when a silo is discovered, more information about its location is revealed. To randomly select a silo, I made a list that would create a sequence of numbers, then shuffle that list using ds_list_shuffle(). Then the script checks each entry of this list to see if it is in the list of known “serial numbers;” the first time a number not in the list is encountered, that number is returned. The spy then adds that number to the list of known silos and proceeds with his dirty work.
Numerous bugs appeared when I tried to implement this procedure, due simply to how new I was to not only ds_lists but to how GML does things in general, compared to the language I had been using during the entire prior academic year, R. But these bugs were a blessing in disguise; they made me realize that if I was going to have any success using GML, I would have to learn how to use GameMaker’s debugger. Watching YouTube videos and reading the documentation were both quite enlightening and I discovered how easy it was to use GameMaker’s new debugger which wasn’t around when I first started using GM:S (and I had in the past never used debuggers because I found them too difficult to use and seeming to only make the problem more cloudy, but that was before I knew about the blessing that is YouTube tutorial videos). The debugger helped me track down the bugs that resulted from fundamental misunderstandings of how things are done in GML. I learned from my mistakes.
Another major feature added was an estimate for the enemy stockpile size based on the known silos. Remember that I insisted that silos must be selected at random? Have you noticed how I have been referring to silo “serial numbers?” The procedure that both the player and the AI will use to estimate enemy stockpile sizes is the exact same procedure the Allies used in World War II to estimate how many tanks the German had based on captured tanks’ serial numbers, otherwise known as the (famous) German tank problem. I programmed an estimator function for stockpile size based on the maximum likelihood estimator for the number of tanks in the German tank problem. This means that both player, while not having completely accurate information about enemy stockpiles (unless the player has found all of his enemy’s silos), will have some information, and will have to figure out how to best use it.
The final feature added was a control for the spies and a spy ranking system. The player will have more than one spy in the completed game, and each spy will have a rank that will impact how effective the spy is at completing missions, not getting caught, and not confessing. The player will add more spies as the game progresses. I got the basics of the new spy system set up, but after completing this I realized that I could go no further without having an actual GUI for my game (which the spy icons were a part of). I spent my final day of the week planning out how the GUI would look.
So far, while progress on my game has not been rapid, it has been steady and my knowledge of GML has improved (which, in some sense, is the true purpose of this project). Next week, I hope to have a working GUI, a turn structure, and the start of the attack process. Here’s hoping I can accomplish these goals.