When I wrote the AI for Galactic Civilizations, everything was hard-coded in C++. That was nice for me but not so nice for everyone who would like to tweak things later. Moreover, it makes it very easy for things to become a mess later on as improvements rely on my memory of what technique I used to do a given thing.
Yesterday and this morning, I officially began my work on the Elemental AI. What’s in the game presently isn’t AI, it’s just a few IF/THEN statements. My job is to design and code a structure that allows the computer players to play intelligently and provide a challenge without having to cheat.
So…how do you start?
The first step is with XML. You can do an awful lot just by defining lots and lots of “stuff” in the XML.
First, I start by defining AI personalities. My starting point is AI_General which is, as the name implies the general AI personality that I’ll start from. When I’m done, modders will be able to go in and define their own AI personalities that behave completely differently.
Here’s an example that I whipped up last night.
I define some Priorities (Economy, Farming) and I define some things I want the AI to avoid (War, Construction Times, etc.). Now, as I get better at this, I’ll tie together these definitions throughout all the game data.
So for instance, items that are tagged as Economy and Farming by the “AI General” will get their priority multiplied by 3.0X and 5.0X respectively. Someone else might come along and make AIPersonality=”RavenX” and have a totally different set of priorities. When the game starts, it’ll eventually look for all the AIPersonalities and grab them for the different AI. We might even let people from within the game pick which AI personality they want (not in 1.0 but eventually).
I’m a n00b
I’ve been using XML for years for skinning purposes but I’ve never tried to data drive an AI before. It’s not hard, but there is no substitute for experience. So over time, it’ll get better and better so that less and less of the AI is actually hard-coded and what requires “real” coding would be provided as Python.
Eventually, we will also have all the AI difficulty levels clearly defined so that players can adjust them far beyond what you could provide in the game UI.
BTW, feel free to shoot off your own ideas on this. My “AI skillz” largely revolve on producing macro-level systems for intelligent artificial players. Implementation is not something I am passionate about so don’t feel like you’re stepping on my toes by suggesting different implementation techniques.
You're my hero for telling it like it is.
Sounds good, but isn't this a bit utopistic? I haven't seen a game with a decent AI like that so far.
...Says the guy not programming the AI.
I ain't never bin someones hero afore...
Quoting BoogieBac, reply 28it it's attacks keep failing, have it try something else. If their attacks are succeeding, keep at it but 'improve' on what it's doing so it's even more successful. We could probably keep track of the number of unsucessful attempts at various actions, then have a threshold for when they'd give up and try something else......Says the guy not programming the AI.
Or perhaps Frogboy could put in a line that says "Flank stupid!" LOL
The AI could easily just log the results of all combat experience (along with strategies / patterns other players make) into a file.
Yeah that is ok Boogie, the question is this: Try something else you say...but what? Stop attacking X city and go for Y? Stop attacking X city, don't care about Y at all, but try to create more units? You got the picture. There will be countless number of choices.
However! I think a decent AI should react properly. Like if I use fire magic mostly, it should try to research spells which offers protection against fire magery, and try to counter the spells. The AI must [try to] defend it's cities & the Sovereign all the time, it's very important as well...and I could list much more stuff. Maybe creating an AI like this should be possible.
What about replacing the <EndTurn>50</EndTurn> by a <End><Turn value="50/></End>?
You could then provide other end conditions like <End><OwnedTiles atleast="40"/></End> when you leave the current state based on actual game parameters instead of turn counter. Eventually, a python function could be called inside the <End> element, although it might be slow.
The point is a fixed-turn counter cannot scale. What if you change the map size? There will be more turns. Do you have a separate xml file for each map size? For each map size + game speed combo (if there are game speeds like in Civ)?
Will your ai be able to adapt if research speed has been modded to be twice or three times slower and it only knows 'turns'?
Players rarely think in terms of number of turns but rather in terms of 'have built X cities' or 'have researched tech X', unless said players are playing a very precise setting with fixed map sizes/speeds/mods.
Yes updating will be so much easier! Better ai is always welcome. With tons of settings too!
"The AI could easily just log the results of all combat experience (along with strategies / patterns other players make) into a file."
My point exactly, except that 1 file will obviously not be enough. 1 brain, sure. 1 file? Not so much.
A file and a "brain" are two completely different concepts. If you want to compare a file to something, you can think of a file as our long-term memory.
The size of a file is only limited by the size of a hard drive; the information contained within a file can detail a number of different topics and be organized in any manner. The file would not do any "thinking" it would just contain information that the AI (being run and managed by the game) could use to make logical and informed choices.
How exactly to do it, I dunno... How it might be done... Take TCore's first post where he mentions:
"The algorithims were designed to avoid waste. The monsters would not fight those who they could barely hit, but who did little damage (i.e, if there's a low damage tank, just ignore him and go straight for 300+ damage mage fireballing us, or the heavy-hitter who kills one of us a turn) which meant tanks had to be sure to "hold the line," if they wanted to be super effective. Just like a real player, the AI knew to "kill the LRMs and carriers first, forget the sentinels.""
and:
"The commander knew everything there was to know about his own units, and unlike the individual AI which was weighted toward self-preservation and personal efficiency, the commander was all about weighing the multiples. If there was a ton of damage being dished out by a unit he knows is weak (his perception event has recorded that even his weakest unit has no problem doing damage to this unit) he'll prioritize them."
Could the algorithims be adjusted based upon successes/failures? Same with the weighing and prioritizing? ie -- some feedback mechanism. TCore mentions something of the sort occuring during combat (the commander having perception regarding his weakest unit's ability to damage) -- what I'm talking about would be similar but from a 'big picture' point of view -- apply what TCore mentions not just within an individual battle but from one battle to subsequent battles.
Setting up AI like TCores mentions is a good start, but if it can be adjusted ingame according to how it plays out, that would increase the ability of the AI without 'cheating'.
I don't know if any games currently avail themselves of this, or whether enough players sufficiently value a good AI for this to be worth their while. I'd sure as heck like to see it, and if Elemental can pull this off it might be a good selling point for the game. Flashy graphics are nice, as is deep lore, modding, etc., but great, non-cheating AI is too and would augment the game's longevity.
"The point is a fixed-turn counter cannot scale."
Given that a flexible AI is created, and for simplicity of editing fixed turns could work. This assumes more than one template being available as well.
What if the span between fixed Turns is directly related to what can be accomplished, via Tech/Research/Probable accumulated wealth, etc.etc, and those turn count spans were increased such that it allows more and more time (turns) and possibilities, to be taken into account?
At fixed turn count 1-25 is "establish your first Village". Priority would be set to accomplish that.
Setting up a priority for War/Army during that short time span would be a waste as the requirements for an Army or to wage war simply are not yet available.
At fixed turn count (after I have a researched mining and Forges such that Swords could be available) might be a better time to think about waging war or starting on a real Army.
I don't see it requiring new files/etc. (other than what's necessary to assess success/failure and adjust accordingly).
Maybe I'm missing something?
Changing behavior relative to turn counters is probably not the best way to manage behavior changes. I think that there's actually another number on which you base the choice to switch from economy building to military building, and that's economic strength to support the military. There might be other things that factor into this, such as how much of a lead your opponents have on you in technology or military. You might, for example, want to send a small attack to slow down your opponent who is trying to research technology quickly and neglecting his military. You wouldn't want to give a player a 50 turn respite to get a technology advantage with no fear of reprisal.
I also share TCores' apprehension toward XML as anything but a long term storage format. I would definitely store the information in tight data structures after reading it off disk to avoid having to re-parse the information for speed.
You could probably get a long way with an input vector of relative kingdom strengths, a difference vector of how your turn would affect those strengths, and a target vector for where you wanted to be before changing priorities. Calculating a path to get your kingdom close to the target could then be a shortest path algorithm with some fuzzing on the cost of the edges. Different personalities could have different target vectors or different path algorithms to get the result. You might be able to calculate that vector from the priorities given in the XML file as you've written it.
How a non-programmer envisions AI might work for sending out an attack force (as an example):
First I'm hoping it's not just 'put together a force and send it out'.
There'd be several elements:
-list possible targets (cities, roving stacks, outposts, etc.)
-estimate each target's strength (technology, hit points, etc), weaknesses (ie -- weakness to fire, no cavalry or ranged weapons, etc.), strengths (stone walls or ranged weapons, etc.)
-estimate difficulty reaching target -- distance, obstacles (rivers/mts/roving enemy forces that could intercept/etc.)
-whatever else is relevant
From the above, choose a target.
With target chosen, create an attack force that takes advantage of the target's weaknesses and the attacker's strengths, sufficient to overcome the target's estimated strength (hit points, # of defenders, etc.).
Conduct the attack then asses the result. If successful, how successful -- is the attack force undamaged? If so that's very successful. If only a few attacking units remain, that's barely successful. Adjust downwards the strength of the created attack force accordingly.
If unsuccessful, how unsuccessful? Adjust upwards the strength of the created attack force accordingly.
This is just a general example of course. Maybe I'm missing something but it seems to take advantage of what's already going to occur, just adding in a feedback mechanism that assesses then modifies already existing priorities/algorithims/weights.
Great idea here. Have the ability to end a phase trigger by multiple things. I can think of a build up phase for an AI, end phase after build up of 10 units or after combined unit strength >= 200. Then I want to go into attack mode until unit strength <= 100. then I will go into turtle and build mode again, etc.
I am already excited about making my own ai, and I rarely if ever mod for games (considering I program for a living, it feels too much like work. )
edit: I am assuming that Stardock has worked with enough XML to realize the limitations in real time access to XML (it's real slow), but there is no reason not to load those XML files at startup or at world creation time (once you know which AI's will be used) and then have them present in whatever object structure makes sense in the game. If they are using Python for scripting/AI work then there are numerous ways to get the data into Python and not have to reparse the XML each time. In any case, I think we can rest assured the XML won't cause a super slow AI, that will be easy to spot in testing if nothing else.
Just wanted to chime in support for this. The XML is a lot cleaner and easier to read using this kind of structure.
Agreed.
It is possible to do this, its been done in Red Alert 3 to an annoying extent, and if you played GallCiv2 you will remember the AI is relatively good at this already. That is assuming Frogsie doesn't forget what he did last time. These guys really are the Da Vinci of the 21st century.
Haha, awesome, so true. The only one I ever really played was Rome:Total War, which, despite being a really enjoyable game, had an absolutely abysmal AI.
On the other hand, the Civ 4 AI was pretty weak out of the box but got substantially better with future releases and with some community involvement. Given how well that worked out, the potential with the Elemental AI is staggering.
The Civ4 [BtS] AI is far from being decent. It's cheating @ the highest diff. levels. The Civ4 AI isn't cheating on medium settings however, and it's hella easy to beat it. That being said, Civ4 is a simple game basically...so I wouldn't be so proud of their AI.
Would it be possible to distribute the relevant schema (xsd) files so that we can have auto-completion?
I'm not a fan of XML. I work mostly in .NET, where Microsoft seem to think that XML is the perfect tool for everything from configuration files to messaging protocols to UI design. Tooling and can make it a lot more bearable though.
I'm not really an AI programmer, but from what I've been able to find out about other games' AI systems, there seems to be two options of changing priorities. 1) When you get to turn X then change to these priorities. 2) When Event X happens, change to these priorites.
If Elemental utilised the event style (2), this would aleviate your need for a "random adjustment". Could also possibly make the AI better. For example, using the event, "have surplus food >21", could cause the priorities to change into city building rather than farm building. Or event "declared war on" , could cause the priorities to change to war, research, and production. This would make the early game, 50 turns in Frogboy's example, actually be somewhere around 50 turns depending on if the start position was good or bad or average, which allows for accelerated progress, slow progress, or smack bang on the 50 turns progress.
Sounds good. I like the theme of what you are attempting to do, I know nothing about AI coding though (currently) so I will just say awesome ... thinking AI are ze best. Probably some setting in game start up that limits amount of time AI is allowed to think per turn (just to not slow down turn times) would be nice. Other than that, hellz yea
There are many great features available to you once you register, including:
Sign in or Create Account