It’s update time, and although I’ve nothing suitable/visual to show there’s been a fair amount of progress on the Pilot NPC/AI code of late.
I can confirm that I have now been attacked (and thoroughly ass-whooped) by a pack of Badian Pirates!
The design work for the NPC state machine has paid off, and has introduced a few new ‘concepts’ for the Pilot: the ‘Pilot Mind’, and the ‘Pilot Memory’
The state machine is really just a series of questions being asked, and the largely yes or no answers determine what state the NPC should be in (Flee, Attack, Dock, etc.)
So something needs to answer these questions, and I’ve collected all that logic in the ‘Pilot Mind’ – this analyses all the data available to it and answers complex questions, like ‘Should I Run Away?’ with a simple yes/no.
Now, I could just check something like ‘Did I get shot? Yes. Am I a coward? Yes. Run away.’
But that would be too simple 🙂 Plus the gameplay would suck. I want Pilot’s with a bit of personality at least.
So, to answer that question, the Pilot Mind has to understand whether the Pilot’s Vessel is under attack, whether the attack is beyond it’s defensive capabilities, whether the Pilot is brave enough to retaliate, whether the Pilot’s Vessel has sufficient weaponry to retaliate, and whether the entire collection of ‘hostile’ attackers is too much for it to handle, whether the Pilot is part of a larger flight of other Vessels, and whether they as a group can handle the enemy, and so on.
Quite a lot of stuff to check, as you can see 🙂
To help out, I introduced ‘Pilot Memory’ – which I’d intended in some form as I wanted NPC’s to hold ‘grudges’, notably against the player. Right now, the Pilot Memory is a short term memory of all collisions recorded against the Pilot’s Vessel. I may refine it further, but right now when the NPC asks ‘Should I Run Away?’ the Pilot Mind can ask it’s short term memory for how many times it got shot by someone in the past ten seconds, and then check each hostile vessels ‘threat’ level. If that threat level is greater than the Pilot’s own threat level, or the number of attacks (or attackers) is too high… the Pilot Mind can go on to check other aspects, such as whether the Pilot is a coward, and so on.
Later, I’ll introduce Long Term Memory to the Pilot, which will record ‘grudges’ and new rivalries, which will be distilled from the short term memories. This may sound like a lot of overkill, and it probably is. But, I want stories to form within Dominium, and the prospect of an NPC pilot surviving combat with the player, to then perhaps seek revenge a couple of weeks later is just right up there, IMHO 🙂 Not all Pilots will be persisted of course! But, some of them will definitely make it to the game database to be picked up later on. Also, some of these ‘memories’ can be pre-generated, so you may well be starting a new game with a definite set of enemies already on the go.
The Pilot Mind also introduces ‘Personality’ – at the moment, a fairly basic set of attributes like Bravery, Determination, Self-preservation, and so on. I may add a few more attributes later on, or even remove some unused ones, but all these allow me to generate Pilots with stereo-typical racial personality traits, and then alter them per Pilot to get variety. So a group of Badian Pirates would racially be very determined, suicidally brave with not much in the way of self-preservation, but you may still get the odd Badian Pilot who finds a sizeable furball a bit too much and scarpers.
Of course, the more attributes, the more complex the logic gets, and more un-maintainable and fragile the system becomes.
It’s also involved a lot of improvements to the Collision and Weapon systems behind the scenes.
So this all sounds like a lot of work/effort just to get an NPC to shoot at you, and you’d be right. But the cornerstone of Dominium has always been to make it ‘data driven’. By capturing the right bits of data on how the player affects the game universe, hopefully, a more complex and involving game experience will emerge, one that the player has – by and large – created themselves. You may make an enemy of a particular rival clan, but one pirate in that clan might really hate you…
Anyway, in short 🙂 right now, if you fire upon an NPC, they may run away, they may turn and fight. They use the same ‘controls’ as the player does, so there’s no real advantage over you. The only advantage is lightning fast reflexes, which I’ll tone down with a Personality Attribute.
Performance is becoming a concern at the moment, as most of the Q & A work going on in the Pilot Mind is in real time, which is not conducive to enjoyable frame rates. My approach is always to right the code first, get it working, then make it more efficient where needed. I can make a lot of improvements here by pre-calculating a lot of information in one pass of the game data and storing the results. Also, these passes don’t need to me made for every game frame, they could be staggered across several. ‘Dumb’ Pilots may not even ask as many questions, further reducing the load.
It’s also still all single-threaded code.
So many things… 🙂
Oh, on that note! You may notice the new ‘Development Effort’ widget on the right there… one of the (dis)advantages of using Redmine is knowing the total estimated effort, and time spent so far… so I thought it would be interesting to post the numbers for all to see!
Please take it with a pinch of salt, the total estimate will keep changing as not everything has been tasked out, or even estimated if it has. And of course, this is not ‘linear’ time, but ‘ad-hoc, when I get chance’ time… that 1.0 Man Year of logged time has taken me 5 years of real-time to date! That projection means another 4 years before the ‘Barely Viable Product’ might be ready… 😐