Here are the letters:
My answers are below, (see RM
.
1. Strategies.txt -
1.1. Increasing the percent of workers dedicated to specialists
increases the impact of PopAssignmentElements. If players are
getting ahead of the AI by using specialists then this change
should help, otherwise it might overbalance the AI toward
specialists.
Reply: Actually, I decreased the number of specialists used, since from my observations with my own cities, you are better off not using specialists unless you have to.
1.2. By setting SliderElement Delta's to 0 you have told the AI to not
try and optimize sliders. When a player has mostly small cities
in the early game (or after getting beaten up) the AI can get a
jump start. However, if you have found cases where the automatic
slider settings are causing problems it might be worth creating
specific strategic states when the sliders get optimized.
WW: This change relates to changes I made in the govern.txt. I made
the per-notch penalties for moving the sliders 4 and -6, since the
1-point penalties were not enough to offset the advantages gained by
maxing out the sliders. Now, it should be like Ctp1, where you only
manipulated the sliders in cases of distress.
RM: If you take a look at my post
http://apolyton.net/forums/Forum35/HTML/000554.html#6)
on apolyton you'll see a simple example of switching strategies based on a SLIC script. You can use the same basic concept to redefine the SliderElement deltas, but with one caveat. You must use the SetStrategicState (see 'Strategic State' section of ai-customization.shtml on Apolyton for why). You could change the slider settings of the base strategic state under specific conditions (like when a civ has only small cities for example).
2. Goals.txt -
2.1. You set the DistanceToHome bonus of the Seige goal to 250. This
number might have more influence than you want since the actual
bonus is computed by multiplying this value by the straight line
distance to the center of the players empire. The
DistanceToEnemy bonus is also computed this way, but all of the
others are normalized so that no goal receives more than the
specified value. For example, the enemy city most threatened by
foreign units will recieve a bonus of 500, and the enemy city
with half of that threat will recieve a bonus of 250. However,
an enemy city 100 cells away will receive a bonus of 25,000
compared to a city half as far will recieve a bonus of 12,500.
Such an out of scale bonus swamps the other bonuses and generally
leads to abnormal goal choices. Values of less than 10 are
advised here unless it's negative. The Chokepoint goal is an
exception since we really only want to guard chokepoints near
home.
Reply: Thanks for the explanation. Here I was trying to get the AIs to prioritize those enemy units/cities closest to its home, in hopes of encouraging the counter-attack ability I mentioned previously. I see now that I was just not figuring the numbers properly, and so I have changed the number from 250 to -10 for both the seige and attack modes. Thanks for seeing this, as it would have screwed up the game.
2.2. GOAL_BOMBARD should not have TargetTypes of both City and
AttackUnit/SpecialUnit. I can't remember exactly how the code
will handle this in all cases. Better to create a new goal,
perhaps GOAL_BOMBARD_ARMY that is identical to GOAL_BOMBARD, but
replaces TargetType:City with TargetType:Army and SpecialUnit.
You'll also have to add this new goal to all of the goal lists in
strategies.txt. Seems you found an oversite here; good catch.
WW: You can add new goals to the strategies.txt? I didn't think you
could add things that weren't already defined in the exe.
RM: Yes! You can add new goals. You'll create a new Goals.txt record and also add a GoalElement reference to it in each of the base strategies in the strategies.txt file. You could, for example, create two different attack goals with different force matching and priorities. The goals are created dynamically based on the attributes in goals.txt and referenced in strategies.txt by their record name in goals.txt.
2.3. FYI, GOAL_SALLY is not used at all and should have been removed.
WW: How about using this goal for the new Bombard_Army goal?
RM: No need really, just create new goals with appropriate names and hook them up.
3. Diplomacy.txt -
3.1. Your changes look reasonable, but I might also suggest that
creating specific diplomatic states is a good way to get leverage
on this aspect of the game. You trigger diplomatic states in a
similar way to how you trigger new strategic states. I can go
into more detail later if you want.
WW: I, and many others, would want more detail, when you get time.
RM: A good general description is available in the 'Diplomatic State' section of ai-customization.shtml on Apolyton. However, the basic idea is that you can define your own diplomacy states (like DIPLOMACY_PROVOKE_WAR in diplomacy.txt) and trigger them to be loaded from the diplomacy.slc file by defining a handler for the NextDiplomaticState event.
RM: You can also redefine specific diplomatic responses and new proposal triggers. The commented out handler in diplomacy.slc titled 'WantGoldAdvance_NewProposalEvent' is an example of how to make the AI consider sending a new proposal with high (1000) priority requesting a desired gold advance.
RM: If you can phrase a change to how the AI responds to a specific new proposal then I can probably tell you how to add a new handler to diplomacy.slc that will implement that change. For example, if you think the AI should never accept a cease fire within 20 turns of getting into a war or something like that, it's pretty easy to do.
1. WW: In the Force Matching section, does the AI include terrain and city
improvement modifiers in its calculations of the matching values, or
does it simply compare unit stats?
RM: The defense and terrain modifiers for a target army or city are
considered, but the terrain modifiers gained by a particular attacker
are not considered because it's not obvious what those bonuses might
be when the attacker gets close enough to attack.
Reply: Thanks for the insight. I seems like a guessing game as to what to set the matching values to. However, since most attacks are made along roads, and roads usually are made through flat terrain (no defense value), then I think it would be wise to assume that the attacker will not have a bonus most of the time.
2. WW: Next, please take a look at my changes to the unit build lists
categories in the Siege, Attack and Defense strategy modes. What I
have done is to let the AI build by using the standard lists in times
of peace, and then shift to specialty lists in times of war. I did
this in the hopes of tailoring the units the AI chooses to build to
better match the situation at that time. This resulted in tripling the
total amount of unit build lists that are listed in the
unitbuildlist.txt. Do you see any problems with doing this?
That looks fine. Good idea!
WW: Finally, would you mind if I posted these letters on the forums?
I would delete your email address, for obvious reasons, and I will
understand if you would rather not do it, or wait until we can covered
more things. Posting these will inform the other mod-makers, and
probably lead to good questions that I have not thought of.
RM: I have no objection to you posting my comments, but I don't want to raise expectations too high. If you want to triage what questions you think are most important to answer, that would be very helpful too. I'll be happy to do what I can to answer any questions I can.
Best wishes,
-- Richard
SECOND LETTER:
Wes,
The remainder of my answers to your questions are below:
WW: Then come the goals settings. I chose 600K as the critical value for the main goals. Settings above 600K are what I want the AIs to prefer in a given situation, and those below 600K should only be chosen if unable to accomplish the higher priorities. I chose 5K as the standard difference between goals. Do you see any problems with these settings?
RM: I think the 5K skip should be ok. The priorities set in the
strategies.txt file specify a base. All of the bonuses specified in
the Goals.txt file are applied to this base priority to come up with
what we call the goals raw priority. You'll notice that all of the
computations needed to compute the bonuses refer to the goal and not
to which particular army is executing the goal. The raw priority is
used to do a first pass sort of the goals which is used when applying
the MaxEval.
RM: All goals of a particular type are sorted based on the raw priority
and only the top MaxEval are matched to the valid armies for that goal
(ie. Attack goal only matches with armies that contain units that
CanAttack). This is purely an efficiency thing, so you can always
increase the MaxEval if you don't care about performance. Be warned
though that increasing this number can seriously impact turn speed for
goals like attack that are executable by many different armies.
RM: For each army matched to a particular goal, a final utility is
computed by taking the raw priority of the goal and applying the
DistanceModifierFactor (from strategies.txt) multipied by the distance
in number of turns the army is from the target of the goal (as the
crow flies, not path length). The number of turns is an approximation
that takes into account how many cells a given unit type can move each
turn. We call the final value the Matching Value for the goal-army
match pair. All matches for all goals are sorted into a big list and
are executed from highest to lowest. Armies can be matched to
multiple goals, but if they have been executed by a higher matching
goal, they won't be executed for any other lower matches that might
exist.
Apolyton question: I am not sure exactly what Richard means with that last sentence, though his example a little ways below with the 5 armies did clear some things up for me.
RM: The reason I say 5K should be ok is that with such a value, goals
will execute mostly based on the raw priorities, but will still use
armies that are far for the action for other things. The MaxExec
parameter from strategies.txt will also ensure that not all armies are
doing the same thing.
WW: Ideally, I want an AI that will shift from one goal
to another if an opportunity presents itself, or if the strength of
the opponent changes suddenly. What I don't want is an AI that is
indecisive, and ends up moving back and forth but never accomplishing
anything. An example of the ideal would be an AI that would
counter-attack and re-take a fallen city if it had a stack strong
enough to defeat the opponent, who is often weakened by his assault.
RM: The AI should take advantage of opportunities as you describe, but
there are many factors that come into play. The best way to tune for
this situation is to create some small test cases using the scenario
editor. Create a reproducable situation where the human can take an
AI city, but lose enough units that the AI should retake the city. By
tweaking the force matching and goal priorities you should be able to
improve the AI's ability.
Apolyton question: This next comment below is a big one, imo.
RM: Another potential problem that may occur is that when the AI units
are tasked, they retain those orders until interrupted or until
certain specific events occur to clear them. You might consider
writing a new slic event handler triggered by the CaptureCity event
that calls the ClearOrder function all on all nearby armies. That
will make sure that they consider attacking the recently captured city
rather than what they might have been tasked to do last turn. Joe's
documentation on events and on the ClearOrder function should make it
clear how to do a brute force version of this that clears all orders.
The downside to clearing all orders every turn is, again, performance.
I considered on the highest difficulty level always clearing orders
every few turns, but never got a chance to implement this.
Apolyton question: Locutus, I believe, had asked before about clearing orders, and I think the above suggests that this is a good idea. What I would want is a trigger to clear all unit orders say, every 3 turns, and another trigger to clear orders whenever an AI civ loses one of its cities. If this is hard to do, then a trigger which makes the seige goal the highest priority whenever a city is lost may work just as well.
WW: Also, would you give me a brief explanation of what triggers the
goals the AI chooses in the game. I *think* I understand their
individual effects pretty well, but I still don't really know what
determines their choices in the first place. I am sure motivations and
desires enters into this, but how does it decide between attack, siege
and harass, for example.
RM: In your example, say you've got 5 armies and 2 of each goal
(attack, siege and harass). Matches will be made between each army
and goal (5 * 2 * 3 = 30 matches). If the attack goal has the highest
raw priority, then all 5 armies will execute attack goals. However,
if the MaxExec for attack is set to 2, then only the 2 highest attack
goals will get armies (as many as are needed to force match).
Assuming one attack goal needs 1 army, and the other need 2 armies,
then you'll have 3 armies left. Those will match to the next highest
goal, which might be seige. If the highest priority seige goal needs
more attack strength than the 3 armies you have, then the goal
will fail. On the next match cycle (there are 6 total match cycles),
the failed goal won't be considered, so the 3 armies will be assigned
to the next highest priority seige goal. If none of the siege goals
can be satisfied by the 3 armies, then the next highest matches might
be to harass goals which need very little matching strength so all
three armies might go to different harass goals.
Apolyton question: I start getting a little confused by the rest of his answer below. If someone could expound upon this, I would appreciate it.
You might see here
another potential source of problems. If there are many seige goals
that require more units than we have the system could run out of match
cycles before any valid goals are found. This is a trade off, and I
wish I had made the match cycles a parameter that could be changed.
But it can't be, so don't ask me. The best way to avoid this is to
make sure the MaxEval for goals that might often need more units than
you have to be low, like 2 or 3. However, if siege is your highest
priority, and you don't have enough units to do a successful seige,
the best bet is to not do anything until you build up your strength.
Apolyton question: I am a little confused by the recommendation to set things at 2 or 3. In the original strategies.txt, the MaxEval and MaxExec are both 25 for the Attack and Harass goals, and around 4 for seige and bombard. Does this mean that the original settings are way off, or am I mis-interpreting Richard's comments?
WW: On the Start strategies, are they determined by personality as far
as Careful or Aggressive? Also, how many turns into the game do they
stay in effect?
RM: Yes, the start strategies are determined by the parameters in the
personalities.txt file. They stay in effect for the whole game, but
you can write triggers that trump them later in the game.
Apolyton question: I definitely need a trigger to disable the start strategies after about 125 turns or so.
WW: On the Explore strategies, what is the difference between Far and
Wide, and what setting determines which of these is used?
RM: In the personalities.txt file (again) each personality has a
Exploration: setting. If Exploration: Minimal is set, then
STRATEGY_EXPLORE_NEAR is used, Exploration: Medium loads
STRATEGY_EXPLORE_FAR and STRATEGY_EXPLORE_WIDE is loaded by
Exploration: Wide. If the Exploration: Wide or Maximum are set, then
STRATEGY_AGRESSIVE_START is used, otherwise STRATEGY_CAREFUL_START is
loaded, btw.
WW: In the Improvement List Production, I added commerce improvements
to that list, and filled out the improvelist.txt to include all the
individual terrain improvements that I wanted the AI to consider. I
restricted the commerce TIs to terrains which could not support farms
or mines, so reduce possible conflicts. Do you see any problems with
this?
RM: Your changes look fine. My one caveat is that there is some logic
that tries to build goalgold improvements preferentially only on cells
that produce gold and not food or production. The logic looks at the
food rank of a cell, and if it's low, looks at the production rank, if
that is low, then it looks at the gold rank, if that's reasonably
high, it tries to build a gold improvement. In retrospect, the logic
should have done the check for whether a food/production improvement
was even possible before considering food/production improvements.
Apolyton question: We will need to keep track of what the AI does in this area during the beta testing.
WW: In the Goal Defend element, would it be wise to up the maxeval and
max execute numbers from 2 and 1 to 4 and 2, respectively?
RM: For the Goal Defend, it's evaluating 2 defend goals *per city* and
executing one per city. They could actually be MaxEval 1 per city and
MaxExec 1 per city since you never have more than one defend goal per
city anyway. The important thing to note is the PerCity tag at the
end of the line.
WW: I changed the fear and desire motivations for all the AI
types. Looking at the ones for the Scientist, for example, do you see
any problems with them? One thing I wanted to address was the fact
that a militarily stronger AI would often not attack the human,
presumably because the human was strong scientifically or financially.
Apolyton question: This answer is very important, imo.
RM: The motivations are only used for computing which new proposals an
AI should make, so I don't think this gets at what you want. If
you want the AI to ignore economic strength when determing if it
should want to be at way, that's tougher. However, if you force the
AI to declare war and make sure the diplomatic state for the AI (in
diplomacy.txt) will refuse peace that should do what you want. So how
do you foce the AI to declare war? Sigh, I have a function to do
this, but I forgot to expose it via SLIC. However, there is a fun way
you can do this. Create a new goal (maybe called
GOAL_PROVOCATION) that looks a lot like an attack goal, but in which
the TargetOwner: is ColdEnemy rather than HotEnemy. This will cause
the AI to preemptively attack, and once at war it will stay at war as
long as it never makes or accepts a ceasefire. You'll have to add the
goal to everyone, but only set it to have maxeval > 0 for beligerent
AI. You could also swap in a strategy specifically that enables this
goal only when the AI has military superiority.
Apolyton question: I would like a trigger to swap in a strategy that enables this goal when they have military superiority. I will set the MaxEval > 0 for Militaristic and Ecotopian AIs.
WW: In the build list sequences, I have made many changes to the
default settings. Please look these over for the Scientist, for
example, and let me know if you see any mistakes I made.
RM: In general these look fine to me, but Dave White (or lead designer)
might have comments about your choices, I'll cc' him on this too.
WW: Finally, at the bottom of the file, there is a list of Defense
Strategies. What triggers these? I know nothing about when they come
into effect, or how long they last.
RM: At the beginning of each turn, the Maximum Threat for an AI is
computed, and as the threat increases, the minimum garrison in each
city increases. Essentially this is a way to make sure the AI
protects its cities with more units when things get more dangereous
later in the game. If you add a new strategic state that is triggered
every turn (with a priority > 1000 or so) which redefines the garrison
counts, then you can use your own system. I forget the actual threat
levels and don't have the code available right now to check when each
level is invoked.
I hope this helps. I look forward to seeing what new and improved AI
strategies you and others will create!
-- Richard
[This message has been edited by WesW (edited February 08, 2001).]
[This message has been edited by WesW (edited February 10, 2001).]