No announcement yet.

AI Customization


  • AI Customization

    AI Customization

    Following is a description of how to use the AI SLIC functions available in Call to Power II to customize the behavior of AI players and the mayors that can control human cities.

    Getting Started

    You should create a new scenario that will include the modifications you make. Specific directions for creating a new scenario can be found below in Appendix A. Most of the files that you will modify to make AI changes can be found in the default\aidata subdirectory of your scenario. You will also create/modify the scenario.slc file in the default\gamedata subdirectory of your scenario.

    Strategic State

    The parameters defined in the strategies.txt file are used to control almost every aspect of how an AI controls their empire and tasks their units. The details of what each parameter does has been described elsewhere; the purpose of this section is to explain how to change these parameters to customize the game.

    The strategic state of each player (AI or human) is initialized when the game begins based on hard coded rules that load one of the six default strategies (see table 1). You can specify a different default strategy to initialize a player with by defining a SLIC function that handles the InitStrategicState event. For example:

    HandleEvent (InitStrategicStateEvent) ‘Example_StrategicStateInit’ post
    // player[0] contains the player being initialized
    // code that ends up calling VOID SetStrategicState(player, strategyDBindex)

    You can also change the initial strategic state after the game has begun by resetting the strategic state from within a SLIC function that handles the NextStrategicState event and calls the SetStrategicState function.

    You can also define any number of SLIC functions to handle the NextStrategicState event that modify situation dependent elements of a player’s strategic state. For example, if you wanted the AI to completely stop building settlers when they had built 20 cities, you would create a function that tests the current number of cities, and when the number exceeded 20 calls the ConsiderStrategicState function to load a new strategy record in which the SettlerUnitsCount is set to 0. Changing the strategy for the human player affects the behavior of the Mayors that can be used to control the players’ cities (see APPENDIX B).

    When a new strategy is "considered" using ConsiderStrategicState, parameters defined by the new strategy record overwrite the values defined in the base strategy (set by SetStrategicState). As strategies are merged in values are overwritten in an order determined by their priority; lower priority strategic state records being overwritten by records that were considered with a higher priority. In this way you can have two handlers fire that load strategy records that modify the same parameter. The changes caused by the strategy record with the higher priority will be the one used.

    Not all parameters can be changed using the ConsiderStrategicState function. The following structure elements are only changed by a SetStrategicState function call: PopAssignmentElement elements, the order of Government elements and SliderElement elements.

    The following structure elements are merged based on the primary reference in the structure: GoalElement elements and BuildListSequenceElement elements. In the former case, the elements will overwrite all existing elements with the same Goal field; see the STRATEGY_ATTACK record for an example that redefines only the GoalElement elements defined for GOAL_DEFEND, GOAL_SEIGE, GOAL_ATTACK, GOAL_HARASS, GOAL_BOMBARD, GOAL_HARASS_CITY and GOAL_PILLAGE. The latter case is similarly redefined, except for being keyed on the BuildListSequence field.

    Diplomatic State

    The parameters in the diplomacy.txt file are used to define unique parameters for how each AI player reacts diplomatically to each other player in the game. Unlike strategic states, each player maintains multiple diplomatic states that define their relationship with each foreigner. Also unlike strategic states, diplomatic states are taken all or nothing. After all diplomatic states have been considered in a turn, only the one with the highest priority is used. However, a diplomatic state might define other states that it inherits from in order reduce the redundancy in diplomatic state records. If the Inherit field is set, then the referenced diplomacy record is loaded first and the current record is merged in overwriting any variables that it redefines.

    The initial diplomatic state record load for a player can be redefined by writing a SLIC function that handles the InitDiplomaticState event and calls ConsiderDiplomaticState followed by a call to ChangeDiplomaticState. For example:

    HandleEvent (InitDiplomaticState) ‘Example_DiplomaticStateInit’ post
    // player[0] is the player being initialized
    // player[1] is the foreigner
    // code that ends up calling ConsiderDiplomaticState
    // code that calls ChangeDiplomaticState

    At the beginning of every turn the NextDiplomaticState event will be triggered for every foreigner that has been contacted. You can define SLIC functions to handle this event and change which diplomacy record should be loaded by calling the ConsiderDiplomaticState function. Do not call the ChangeDiplomaticState function from within these handlers; it will be called after all handlers have been executed and cause a change to the one with the highest priority.

    HandleEvent (NextDiplomaticState) ‘Example_NextDiplomaticState’ pre
    // player[0] is the player being whose turn it is
    // player[1] is the foreigner
    // code that ends up calling ConsiderDiplomaticState


    At the beginning of every player turn the ReactionMotivation and possibly one or both of the FearMotivation or DesireMotivation events will be triggered. To add a rule which can trigger the sending of a new proposal you should write a SLIC function to handle one of these events. For simplicity it is best to write your handles to be triggered by the ReactionMotivation event. For all of these events, player[0] is the player whose turn it is, and player[1] is the foreigner that would receive the new proposal.

    You should access the current diplomacy state for the player using the GetNewProposalPriority function and also call any other functions needed to determine whether or not the player should send a particular new proposal. If it is determined that the proposal should be sent, then call the function ConsiderNewProposal. If multiple calls to ConsiderNewProposal are made, then the proposal with the highest priority will be sent.

    If an AI has received a new proposal, then the NewProposal event will be triggered. You should write functions to handle this event and respond to it. The parameter player[0] will be the player that sent the proposal and player[1] will be the player that received it. You should call the functions GetLastNewProposalType, GetLastNewProposalArg and GetLastNewProposalTone to figure out how to respond; other functions might also be useful when deciding how to respond. You should use the function ConsiderResponse if you wish to accept or counter the new proposal. By default the new proposal will be rejected. If multiple calls to ConsiderResponse are made then the response with the highest priority will be sent.

    If an AI has received a response to their new proposal other than accept, then the Counter event will be triggered if the receiver of the proposal countered or a Reject event if they rejected it outright. The parameter player[0] will be the player that sent the original new proposal and player[1] will be the player that was the original receiver. You should call the functions GetLastResponseType, GetLastCounterResponseType, GetLastCounterResponseArg before determining how to respond to a counter proposal or rejection. You can then call the ConsiderResponse function (with the receiver and sender id’s swapped if accepting or rejecting) to respond. You can also call ConsiderResponse to threaten.

    If an AI has received a threat from a proposal sender, then the Threaten event will be triggered. The parameter player[0] will be the player that send the original new proposal and player[1] will be the player that was the original receiver. You can call the GetLastNewProposal* and GetLastResponse* functions to determine how to respond to a threat. You can then call the ConsiderResponse function to accept or reject the original proposal after a threat.

    All diplomacy event handler functions should be of type pre so that multiple responses or new proposals can be considered before selecting one to be sent.


    The personality.txt file defines parameters that are used to determine which strategic state and diplomatic states will automatically be used for each AI player. As a mod maker you can call the function GetPersonalityType to determine the personality of a particular player and then use the DB accessor functions built into SLIC2 to determine the settings of a particular personality. These personality settings are used as a reference by other parts of the system but do not alone have direct control over how the AI behaves. Just because you give an Evil personality to an AI does not mean it will “act evil.” You also should define strategic and diplomatic event handlers that check for this personality setting and load in strategic and diplomatic states that cause evil behaviors.

    Table 1: Player initialization strategies based on personality.

    APPENDIX A – How to create a Mod Pack

    From Joe Rumsey’s November 29th description on Apolyton:

    This is a good opportunity to describe the right way to make a mod pack. The first step is to create a new "scenario" using the editor: Open the editor and click Save Scenario. Click the New button, and fill in the details for the new mod pack (which may contain multiple mods, but will only contain one for this example.) Click OK, and then click New again (you should be viewing an empty list of scenarios before clicking New the second time.) Fill in the details for the new scenario. At this point, you will have a complete pack and scenario, which if loaded will have no effect at all on gameplay.

    So now it's time to change something. There are two parts to Richard's PW mod, a change to strategies.txt and an added event handler. To change strategies.txt, you need to first replicate the standard version in your mod. Assuming you named your mod pack directory "PWModPack", find it in [installdir]/scenarios/PWModPack. Inside that, there will be a scen0000 directory. Inside the scen0000 directory, you can recreate any part of the standard data. For this example, you need to create .../PWModPack/scen0000/default/aidata/strategies.txt. The "default" directory should already exist (creating the scenario created it) but you need to make the aidata directory. Then copy the standard strategies.txt into that directory, and add to it Richard's suggested record.

    Finally, open .../PWModPack/scen0000/default/gamedata/scenario.slc (which should already exist as an empty file) and copy the event handler to it.

    Then to play your Mod, just click the Select Scenario button on the launch screen, and choose it like you would any scenario.

    Just to finish this with an example of how to distribute a mod, I've zipped up everything needed for this mod and placed the zip here. If you unzip this to [installdir]/scenarios (which should create a directory named [installdir]/scenarios/PWModPack), you'll have everything you need to play this mod.

    APPENDIX B – Example of using SLIC to customize the Mayor system

    The scripting system can be used to customize the game. Begin by creating a new scenario tree (see APPENDIX A) and put a copy of the standard strategies.txt file in the default\aidata\ subdirectory of the scenario. Also create a new scenario.slc file in the default\gamedata subdirectory of the scenario.

    This example will show how to change the game so mayors will use PW only if there is over 5000 stored. To do this, we need to change the currently loaded strategy for the player so that the PublicWorksReserve field is set to 5000. The solution would be to add a new strategy record to the end of the scenarios strategies.txt that looks like:

    PublicWorksReserve 5000

    When this strategy record is loaded, it will increase the public works reserve so that mayors (or AI) will only spend PW that is above this limit.

    You must then use SLIC to load this strategy explicitly for human players. This should be done by adding to the new scenario.slc the following event handler:

    HandleEvent(NextStrategicState) 'ChangeHumanMayorStrategy' pre
    // Increase PW reserve for human players

    int_t db_index;

    int_t ss_priority;

    db_index = StrategyDB(STRATEGY_LARGE_PW_RESERVE);

    ss_priority = 500;

    if (db_index >= 0 && IsHumanPlayer(player[0]))
    ConsiderStrategicState(player[0], ss_priority, db_index);

    Attached Files
      Posting comments is disabled.

    Article Tags


    Latest Articles


    • CTP tga picture sizes
      by Caranorn
      Until today I was convinced there were only 3 sizes for the tga files 160 x 120, 32 x 24 and 24 x 18. But the large pictures used for units appear to be 96 x 72. This might explain some of the bad quality of the pictures in game (if the game has to scale them down). The uniticon.txt obviously uses 4 entries for icons (2 are identical), so I tried to enter a 96 x 72 tga instead of one of the UPUPXXXL.TGA files and it does work. However, I guess this requires additional space for the files, but probably this gives better quality of game icons and possibly even improves speed...
      December 25, 2011, 16:47
    • Setting Trust and Regard in CTP2 scenarios
      by Immortal Wombat
      I would like to do a SCENARIO. where things have already happened you know.
      Are there some place to read about how to define regard,- trust,- startyear,- cost of researches and that kind of stuff?

      Answer: The questions you have asked are really two things. You can alter scenarios by changing the text files, and more abstract stuff has to be done by SL...
      December 25, 2011, 14:51
    • CTP II map editor manual
      by Immortal Wombat

      1. Cut Map Area
      2. Copy Map Area
      3. Paste Map Area

      - These work much like any such cut, copy and paste buttons in painting programs. To use them, you first have to select an area of the map using button 13, see below. Having selected a map region, you can cut it (copies it to the 'clipboard' and replaces with shallow ocean), copy it (copies to the 'clipboard' but remains present also. Once it is on the 'clipboard', you can paste the region by selecting the paste button (#3) and clicking a tile which you wish to become the TOP LEFT tile of the pasted region.

      4. save map area.
      -I never use this. I guess it's so you can save a segment from one map you make. why? (see #8)

      5. Small brush size. One tile at a time
      6. Medium brush size. I dunno, maybe 9 at a time.
      7. Large brush size. Something like 25 or 36 at a time.

      8. load map area.
      -Cunning, no? You can now load the segment (that you saved from one map in #4) into another.

      9. Set Map 'Explored'
      - All players see the map as fully explored. I think this saves into the scenario, otherwise it works no difference from button #16.

      10. Set Map 'Unexplored'
      - Opposite of #9

      11. X-wrap on/off.
      - i.e. do the sides of the map connect in the game?

      12. Y-wrap on/off
      - i.e. do the top and bottom of the map connect?

      - Displays the co-ordinates of the tile your cursor is hanging over.

      13. Select portion of the map
      - As used with buttons 1,2 and 3. Simply click the tile you want at a corner of the chosen region, then drag across to the opposite corner of the region and let go.

      14. Eraser.
      - Works like a paintbrush, but turns everything to default terrain (shallow water)

      15. Reset Map
      - Covers the whole map in shallow water.

      16. Reveal Map
      - duh...

      17. Reload Slic
      - You won't need this for map design, but it reloads the SLIC files that you may have changed while modding.

      18. Locate!
      - Type in a set of x and y co-ordinates, and press locate to center the map on them.

      19. Remove all Goods
      - Removes all goods...

      20. Generate Goods
      - Generates goods at random across the map. Different seeding pattern on each click.

      21. Hut
      - Place a hut on the map, or remove one by clicking this button, then clicking the hut.

      22. River.
      - As above, but with rivers, not huts.

      23-26. Place goods
      - Place (or remove) goods on the map. Most terrains only have 2 goods, so only the first two buttons work. Some mods allow the other 2 to work as well.
      Button 1 places the first good for that terrain, button 2 will place a different one (but will firstly remove the first good, click again to add the second - it doesn't replace. if that makes any sense...)

      27. Toggle Pollution on/off

      28. Map Size.
      Select the map size you want. This will reload the map as a blank all-sea map, so copy any regions you want to keep.

      29. Difficulty
      - Select one of the 6 difficulty levels.

      30. Barbarians.
      - Select one of the 4 barbarian levels.

      31. Date Roller
      - Change the year in the game by scrolling backwards and forwards.

      32. Save Map
      - Save the map to a map file. Then you can reload it later, or publish it, or something.

      33. Load Map
      - So you can continue working on it I guess. You have to have saved it first.

      34. Save scenario.
      - Save the whole scenario (map, rules, etc. ) to a scenario file, which you are asked to place in the scenario structure. Select the scenario fo your choice, and click save. The press 'back' outwards.

      December 25, 2011, 14:15
    • EditPlus: updated SLIC-definitions, new CTP2-DB-definitions
      by BureauBert
      Why not get back to CTP2-modding just to enjoy the luxury of syntax highliting in EditPlus?
      • for SLIC (Locutus' SLIC-definitions file updated for CTP2 AE)
      • for CTP2 AE database files (a brand new definitions file)

      I will keep updating both files as long as the Source Code Project is going on with the Information I can find in the AE Modding Wiki (or somewhere else, but preferably there).

      The EditPlus definitions for CTP2 AE database structures are currently supporting all files in \default\gamedata and \default\aidata. I will see how much I can do for the string files, but I intend to integrate at least some highliting support for editing the Great Library. Personally, I like browsing the textfiles with syntax highliting -- I can see clearly now .

      I will eventually post updates here (not too frequently though).

      Please don't hesitate to post your suggestions and complaints .

      • Requires: EditPlus
      • copy the zipped files into the EditPlus program folder
      • open EditPlus, open the menu Tools > Preferences
      • go to "Settings and Syntax"
      • hit the "Add" button
      • for SLIC enter a description like "SLIC", file extension "slc", the syntax file is "slic.stx", the auto completion file is "slic.acp" and the function pattern file is "slic.ctl"
      • for the database defintions enter a description like "CTP2 DB", the file extension is "txt" (which might be a bit annoying if you use EditPlus for other textfiles and if you frequently use words like "InvaderMovementRegardCost" in your notes ), there is just a syntax file "ctpdb.stx"
      January 29, 2011, 18:53
    • CTP1 Sprite List for CTP2 modders
      by Martin Gühmann
      The following is a list of the units sprites that existed in CTP1 and are not now in CTP2. To be more specific, the units are not in the game, but Activision left the sprites for use in mods. Here is the list...
      December 10, 2010, 20:19
    • AI Customization
      by Martin Gühmann
      AI Customization

      Following is a description of how to use the AI SLIC functions available in Call to Power II to customize the behavior of AI players and the mayors that can control human cities.

      Getting Started

      You should create a new scenario that will include the modifications you make. Specific directions for creating a new scenario can be found below in Appendix A. Most of the files that you will modify to make AI changes can be found in the default\aidata subdirectory of your scenario. You will also create/modify the scenario.slc file in the default\gamedata subdirectory of your scenario.
      December 10, 2010, 19:42