Difference between revisions of "Development:AIScripts"

From VsWiki
Jump to: navigation, search
Line 41: Line 41:
  
 
Lets take a look at an example:
 
Lets take a look at an example:
<hull max=".03" script="drop cargo" time="1" priority="8">                       
+
  <hull max=".03" script="drop cargo" time="1" priority="8">                       
  <hull max=".03" script="afterburn turn away" time="10" priority="8">           
+
    <hull max=".03" script="afterburn turn away" time="10" priority="8">           
  </hull>                                                                       
+
    </hull>                                                                       
</hull>                                                                         
+
  </hull>                                                                         
 
This says if the hull is at most .03 and the hull is at most .03 drop cargo for a second and then turn away for 10 seconds with a priority of 8
 
This says if the hull is at most .03 and the hull is at most .03 drop cargo for a second and then turn away for 10 seconds with a priority of 8
 
nested script actions are conjoined together and if all their conditions evaluate to true they are performed in sequence.
 
nested script actions are conjoined together and if all their conditions evaluate to true they are performed in sequence.
Line 50: Line 50:
  
 
Lets fish up a little more complex example:
 
Lets fish up a little more complex example:
<hull max=".6" script="evade up down" time="4" timetointerrupt="3" priority="7">                                                                               
+
  <hull max=".6" script="evade up down" time="4" timetointerrupt="3" priority="7">                                                                               
  <fshield max=".25" script="evade up down" time="1" timetointerrupt="0" priority="7">                                                                         
+
    <fshield max=".25" script="evade up down" time="1" timetointerrupt="0" priority="7">                                                                         
    <rand max=".13" script="evade up down" time=".5" timetointerrupt="0" priority="7"/>                                                                         
+
      <rand max=".13" script="evade up down" time=".5" timetointerrupt="0" priority="7"/>                                                                         
  </fshield>                                                                  
+
    </fshield>                                                                    
</hull>       
+
  </hull>       
  
 
This translates into:  if the hull is at most at 60% strength, the forward shields are at most 25% and the random number generator selects a number with 13% probability then evade up and down for 4 seconds, 3 of which are uninterruptible, then evade up and down for another 1.5 seconds which are interruptible
 
This translates into:  if the hull is at most at 60% strength, the forward shields are at most 25% and the random number generator selects a number with 13% probability then evade up and down for 4 seconds, 3 of which are uninterruptible, then evade up and down for another 1.5 seconds which are interruptible
Line 63: Line 63:
 
Collision Avoidance:
 
Collision Avoidance:
  
<meterdistance max="30" script="afterburn turn away" time="7" timetointerrupt="3" priority="6">                                                                 
+
  <meterdistance max="30" script="afterburn turn away" time="7" timetointerrupt="3" priority="6">                                                                 
    <rand min=".4" script="afterburn fly straight" time=".5" timetointerrupt="1" priority="6"/>                                                                 
+
      <rand min=".4" script="afterburn fly straight" time=".5" timetointerrupt="1" priority="6"/>                                                                 
</meterdistance>                                                                 
+
  </meterdistance>                                                                 
 
                    
 
                    
  
Line 76: Line 76:
 
The script that needs to be interrupted by the above script follows later in the file:
 
The script that needs to be interrupted by the above script follows later in the file:
  
<meterdistance min="60" max="500" script="turn towards itts" priority="4" time="5">                                                                             
+
  <meterdistance min="60" max="500" script="turn towards itts" priority="4" time="5">                                                                             
  <meterdistance max="500" script="turn towards" priority="4" time="8">         
+
    <meterdistance max="500" script="turn towards" priority="4" time="8">         
  <rand min=".5" script="loop around" priority="4" time="5">                   
+
    <rand min=".5" script="loop around" priority="4" time="5">                   
  </rand>                                                                       
+
    </rand>                                                                       
  </meterdistance>                                                               
+
    </meterdistance>                                                               
</meterdistance>     
+
  </meterdistance>     
 
This says "if the distance is between 60 and 500, is at most 500 and the random number generator gives a number that has probability 50% then turn towards the target, giving it itts lead if available, then turn towards it without lead, then loop around it.  Notice that this script is entirely interruptible if the AI ever gets within 30--and since the priority is lower than 6, it will indeed be overridden by the afterburn turn away listed above.  But the above script is essentially the bread and butter of the AI--it directs it to turn towards its opponent and shoot like crazy (the shooting is handled in C code right now)
 
This says "if the distance is between 60 and 500, is at most 500 and the random number generator gives a number that has probability 50% then turn towards the target, giving it itts lead if available, then turn towards it without lead, then loop around it.  Notice that this script is entirely interruptible if the AI ever gets within 30--and since the priority is lower than 6, it will indeed be overridden by the afterburn turn away listed above.  But the above script is essentially the bread and butter of the AI--it directs it to turn towards its opponent and shoot like crazy (the shooting is handled in C code right now)
  
 
Another important facet of this attacking part of the AI is to have something that's true in all conditions...this means including a fallback that happens if the random number fails like so:
 
Another important facet of this attacking part of the AI is to have something that's true in all conditions...this means including a fallback that happens if the random number fails like so:
  
<meterdistance min="60" max="500" script="afterburn veer away" priority="4" tim\
+
  <meterdistance min="60" max="500" script="afterburn veer away" priority="4" tim\
 
e="2">                                                                           
 
e="2">                                                                           
  <meterdistance max="500" script="turn towards" priority="4" time="8">         
+
    <meterdistance max="500" script="turn towards" priority="4" time="8">         
  </meterdistance>                                                               
+
    </meterdistance>                                                               
</meterdistance>       
+
  </meterdistance>       
  
 
and also some things to do if far away:
 
and also some things to do if far away:
  
 
<!-- meterdistance far out-->                                                   
 
<!-- meterdistance far out-->                                                   
<meterdistance min="500" script="barrel roll" time="2" timetointerrupt="1">     
+
  <meterdistance min="500" script="barrel roll" time="2" timetointerrupt="1">     
  <fshield max=".1"  script="barrel roll" time="1">                             
+
    <fshield max=".1"  script="barrel roll" time="1">                             
  </fshield>                                                                     
+
    </fshield>                                                                     
</meterdistance>                                                              
+
  </meterdistance>                                                                
<meterdistance min="500" script="barrel roll" time="2" timetointerrupt="1">     
+
  <meterdistance min="500" script="barrel roll" time="2" timetointerrupt="1">     
  <bshield max=".1"  script="barrel roll" time="1">                             
+
    <bshield max=".1"  script="barrel roll" time="1">                             
  </bshield>                                                                     
+
    </bshield>                                                                     
</meterdistance>                                                                 
+
  </meterdistance>                                                                 
<meterdistance min="500" script="afterburn turn towards itts" priority="4" time="3">                                                                           
+
  <meterdistance min="500" script="afterburn turn towards itts" priority="4" time="3">                                                                           
</meterdistance>     
+
  </meterdistance>     
  
  

Revision as of 02:41, 16 August 2008

Vega Strike has completely programmable python AI scripts--but often times just editing an XML file with a list of actions at various distances and probabilities is sufficient and quite a bit more performant

AI scripts are selected as follows: the following two excel files in the ai/ folder are consulted ai/VegaEvents.csv The VegaEvents file is a table mapping combat_roles of the attacker to roles of his target. Combat roles are stored in the Combat_Role column in units.csv For instance if my starship is a BOMBER and I am targeting a BASE then vega strike will look in row BOMBER and column BASE and find the beginning of the name of the AI script thus it would be bomber.* where * might be .agg.xml or .civ.xml depending on the next file:

ai/VegaPersonalities.csv VegaPersonalities is a list of a factions and what AI scripts they wish to use Each listed faction is followed by a comma and then by a space separated list of extensions to use on their AI script. so if bomber was selected from VegaEvents.csv and the faction is merchant which has the second column "scared scared civ" there will be a 1/3 chance that bomber.civ.xml will be selected, otherwise bomber.scared.xml will be selected

if the file is not found bomber.agg.xml will be searched then default.civ.xml then default.agg.xml (I believe .py files are also searched)


Once an XML file is selected, it is parsed every frame to select an AI behavior for the starship to use when attacking its target. AI scripts are selected as follows: the following two excel files in the ai/ folder are consulted ai/VegaEvents.csv The VegaEvents file is a table mapping combat_roles of the attacker to roles of his target. Combat roles are stored in the Combat_Role column in units.csv For instance if my starship is a BOMBER and I am targeting a BASE then vega strike will look in row BOMBER and column BASE and find the beginning of the name of the AI script thus it would be bomber.* where * might be .agg.xml or .civ.xml depending on the next file:

ai/VegaPersonalities.csv VegaPersonalities is a list of a factions and what AI scripts they wish to use Each listed faction is followed by a comma and then by a space separated list of extensions to use on their AI script. so if bomber was selected from VegaEvents.csv and the faction is merchant which has the second column "scared scared civ" there will be a 1/3 chance that bomber.civ.xml will be selected, otherwise bomber.scared.xml will be selected

if the file is not found bomber.agg.xml will be searched then default.civ.xml then default.agg.xml (I believe .py files are also searched)


Once an XML file is selected, it is parsed every frame to select an AI behavior for the starship to use when attacking its target

The XML file selected has a simple format <AggressiveAI time="7"> is the header it tells the AI script how often to search for scripts and must be paired with a </AggressiveAI> at the very end of the file Between this header and footer is a list of actions that the AI is allowed to perform, each tagged by conditions that enable them to be selected and a priority to help the computer choose an action to perform

Lets take a look at an example:

 <hull max=".03" script="drop cargo" time="1" priority="8">                      
   <hull max=".03" script="afterburn turn away" time="10" priority="8">          
   </hull>                                                                       
 </hull>                                                                         

This says if the hull is at most .03 and the hull is at most .03 drop cargo for a second and then turn away for 10 seconds with a priority of 8 nested script actions are conjoined together and if all their conditions evaluate to true they are performed in sequence. Noticed in the above example we specified the hull being at most .03 *twice* so that the condition would be evaluated in the same manner both times---this simply enables us to tell the computer to perform those two actions in sequence so that the AI computer does not drop all cargo at once but only drops cargo every 10 seconds and runs away

Lets fish up a little more complex example:

 <hull max=".6" script="evade up down" time="4" timetointerrupt="3" priority="7">                                                                               
   <fshield max=".25" script="evade up down" time="1" timetointerrupt="0" priority="7">                                                                         
     <rand max=".13" script="evade up down" time=".5" timetointerrupt="0" priority="7"/>                                                                        
   </fshield>                                                                     
 </hull>       

This translates into: if the hull is at most at 60% strength, the forward shields are at most 25% and the random number generator selects a number with 13% probability then evade up and down for 4 seconds, 3 of which are uninterruptible, then evade up and down for another 1.5 seconds which are interruptible

This timetointerrupt parameter can ensure that an AI is not constantly shifting between decisions but instead actually follows through on an action. It can help the AI "commit" to finishing a task instead of being interrupted--and hence should be used with caution with scripts that could cause collision--because a collision-imminent decision (as we shall see in a bit) needs to interrupt other choices with a high priority


Collision Avoidance:

 <meterdistance max="30" script="afterburn turn away" time="7" timetointerrupt="3" priority="6">                                                                
     <rand min=".4" script="afterburn fly straight" time=".5" timetointerrupt="1" priority="6"/>                                                                
 </meterdistance>                                                                
                 

This part of the script says: if the distance is at most 30 meters (this is adjusted for speed and acceleration) then turn around for 7 seconds (3 of those are uninterruptible) and then fly away for another half second. This would hopefully direct an AI to avoid a collision instead of playing chicken with a human (or computer ) opponent

However all of the scripts we have talked about before have a higher priority, so they're not considered interruptible with this particular command.. .however the above commands also move the ship AWAY from the target---so they aren't really the type of thing that could result in an intentional collision

Attacking Script: The script that needs to be interrupted by the above script follows later in the file:

 <meterdistance min="60" max="500" script="turn towards itts" priority="4" time="5">                                                                            
   <meterdistance max="500" script="turn towards" priority="4" time="8">         
    <rand min=".5" script="loop around" priority="4" time="5">                   
    </rand>                                                                      
   </meterdistance>                                                              
 </meterdistance>    

This says "if the distance is between 60 and 500, is at most 500 and the random number generator gives a number that has probability 50% then turn towards the target, giving it itts lead if available, then turn towards it without lead, then loop around it. Notice that this script is entirely interruptible if the AI ever gets within 30--and since the priority is lower than 6, it will indeed be overridden by the afterburn turn away listed above. But the above script is essentially the bread and butter of the AI--it directs it to turn towards its opponent and shoot like crazy (the shooting is handled in C code right now)

Another important facet of this attacking part of the AI is to have something that's true in all conditions...this means including a fallback that happens if the random number fails like so:

 <meterdistance min="60" max="500" script="afterburn veer away" priority="4" tim\

e="2">

   <meterdistance max="500" script="turn towards" priority="4" time="8">         
   </meterdistance>                                                              
 </meterdistance>      

and also some things to do if far away:

 <meterdistance min="500" script="barrel roll" time="2" timetointerrupt="1">    
   <fshield max=".1"  script="barrel roll" time="1">                             
   </fshield>                                                                    
 </meterdistance>                                                                 
 <meterdistance min="500" script="barrel roll" time="2" timetointerrupt="1">    
   <bshield max=".1"  script="barrel roll" time="1">                             
   </bshield>                                                                    
 </meterdistance>                                                                
 <meterdistance min="500" script="afterburn turn towards itts" priority="4" time="3">                                                                          
 </meterdistance>     



Now as you may have noticed there are a lot of descriptions in script

script can be a python script (which executes turns, or fire commands, etc) or an XML script located in the scripts folder, but for the most part those scripts should simply be precanned ones that I've written in the Vega Strike C code

the prebaked scripts are listed as follows:

 loop around fast                            
 aggressive loop around fast        
 loop around slow                             
 aggressive loop around slow        
 loop around                                      
 aggressive loop around                 
 barrel roll                                      
 veer away                                         
 veer away itts                                
 veer and turn away                        
 veer and vector away                      
 afterburn veer away                
 afterburn vector away           
 match velocity                               
 fly straight                                   
 fly straight afterburner
 afterburn fly straight
 do nothing
 take off
 coast to stop
 self destruct
 take off every zig
 afterburn turn towards
 afterburn turn towards itts
 cloak
 evade
 kick stop
 move to
 shelton slide
 skilled afterburner slide
 afterburner slide
 stop
 turn away
 afterburn turn away
 turn towards
 turn towards itts
 drop cargo
 drop half cargo
 drop one cargo
 roll right
 roll right hard
 roll left
 roll left hard
 evade left right
 evade up down
 afterburn evade left right
 afterburn evade up down

For a description of what each of these do see hard_coded_scripts.cpp