AI setup and usage

From WiCWiki

Revision as of 12:16, 11 December 2007 by kowalski (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

Contents


About AI players

The AI is an invaluable tool when creating fun missions. It can make the fights the player has more vivid and interesting or just used to create ambient fights around the map. The setup of AI’s can be a bit tricky but the effort it takes will be paid back in full by the end results.


Creating a AI-player

In this part we will describe how to create an AI-player. The map europeTest will be used as a frame for all examples. We will do a quick and dirty startup with an already created AI .juice file.

The first thing we have to do is to assign an AI–file to an AI-slot in the singleplayerdata.juice file.

Open up the singleplayerdata.juice file and scroll down to myPlayer. It will look like the following lines. Note that all changes done in juice files can be done in the juice maker as well. However, we will go deeper and explain how to do the changes using a text editor.

myPlayers
{
    PLAYER1
    {
        myType HUMAN
        myTeam TEAM_1
        myAIConfigFile <empty>
    }
    PLAYER2
    {
        myType AI
        myTeam TEAM_1
        myAIConfigFile <empty>
    }
   “More Player will be here.”
}

The first slot – PLAYER1 – is always reserved for the player and should not be changed. So we assign the first AI to slot PLAYER2.

Let us now open up the commanderai map and see what kind of AI we want to use. Go to:

WIC install directory\commanderai\singleplayerais\europeTest.

Hopefully you will find two AI ice files, europeTestrussia_armor.ice and europeTestbannon_armor.ice. We will create an enemy AI and therefore choose the Russian AI. There will be more about team settings later in this chapter.


Now we have to link the AI .ice file into myAIConfigFile, it will look like this:


PLAYER2
{
    myType AI
    myTeam TEAM_1
    myAIConfigFile commanderai/singleplayerais/europeTest/europeTestrussia_armor.ice
}


The time has now come to setup and assign a group to the AI. Open the allunits.py file and create a new function called AISetup. We will add the AI( PLAYER2) to a variable for easy access and for save/load reasons. Open the mapvars.py file and add aiPlayer2Ru = None. Head back to allunits.py and assign the AI to the variable. It should now look like this:

def AISetup():

    mapvars.aiPlayer2Ru = AI( PLAYER2 )
     

The next step is to enable the AI and to disable some of its abilities. Let us start with enabling the AI.

Take the variable you assigned the AI to and put .Enable() to it. Now the AI will be activated in game.

Continue with adding:

mapvars.aiPlayer2Ru.DisableBuy() 
mapvars.aiPlayer2Ru.DisableTA() 

We will not explain the disabled abilities now, they will be talked about later in this tutorial. The AISetup function should now look like this:

def AISetup():

    mapvars.aiPlayer2Ru = AI( PLAYER2 )
    mapvars.aiPlayer2Ru.Enable( )
    mapvars.aiPlayer2Ru.DisableBuy( )
    mapvars.aiPlayer2Ru.DisableTA( )

The basic premises of the AI is now done and the only thing left is units for it to use. The easiest way to give units to the AI is to create a group and assign it to the AI. We will create a group called grpRUDefenseForce and add it to mapvars.py as well.

How to create groups can be found in the chapter about groups and units.

We have chosen to add two medium tanks and a heavy one in this group. The group is created at the commandpoint ‘CP_Mansion’ , because we want the AI to guard this place.

mapvars.grpRUDefenseForce = CreateGroup( 'grpRUDefenseForce ', [ USSR_T62, USSR_T62, USSR_T80U ], 'CP_Mansion', PLAYER_SCRIPT, TEAM_USSR )

The next step is to assign the group to the AI.

Take the variable we assigned the AI to and add:

mapvars.aiPlayer2Ru.AddGroup(mapvars.grpRUDefenseForce). 

It is worth noting that groups that are given to an AI cannot be controlled by script unless they are removed from the AI again.

We will also add reinforcements to this group. The refill orders are given to the group the AI controls. It works the same way as for normal scripted groups, as explained in the chapter about units.

mapvars.grpRUDefenseForce.ActivateRefillMode( 0, 3, [USSR_T62, USSR_T62, USSR_T80U], ‘Mansion_RefillSpot’, 30, None )

The whole AISetup function is now ready to be called from server.py and should look like this:

def AISetup():

    mapvars.aiPlayer2Ru = AI( PLAYER2 )
    mapvars.aiPlayer2Ru.Enable( )
    mapvars.aiPlayer2Ru.DisableBuy( )
    mapvars.aiPlayer2Ru.DisableTA( )
    mapvars.grpRUDefenseForce = CreateGroup( 'grpRUDefenseForce ', [ USSR_T62, USSR_T62, USSR_T80U ], 'CP_Mansion', PLAYER_SCRIPT, TEAM_USSR )
    mapvars.aiPlayer2Ru.AddGroup( mapvars. grpRUDefenseForce )
    mapvars.grpRUDefenseForce.ActivateRefillMode( 0, 3, [USSR_T62, USSR_T62, USSR_T80U], ‘Mansion_RefillSpot’, 30, None )

When called from server.py with allunits.AISetup(), the commandpoint CP_Mansion will now have an AI controlled defense force guarding it.

Useful Methods

There are a lot of methods available to set up the AI. Here are those useful for single player scripts, with examples and explanations.

Enable()

This activates the AI so it will give orders to the units under its control.

Ex.

mapvars.aiPlayer2Ru.Enable( )

Disable()

This deactivates the AI so no orders will be given to the units under its control.

Ex.

mapvars.aiPlayer2Ru.Disable( )

IsEnabled()

This will return a True if AI is Enabled. Ex.

If mapvars.aiPlayer2Ru.IsEnabled():
    #Do this.


Disables the AI if it is Enabled.

Ex.

mapvars.aiPlayer2Ru.Disable( )

RemoveAllUnits()

This removes all the units under the AI’s control. This will give the units control back to the group it belongs. If the units don’t have a group( if the AI has called in own reinforcements ) they will be lost control wise and will not be able to be controlled by scripts nor AI. So the usage of the SetJoinGroup() method is advised to use when using RemoveAllUnits().

ex.

mapvars.aiPlayer2Ru.RemoveAllUnits( )

SetJoinGroup

This method is used to make units that doesn’t belong to a group, when the RemoveAllUnits method is used, to join the set group.

ex.

mapvars.aiPlayer2Ru.SetJoinGroup( mapvars.grpVillageRu2 )

AddGroup( aGroup )

This adds a group to the AI’s control. All groups under a AI’s control will get the same orders. ex.

mapvars.aiPlayer2Ru.AddGroup( mapvars.grpRUDefenseForce )

EnableBuy()

This enables the AI’s ability to buy and call in reinforcements. For this to work the team the AI belongs to need to have a deployment zone assigned, otherwise the game will crash. The AI also needs to have units assigned to it in the *.juice/ *.ice file, in this case the europeTestrussia_armor.juice/europeTestrussia_armor.ice file for the same reason. The process of adding units will be explained later in this chapter.

ex.

mapvars.aiPlayer2Ru.EnableBuy( )

DisableBuy()

This disables the AI’s ability to buy and call in units for itself.

ex.

mapvars.aiPlayer2Ru.DisableBuy( )

EnableTA()

This enables the AI to call down TA. The AI must have tactical aids assigned to it in the AI’s *.ice file, in this case the europeTestrussia_armor.ice file or this will cause a crash.

ex.

mapvars.aiPlayer2Ru.EnableTA( )

DisableTA()

This disables the AI’s ability to call down TA.

ex.

mapvars.aiPlayer2Ru.DisableTA( )    

SetTAZones( someZones )

This sets the areas the AI is allowed to drop TA in. someZones is a list with a position followed by a radius in meters.

ex

mapvars.aiPlayer2Ru.SetTAZones( [ GetPosition(‘aArea1’), 50,  GetPosition(‘aArea2’), 75, GetPosition(‘aArea3’), 40 ] ) 

DropTAUsingMeAsHost( taName, aPosition, aDirection )

This is used to drop a TA with an AI as host. The method will automatically add the TA to the AI and give the AI player 500 TA points. taName is a name of the TA to be used. The list of available TA’s is to be found in install directory\maps\supportweapons.juice. aPosition is the position where to drop the TA. aDirection is the direction from which the TA will hit. This is a directional vector value.

ex.

TADirection =  Vector2Position( GetVector( GetPosition( ‘aArea1’) , GetPosition( ‘aArea2’ ) ) )
DropTAUsingMeAsHost( 'SINGLEPLAYER_DaisyCutter_NATO', GetPosition(‘ aArea1’), TADirection)

SetArtilleryZones( someZones )

This sets areas where the AI is allowed to fire his artillery. someZones is a list with a position followed by a radius in meters.

ex.

mapvars.aiPlayer2Ru.SetArtilleryZones( [GetPosition(‘aArea1’), 150,  GetPosition(‘aArea2’), 175, GetPosition(‘aArea3’), 140 ] )         

EnableSpecialAbilities()

This enables the AI’s ability to use special abilities with the units under its control.

ex.

mapvars.aiPlayer2Ru.EnableSpecialAbilities( )        

DisableSpecialAbilities()

This disables the AI’s ability to use special abilities with the units under its control.

ex.

mapvars.aiPlayer2Ru.DisableSpecialAbilities( )

SetSpecialAbilityOffensiveFactor( anOffensiveFactor )

This sets how often the AI will use the units offensive special abilities. anOffensiveFactor is expressed as a percentage from 0 - 100 %, where 0 means it will never use them and 100 means constant usage.

ex.

mapvars.aiPlayer2Ru.SetSpecialAbilityOffensiveFactor( 50 )

EnableInfantryEnterBuildings()

This will allow the Infantry under the AI’s command to enter buildings.

ex.

mapvars.aiPlayer2Ru.EnableInfantryEnterBuildings( )                  

DisableInfantryEnterBuildings()

This will stop the infantry under the AI’s control to enter buildings.

ex.

mapvars.aiPlayer2Ru.DisableInfantryEnterBuildings( )

Giving orders

The Ai will defend and attack its enemy’s fine without scripting specific orders to it. But sometimes you want the AI to perform a certain task. All orders will move the AI’s units to the designated area. There are three different orders you can give the AI.

These orders will be presented further down, but first some vital parts of these orders will be explained.

Stances

There are two different stances for the AI. Either the AI_STANCE_DEFENSIVE or AI_STANCE_OFFENSIVE.

The AI_STANCE_OFFENSIVE stance was primary created for ambience fights. It will fight hard and making flanking maneuvers, but it will sometimes make irrational decisions.


The AI_STANCE_DEFENSIVE is the default stance. This stance is the one to prefer when giving the AI orders. It behaves more rational then the offensive one and the AI will for example try to recapture command points close to it.

KillZones

KillZones are areas where the AI is allowed to fire upon the enemy. The input in the Killzones is a list of positions followed by a radius.

ex.

aKillZone = [ aPosition1, aRadius1, aPosition2, aRadius2 ]


The AI must have line of sight to a killzone or it may not move at all.


HoldZoneLine( somePositions, aWidth, someKillZones, aUseFlanking, aUseSpreadOut, aUseHeight, aStance )

The HoldZoneLine order will line up the units between two positions and they will defend this line.


somePositions

This list must contain at least two positions for the line to be created. It can have more than two positions.

[ aPosition1, aPosition2 ]


aWidth

This sets width of the line. A too narrow width can sometimes create problems for the AI’s pathfinding.


someKillZones

In a HoldZoneLine order you must define at least one killzone or the game will crash.


aUseFlanking

This is a Boolean value. If set to True the units will try to attack the sides or rear of the enemies.


aUseSpreadOut

This is a Boolean value. If set to True the units will spread out on the line set.


aUseHeight

This is a Boolean value. If set to True the Units will try to gain height advantage.


aStance

Choose one of the two stances. Default is AI_STANCE_DEFENSIVE.


Example.

mapvars.aiPlayer2Ru.HoldZoneLine( [ Getposition( ‘aPos1’ ), GetPosition( ‘aPos2’ ), 30, [ GetPosition( ‘aPos3’ ), 45 ], False, True, True, AI_STANCE_DEFENSIVE )


HoldZone( aZoneCenter, aZoneRadius, someKillZones, aStance )

The HoldZone order will move the AI to the defined area and defend it.

This order is the one mostly used when giving the AI move orders.


aZoneCenter

This is a position. It will be the center of the area the AI will hold.


aZoneRadius

This sets the radius of the area the AI will hold.


someKillZones

The HoldZone order does not require a killzone to work. If set to NONE, they will target and attack all enemies in range.


aStance

Choose one of the two stances. Default is AI_STANCE_DEFENSIVE.


Example.

mapvars.aiPlayer2Ru.HoldZone( GetPosition( ‘aPos’ ), 80, None, AI_STANCE_DEFENSIVE )


HoldCommandPoint( aCommandPoint, aStance )

This order will make the AI to take and hold a specified command point.


aCommandPoint

This is the name(string) of the command point the AI should hold.


aStance

Choose one of the two stances. Default is AI_STANCE_DEFENSIVE.


Example.

mapvars.aiPlayer2Ru.HoldCommandPoint( ‘CP_Site1’, AI_STANCE_DEFENSIVE )

Advanced AI creation

In this section we will create an AI that calls in its own units and who drops TA when given opportunity. To be able to do that we have to start with creating an AI file that allows all that.


In the folder wic\tutorial files\commanderai you can find a file called CLEAN_AI_FILE.juice. Make a copy of the file and rename it to something you will remember. For the tutorial we chose to rename it to UberAI.juice.


Naming your AI

The first thing to do is to add a name to the AI. The name will be shown when hovering with the mouse pointer over the units under the AI’s control. This is not vital for the creation of an AI, but its great for immersion.

In the UberAI.juice file search for myUIName, it’s under Advanced section. There it says <empty>, replace this with the name the name you want AI to have, we chose the name Rasputin for the tutorial. It will display like this in-game:

Image:scripting_AI_001.jpg

This should be a string and it would look something like this.


myUIName Rasputin


Adding buyable units

The next step is to make a list of units the AI can choose from when calling in reinforcements. In UberAI.juice search for myTrees. Then go to the myTree node and down to the myChilds variable. Here you will find the UNITS node. Copy the whole node and paste it under its own myChilds variable. Now rename the pasted node, we rename it to USSR_Heavy_Tank for the tutorial.


Next thing is to start changing the different variables in the newly created node.


These explanations only comply to the variables in the nodes created under the UNITS node:


myNodeName

This is an informative text used for your own sake. We usually put the node name here to. In this case it would be USSR_Heavy_Tank.

myWeight

This is a value setting how preferred this unit will be by the AI. All values in myWeight under the UNITS node will be compared and the unit node with highest value will be bought more often by the AI.


Example:

The USSR_Heavy_Tank node has a myWeight value of 1 and USSR_Medium_Tank has a value of 3. This means that the medium tank will be bought three times more often then the heavy tank.

myManagedAgentType

This is the actual setting/pointer on what unit to be used in this node. The names can be found in the install directory\units\unittypes_wic_singleplayer.juice.


Adding one more unit

Now that we have added heavy tanks to the AI’s buy menu we can go ahead and add one more for practice.


Now copy the USSR_Heavy_Tank node and paste it in the UNITS node variable myChilds, under the USSR_Heavy_Tank node.

Replace all Heavy texts with Medium in this new node. Set myWeight to 3 and change myManagedAgentType to USSR_T62.


The node branch should now look something like this:

DecisionTreeNode myTree
{
    myNodeType BRANCHING_NODE
    myNodeName OvsDBranch
    myWeight 0.0
    myManager AGENT_MANAGER
    myManagedAgentType Root
    myLevel 0
    myChilds
    {
        DecisionTreeNode UNITS
        {
            myNodeType BRANCHING_NODE
            myNodeName OffensiveTankBranch
            myWeight 0.60
            myManager AGENT_MANAGER
            myManagedAgentType ARMOR_ROLE
            myLevel 0
            myChilds
            {
                DecisionTreeNode USSR_Heavy_Tank
                {
                     myNodeType BRANCHING_NODE
                     myNodeName USSR_Heavy_Tank
                     myWeight 1.0
                     myManager AGENT_MANAGER
                     myManagedAgentType USSR_T80U
                     myLevel 0
                     myChilds
                     {
                     }
                 }

                 DecisionTreeNode USSR_Medium_Tank
                 {
                     myNodeType BRANCHING_NODE
                     myNodeName USSR_Medium_Tank
                     myWeight 1.0
                     myManager AGENT_MANAGER
                     myManagedAgentType USSR_T62
                     myLevel 0
                     myChilds
                     {
                     }
               }
           }
       }
   }


Now the AI will be able to order down his own troops. But first add some TA to the AI’s palette of destruction.


Adding Tactical Aid

The way to add TA’s to the AI is made the same way as with units. In UberAI.juice under myTrees you will find a second branch named mySupportWeaponTree. Under the variable named myChilds we list the TAs the AI is allowed to use. We already have a node named TA_BARRAGE here.


Copy the whole TA_BARRAGE node and paste it in it’s own myChilds variable.

Rename the new node to USSR_Heavy_Artillery and put the new name into the variable myNodeName to. Set myWeight to 1 and if myManager does not have OFFENSIVE_SUPPORTWEAPON_MANAGER as a value you will have to make it so.

The strings used to set myManagedAgentType can be found in install directory\maps\supportweapons.juice

There we find the string for heavy artillery barrage and we now can set myManagedAgentType to HeavyArtilleryBarrage_USSR.


The node branch should look something like this.

DecisionTreeNode mySupportWeaponTree
{
    myNodeType BRANCHING_NODE
    myNodeName SupportWeapons
    myWeight 0.0
    myManager OFFENSIVE_SUPPORTWEAPON_MANAGER
    myManagedAgentType SupportWeaponTree
    myLevel 0
    myChilds
{

DecisionTreeNode TA_BARRAGE
{
    myNodeType BRANCHING_NODE
    myNodeName ARMOR_ROLE_BRANCH
    myWeight 0.0
    myManager OFFENSIVE_SUPPORTWEAPON_MANAGER
    myManagedAgentType ARMOR_ROLE
    myLevel 0
    myChilds
    {
        DecisionTreeNode USSR_Heavy_Artillery
        {
            myNodeType BRANCHING_NODE
            myNodeName USSR_Heavy_Artillery
            myWeight 0.0
            myManager OFFENSIVE_SUPPORTWEAPON_MANAGE
            myManagedAgentType HeavyArtilleryBarrage_USSR
            myLevel 0
            myChilds
            {

            }
        }
    }
}


Now if you enable the TA the AI will rain doom upon its enemies.

Creating the AI player

The europeTestrussia_armor.juice file is now complete, and available to use, but there are still some preparations to be done before the AI will work as intended.


The most important thing to add before the AI can operate independently is a dropzone. As described in the chapter about dropzones, the dropzone is necessary to able to order in units. This applies to the AI to, if it is supposed to manage its own reinforcements.

Follow the steps covered in the chapter about dropzones and add a dropzone to the team you want the AI to belong to.


Next we have to add the AI to a player in the singleplayerdate.juice file, as described in the beginning of this chapter. We will add it to the PLAYER3 slot and to TEAM_1. Exactly why we chose TEAM_1 will be explain later in this tutorial.


To make the linking process easy we always have the AI .juice files in the same folder, commanderai\singleplayerais\map name\. If your UberAI.juice is in another location you will have to remember the direction, or move it into the above mentioned folder. You also have to make an .ice file out the .juice file. This because the World in Conflict engine only reads .ice files. This is done by saving the .jucie file in the juicemaker.

Now write the directory to your freshly made .ice file in myAIConfigFile.


PLAYER3
{
    myType AI
    myTeam TEAM_1
    myAIConfigFile commanderai/singleplayerais/europeTest/UberAI.ice
}

When this is done head to the allunits.py file, since its time for the final stages of the AI implementation.

The function made in the beginning of this chapter called AISetup() is going to be used. So if you don’t have it saved, create it now.

The first step here is, like before, to add the AI player to a variable. Primary for save/load reasons, but also to ease things up for ourselves.

Add aiPlayer3Ru = None to mapvars.py and assign AI( PLAYER3 ) to it in allunits.py.


mapvars.aiPlayer3Ru = AI( PLAYER3 )

Next we will enable the AI. We want to make this AI extra “evil”, so enable the usage of special abilities.

mapvars.aiPlayer3Ru.Enable( )
mapvars.aiPlayer3Ru.EnableSpecialAbilities()

Next we will add a DropZone to the Soviet team so the AI can order down his own troops. If this step is neglected the game will crash.

AddDeploymentZoneToTeam( 'DZ_Ussr', TEAM_USSR )

Don’t forget to add a deploymentzone in the europeTest_singleplayerdata.juice file. For more information look in the chapter about deploymentzones.

Finally, we give the AI something to do. This AI will control the Village commandpoint.

mapvars.aiPlayer3Ru.HoldCommandPoint( ‘CP_Village’, AI_STANCE_DEFENSIVE )

The AISetup() function should now look like this.

def AISetup():
     mapvars.aiPlayer2Ru = AI( PLAYER2 )
     mapvars.aiPlayer2Ru.Enable( )
     mapvars.aiPlayer2Ru.DisableBuy( )
     mapvars.aiPlayer2Ru.DisableTA( )
     mapvars.grpRUDefenseForce = CreateGroup( 'grpRUDefenseForce ', [ USSR_T62, USSR_T62, USSR_T80U ], 'CP_Mansion', PLAYER_SCRIPT, TEAM_USSR )
     mapvars.aiPlayer2Ru.AddGroup( mapvars. grpRUDefenseForce )
     mapvars.aiPlayer3Ru = AI( PLAYER3 )
     mapvars.aiPlayer3Ru.Enable( )
     mapvars.aiPlayer3Ru.EnableSpecialAbilities()
     mapvars.aiPlayer3Ru.HoldCommandPoint( ‘CP_Village’, AI_STANCE_DEFENSIVE )

The AI should now be able to call in own troops and will defend the village CP.

Setting teams

Earlier in this chapter we added the AI to TEAM_1 in the mapname_singleplayerdata.juice file.

This is because the AI uses the team settings from the multiplayer part of the map.

If you open up europeTest.juice and head to myMissionStats you can find these lines.

myAllowedTeam1 USSR
myAllowedTeam2 NATO
myAllowedTeam1SinglePlayer NATO
myAllowedTeam2SinglePlayer USSR

Here you can change which teams are allowed for the map.


The two top lines control the multiplayer settings. These two decide what team a certain AI will belong to. We see here that team1 is USSR, thus explaining why the AI was given to TEAM_1 earlier.


The next two lines decides the team settings for the singleplayer mission. The setting in myAllowedTeam1SinglePlayer is the team the player will belong to on this map.

These settings are used by every script that requires team input in singleplayer, except for the ones needed in the AI .juice file of course.

"More human than human" is our motto. :Tyrell in BladeRunner 1982


Chapter 16: Timers < > Chapter 18: Or how we set us up the bomb
Personal tools
User Created Content