Frogboy Frogboy

Elemental – Data Driving the AI

Elemental – Data Driving the AI

image

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.

image

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.

870,939 views 106 replies
Reply #26 Top

Quoting John_Hughes, reply 24


The android DATA is a fascinating bit of futuristic imagination but the reality is. We have a very very long wait for it to even becomes anything other than a wet dream.

 

You're my hero for telling it like it is.

Reply #27 Top

Quoting Nick-Danger, reply 22


Also, I'd like to see AI learn during a game -- it 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.

Sounds good, but isn't this a bit utopistic? :) I haven't seen a game with a decent AI like that so far.

Reply #28 Top

it 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.  :)

Reply #29 Top

Quoting TCores, reply 26

Quoting John_Hughes, reply 24

The android DATA is a fascinating bit of futuristic imagination but the reality is. We have a very very long wait for it to even becomes anything other than a wet dream.

 
You're my hero for telling it like it is.

:blush: I ain't never bin someones hero afore... :blush:

Reply #30 Top

Quoting BoogieBac, reply 28

it 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

 

 

Reply #31 Top

Quoting John_Hughes, reply 24
I don't want to sound negative but a "thinking AI" may be a bit much. Take a decent Chess AI and give it unlimited time to make moves, and your a decent opponent, and you now have to shave between moves. I think that even DEEP BLUE was given a time restriction.

If an AI was to really "learn". Where would it store and or retrieve all that learned knowledge? Lucky us, we carry our around in a melon atop our shoulders.
 

The AI could easily just log the results of all combat experience (along with strategies / patterns other players make) into a file.

Reply #32 Top

Quoting BoogieBac, reply 28

it 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. 

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.

Reply #33 Top

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.

Reply #34 Top

Yes updating will be so much easier! Better ai is always welcome. With tons of settings too! }:)

Reply #35 Top

"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.

Reply #36 Top

Quoting John_Hughes, reply 35

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.

 

Reply #37 Top

Quoting Tormy-, reply 27

Quoting Nick-Danger, reply 22

Also, I'd like to see AI learn during a game -- it 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.


Sounds good, but isn't this a bit utopistic? I haven't seen a game with a decent AI like that so far.
Utopistic?  You bet!

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.

Reply #38 Top

"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.

 



Reply #39 Top

Quoting John_Hughes, reply 35
"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.
I'm not a programmer, so can't specify how it'd work.  What I'm thinking is that since Frogboy mentioned priorities, and the AI will be using some logic to decide when/where/how to attack (or build, or explore, etc.) and some sort of 'priority' to decide this (or algorithim or weighing), and these priorities/algorithims/weights will be coded in, then allow them to be modified during the game according to success/failure.  Keep the original values, and have modified values, and an option of which to use.

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?

Reply #40 Top

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.

Reply #41 Top

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.

Reply #42 Top

Quoting LDiCesare, reply 33
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.

 

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.  

Reply #43 Top

Quoting Peace, reply 3
I am wondering if it is a good thing to have so many different attributes with important semantic meanings used for the the same XML tag. I am not really sure that it helps extensibility (adding new priority focus). I guess only time will tell which is more usable for AI coding

You could have written your XML that way

<GamePhase Early="GamePhase_Early">
   <EndTurn>50</EndTurn>
   <Priorities>
     <Economy Value="3.0"/>
     <Farming Value="5.0"/>
   </Priorities>
   <Avoid>
     <War Value="3.0"/>
     <ConstructionTime Value="3.0"/>
   </Avoid>
   <SovereignFocus>
     <CityBuilding Value="3.0"/>
     <GoodyHuts Value="3.0"/>
   </SovereignFocus>
</GamePhase>

Just wanted to chime in support for this. The  XML is a lot cleaner and easier to read using this kind of structure.

 

Reply #44 Top

Quoting Tridus, reply 43



Quoting Peace Phoenix,
reply 3
I am wondering if it is a good thing to have so many different attributes with important semantic meanings used for the the same XML tag. I am not really sure that it helps extensibility (adding new priority focus). I guess only time will tell which is more usable for AI coding

You could have written your XML that way

<GamePhase Early="GamePhase_Early">
   <EndTurn>50</EndTurn>
   <Priorities>
     <Economy Value="3.0"/>
     <Farming Value="5.0"/>
   </Priorities>
   <Avoid>
     <War Value="3.0"/>
     <ConstructionTime Value="3.0"/>
   </Avoid>
   <SovereignFocus>
     <CityBuilding Value="3.0"/>
     <GoodyHuts Value="3.0"/>
   </SovereignFocus>
</GamePhase>




Just wanted to chime in support for this. The  XML is a lot cleaner and easier to read using this kind of structure.

 

Agreed.

Reply #45 Top

Quoting Tormy-, reply 32



Quoting BoogieBac,
reply 28

it 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. 



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.

 

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.

Reply #46 Top

Quoting leeboy26, reply 25
So Frogboy has started on the AI eh? Well I don't know much about that but if it's anything like the Total War games he'll be finished by tonight.

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.

Reply #47 Top

Quoting Ryan, reply 46

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. :P

Reply #48 Top

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.

Reply #49 Top

Quoting Nick-Danger, reply 20
For game phases (early/mid/etc.), a hard definition (turn 50 for early, etc.) bothers me, as it gives players some out-of-game foresight on when things will change. I'd prefer it be random, one that would vary amongst AI and change from game to game.  Also, a gradual change would be better than an abrupt one (since priorities are multipliers, instead of jumping from 3 to 4, make it more gradual).

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.

Reply #50 Top

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