Hello! Me Again. It has been over a month since the last dev blog so my target (writing one once a fortnight) has unfortunately not been hit.
I wasn’t really sure what to write about next: I could go into more depth about our universe, but that was the topic last time so I don’t think that would be right, I could talk about the art style, but I think I would rather leave that to Ian (our fabulous production designer). Eventually I decided to talk a bit about the artificial intelligence we are using in the Grand Mission. Compared to the previous dev blogs, this may come across as a bit dry, there aren’t and space-faring sheep here, but I hope you find my programming trial by fire somewhat interesting.
The first thing to note is that I hadn’t touched code until about a year ago… I am developing The Grand Mission using Unity3D, so the language I am using is C#, which is a really nice language to learn the principles of programming. Anyway, I knew that in making TGM (The Grand Mission), I would have to implement some form of artificial intelligence. We have lots of autonomous agents in the game: weapons need to target and fire autonomously; enemy ships need to move, fire and track autonomously; crew members need to make decisions about how to interact with rooms, weapons, engines, ammo storage, shield capacitors and more. I decided to start with the last of these three, as I knew it would be the most complex. Commence months of wailing horror.
To tackle the crew AI, I had to think like a crew member of a science-fantasy Victorian spaceship. The space ship is made up of rooms, which themselves consist of modules, which the crew can interact with. I initially thought that the best way to approach their behaviour was on a room-by-room basis. That is, when a crew member enters a room, they look around the room, check to see which modules (weapons, engines etc.) require the most immediate help: they rank them all using some algorithm, and then choose the highest ranked module to “interact” with. The “interact” function is context-specific, so interact for a weapon may mean fire, whereas interact for a wall may mean repair. Seems simple enough. However, there were two immediate problems, the first being that modules require different types of interaction. For example, weapons can be repaired, fired once, reloaded, fired on player command or fired automatically. The second problem was efficiency related. If every time a crew member needs to rank the modules they need to create new lists in the heads of every module, and run a load of functions for each one to count its allocation points up, AND if we have over a hundred crew members, things start to get slow very quickly. I needed a new soluition, and this one involved me ceasing to think like the crew member, and beginning to think like…
This is the section of the blog where I try to pawn off my couple of weeks programming AI as a profound epistemological exploration into what artificial intelligence is, and where the line between mimicry and authenticity can be drawn, whether group intelligence is a thing, and something about an ant colony.
The truth is, it’s really not as interesting as all that, I actually just wrote some very basic principles for the crewmembers, such as [go to module] >> [on arrival, if weapon is ready to fire & Has ammo, FIRE!]. It really is that easy. My crew members are incredibly dull and they spend most of their time milling around in throngs making ad hoc virtual mosh pits.
Anyway, our solution to the problems outlined a whole tangential segment ago was to attach an “allocation point counter” to every ship module, so that it dealt with its allocation points whenever its state changed: so every time it fired a bullet, it’s “reload” points would increase, increasing the likelihood of a crew member being assigned to reload it. This was an interesting change in thinking for me. Previously, I had been thinking of the crew members as unitary agents, who could make decisions about what to do wherever you plonked them. This approach more cultivated an illusion of intelligence, really some of the thinking was done by the ship modules, not the agents. SPOOKY. Alas, this system added unnecessary complexity, as the modules needed their own specific point system which would have needed to be accounted for by the crew members anyway.
The third and final iteration of our AI combined both systems. The algorithm I developed to rank modules contained different behaviours, and is calculated from very basic variables within the modules’ information, such as the amount of ammo they have vs their ammo cap, whether they have people assigned to them etc. This does not allow for the amount of flexibility that I would have hoped – for example, you cannot have one crew member reloading and one firing simultaneously, but it does simplify the system and make it a bit more palatable. Now the AI is divided into various room behaviours, which once activated, choose a job module to work on, and a behaviour, and get to work on that. It also allows flexibility and a catcher function, so if there is a problem and the crew member has got such for some reason, the catcher function should catch it and reset its behaviour – hopefully.
Well that is it for our incredibly dry AI dev blog. Next one will leave a smaller gap, I hope!