Diplomacy AI Development

@Recursive, how come the Celts don't have a penalty to our diplomacy because of differing ideologies? Everyone else does, are there things that nullify it?


Yes, a few things cause them to ignore the penalty. A coop war is one of them, which I'm guessing is the case here.
 
@Recursive I do have a 5 way DP right now, but it is among all Order civs and I think you mentioned that was expected?

Spoiler :

upload_2021-1-26_15-45-11.png

 
Additional diplomacy changes for next version:
Code:
Adjustments to AI "diplo personality" selection and flavor usage
Global politics are more strategic - significantly increased and scaled bonuses and penalties for DoF, DP and denouncement with same/enemy leaders
  Befriending/denouncing/DP'ing the AI's "most valued friend/ally" or "worst competitor/worst World Congress rival" now carries additional opinion weight
Added opinion bonus for previously having a DoF, if there's been no denouncement or DoW or prematurely ended DoF in the interim; stacks up to 3 times
Added customizable timers for most timed opinion modifiers to DiploOpinionWeights.sql
Added a bunch of values controlling Opinion to the database; cleaned up and annotated DiploOpinionWeights.sql for easier use by modders and players
Tweaked the value of some opinion modifiers
Various bugfixes

ilteroi has also fixed a crash and made adjustments to city governor/early expansion logic.
 
On latest version, I played a tall tradition Korea on emperor. Had two civs keep being bribed into warring with me. A Siam that had forward settled me early and never became too big and Persia that steadily started conquering the continent, where we started on opposite ends of the continent. Persia ended up being score leader and a massive autocracy threat. The very odd thing about it however is that even though my military was very under par, they kept agreeing to peace immediately every single time right after 15 turns had passed. One time one my of 4 (thus powerful) cities was like 5 hits away from being taken over. They had like only hate modifiers for me too and it didn't seem to matter that I had pulled all my delegates to make Siam host that one time. They kept on doing this dance of being bribed, peacing out immediately when possible (upon me asking them) and then being bribed again after peace treaty was over.

I should not have won that game and it felt very gamey to me how I won it. I barely managed to survive 15 turns over and over. Persia seemed to be going for domination victory and should have kept going. I also had many wonders in my tradition capital that at one point was quite exposed to Siam, where they should have kept going even though they were probably pursuing DV.

Hope this.is helpful feedback, love the work you do!
 
On latest version, I played a tall tradition Korea on emperor. Had two civs keep being bribed into warring with me. A Siam that had forward settled me early and never became too big and Persia that steadily started conquering the continent, where we started on opposite ends of the continent. Persia ended up being score leader and a massive autocracy threat. The very odd thing about it however is that even though my military was very under par, they kept agreeing to peace immediately every single time right after 15 turns had passed. One time one my of 4 (thus powerful) cities was like 5 hits away from being taken over. They had like only hate modifiers for me too and it didn't seem to matter that I had pulled all my delegates to make Siam host that one time. They kept on doing this dance of being bribed, peacing out immediately when possible (upon me asking them) and then being bribed again after peace treaty was over.

I should not have won that game and it felt very gamey to me how I won it. I barely managed to survive 15 turns over and over. Persia seemed to be going for domination victory and should have kept going. I also had many wonders in my tradition capital that at one point was quite exposed to Siam, where they should have kept going even though they were probably pursuing DV.

Hope this.is helpful feedback, love the work you do!

It is, thank you!
 
What determines the "I consider you a rival in the WC". In my current game I don't even have enough votes to get to select agendas and I'm getting that penalty.
 
What determines the "I consider you a rival in the WC". In my current game I don't even have enough votes to get to select agendas and I'm getting that penalty.

It's generally based on whether they think you'll support their interests, not how much voting power you have.

This is not the precise calculation used right now, but it's the one the AI will use in the next version (and relatively close, minus the new vassal stuff):

(When calculating the opinion penalty, bIgnoreWar = true, bNoAutomaticMasterAlignment = false)

There is one exception to this: AIs who are competing for victory and going for diplo victory will consider the player not on their team with the highest vote count their "prime league competitor" ("greatest rival in the World Congress"), regardless of the alignment. Alignment is only used to tiebreak if players have the same vote count.

AIs who are not competing for victory or not going for diplo victory will apply this penalty instead to the player with the worst alignment, using the higher vote count to tiebreak.

(Note: If two players have both the same alignment and the same vote count, the player with the worst opinion score is considered the greater rival)
Code:
// Calculate how much we think our interests are aligned with ePlayer, based on ideology, liberation, past voting patterns, etc.
CvLeagueAI::AlignmentLevels CvLeagueAI::EvaluateAlignment(PlayerTypes ePlayer, bool bIgnoreWar, bool bNoAutomaticMasterAlignment)
{
   int iAlignment = 0;

   if (ePlayer == NO_PLAYER)
   {
       return ALIGNMENT_NEUTRAL;
   }
   if (!GET_PLAYER(ePlayer).isAlive())
   {
       return ALIGNMENT_NEUTRAL;
   }
   if (GET_PLAYER(ePlayer).isMinorCiv())
   {
       return ALIGNMENT_NEUTRAL;
   }
   if (GetPlayer()->GetID() == ePlayer)
   {
       return ALIGNMENT_SELF;
   }
   if (GetPlayer()->GetDiplomacyAI()->WasResurrectedBy(ePlayer))
   {
       return ALIGNMENT_LIBERATOR;
   }
   if (GetPlayer()->getTeam() == GET_PLAYER(ePlayer).getTeam())
   {
       if (GET_TEAM(GetPlayer()->getTeam()).getLeaderID() == ePlayer)
       {
           return ALIGNMENT_LEADER;
       }
       else
       {
           return ALIGNMENT_ALLY;
       }
   }
   if (GET_TEAM(GetPlayer()->getTeam()).isAtWar(GET_PLAYER(ePlayer).getTeam()))
   {
       if (!bIgnoreWar)
       {
           return ALIGNMENT_WAR;
       }
       else
       {
           if (GET_PLAYER(ePlayer).GetDiplomacyAI()->IsAggressor(GetPlayer()->GetID()))
           {
               iAlignment -= 2;
           }
           else
           {
               iAlignment -= 1;
           }
       }
   }

   CvDiplomacyAI* pDiplo = GetPlayer()->GetDiplomacyAI();
   bool bUntrustworthy = pDiplo->IsUntrustworthy(ePlayer);

   // Ideology
   PolicyBranchTypes eOurIdeology = GetPlayer()->GetPlayerPolicies()->GetLateGamePolicyTree();
   PolicyBranchTypes eTheirIdeology = GET_PLAYER(ePlayer).GetPlayerPolicies()->GetLateGamePolicyTree();
   if (eOurIdeology != NO_POLICY_BRANCH_TYPE && eTheirIdeology != NO_POLICY_BRANCH_TYPE)
   {
       int iIdeologyMod = 0;

       if (eOurIdeology == eTheirIdeology && !bUntrustworthy)
       {
           iIdeologyMod += 2;
       }
       else if (!pDiplo->IsIgnoreIdeologyDifferences(ePlayer))
       {
           iIdeologyMod -= 2;
       }

       CvLeague* pLeague = GC.getGame().GetGameLeagues()->GetActiveLeague();
       if (pLeague != NULL)
       {
           // Is this the World Ideology?
           if ((pLeague->GetPressureForIdeology(eOurIdeology) > 0) || (pLeague->GetPressureForIdeology(eTheirIdeology) > 0))
           {
               iIdeologyMod *= 2;
           }
       }

       // Are either of us a vassal?
       if (GetPlayer()->IsVassalOfSomeone())
       {
           iIdeologyMod /= 2;
       }
       if (GET_PLAYER(ePlayer).IsVassalOfSomeone())
       {
           iIdeologyMod /= 2;
       }

       iAlignment += iIdeologyMod;
   }

   // Religion
   ReligionTypes eOurReligion = GetPlayer()->GetReligions()->GetCurrentReligion(false) != NO_RELIGION ? GetPlayer()->GetReligions()->GetCurrentReligion(false) : GetPlayer()->GetReligions()->GetReligionInMostCities();
   ReligionTypes eTheirReligion = (GET_PLAYER(ePlayer).GetReligions()->GetCurrentReligion(false) != NO_RELIGION && GC.getGame().GetGameReligions()->HasAnyDomesticCityFollowing(GET_PLAYER(ePlayer).GetReligions()->GetCurrentReligion(false), ePlayer)) ? GET_PLAYER(ePlayer).GetReligions()->GetCurrentReligion(false) : GET_PLAYER(ePlayer).GetReligions()->GetReligionInMostCities();
   if (eOurReligion != NO_RELIGION && eTheirReligion != NO_RELIGION)
   {
       int iReligionMod = 0;

       if (eOurReligion == eTheirReligion && !bUntrustworthy && !pDiplo->IsHolyCityCapturedBy(ePlayer))
       {
           iReligionMod += 1;
       }
       else if (!pDiplo->IsIgnoreReligionDifferences(ePlayer))
       {
           iReligionMod -= 1;
       }

       // Is this the World Religion?
       if ((GC.getGame().GetGameLeagues()->GetReligionSpreadStrengthModifier(ePlayer, eTheirReligion) > 0) || (GC.getGame().GetGameLeagues()->GetReligionSpreadStrengthModifier(GetPlayer()->GetID(), eOurReligion) > 0))
       {
           iReligionMod *= 2;
       }

       iAlignment += iReligionMod;
   }

   // Did they help us become host?
   if (pDiplo->GetSupportedMyHostingScore(ePlayer) != 0)
   {
       iAlignment += 2;
   }

   // Do we like their proposals or votes?
   if (pDiplo->GetLikedTheirProposalScore(ePlayer) < 0)
   {
       iAlignment += 2;
   }
   else if (pDiplo->GetDislikedTheirProposalScore(ePlayer) > 0)
   {
       iAlignment -= 2;
   }

   // Have they supported our proposals?
   int iSupportedOurProposalScore = pDiplo->GetSupportedOurProposalScore(ePlayer);
   if (iSupportedOurProposalScore > 0)
   {
       if (pDiplo->IsFoiledOurProposalAndThenSupportedUs(ePlayer))
       {
           iAlignment -= 1;
       }
       else
       {
           iAlignment -= 2;
       }
   }
   else if (iSupportedOurProposalScore < 0)
   {
       if (pDiplo->IsSupportedOurProposalAndThenFoiledUs(ePlayer))
       {
           iAlignment += 1;
       }
       else
       {
           iAlignment += 2;
       }
   }

   // DoF or Denounce
   if (pDiplo->IsDenouncedPlayer(ePlayer) || pDiplo->IsDenouncedByPlayer(ePlayer))
   {
       iAlignment -= 2;
   }
   else if ((pDiplo->IsDoFAccepted(ePlayer) || pDiplo->IsWantsDoFWithPlayer(ePlayer)) && !pDiplo->IsWantsToEndDoFWithPlayer(ePlayer))
   {
       switch (pDiplo->GetDoFType(ePlayer))
       {
       case DOF_TYPE_FRIENDS:
           iAlignment += 1;
           break;
       case DOF_TYPE_ALLIES:
           iAlignment += 2;
           break;
       case DOF_TYPE_BATTLE_BROTHERS:
           iAlignment += 3;
           break;
       }
   }

   // Defensive Pact?
   if (pDiplo->IsHasDefensivePact(ePlayer) && !pDiplo->IsWantsToEndDefensivePactWithPlayer(ePlayer))
   {
       iAlignment += 1;
   }

   // Current vassal?
   if (pDiplo->IsVassal(ePlayer))
   {
       VassalTreatmentTypes eTreatmentLevel = pDiplo->GetVassalTreatmentLevel(ePlayer);

       if (pDiplo->IsVoluntaryVassalage(ePlayer))
       {
           switch (eTreatmentLevel)
           {
           case VASSAL_TREATMENT_CONTENT:
               if (bNoAutomaticMasterAlignment)
                   iAlignment += 4;
               else
                   return ALIGNMENT_LEADER;
               break;
           case VASSAL_TREATMENT_DISAGREE:
               if (bNoAutomaticMasterAlignment)
                   iAlignment += 2;
               else
                   return ALIGNMENT_ALLY;
               break;
           case VASSAL_TREATMENT_MISTREATED:
               if (bNoAutomaticMasterAlignment)
                   iAlignment -= 2;
               else
                   return ALIGNMENT_NEUTRAL;
               break;
           case VASSAL_TREATMENT_UNHAPPY:
               iAlignment -= bNoAutomaticMasterAlignment ? 3 : 2;
               break;
           case VASSAL_TREATMENT_ENSLAVED:
               iAlignment -= bNoAutomaticMasterAlignment ? 5 : 3;
               break;
           }
       }
       else
       {
           switch (eTreatmentLevel)
           {
           case VASSAL_TREATMENT_CONTENT:
               if (bNoAutomaticMasterAlignment)
                   iAlignment += 2;
               else
                   return ALIGNMENT_ALLY;
               break;
           case VASSAL_TREATMENT_DISAGREE:
               if (bNoAutomaticMasterAlignment)
                   iAlignment -= 1;
               else
                   return ALIGNMENT_NEUTRAL;
               break;
           case VASSAL_TREATMENT_MISTREATED:
               iAlignment -= bNoAutomaticMasterAlignment ? 4 : 2;
               break;
           case VASSAL_TREATMENT_UNHAPPY:
               iAlignment -= bNoAutomaticMasterAlignment ? 5 : 3;
               break;
           case VASSAL_TREATMENT_ENSLAVED:
               iAlignment -= bNoAutomaticMasterAlignment ? 10 : 5;
               break;
           }
       }
   }
   else
   {
       // Previous vassalage?
       if (pDiplo->IsMasterLiberatedMeFromVassalage(ePlayer))
       {
           iAlignment += 2;
       }
       else if (pDiplo->IsHappyAboutPlayerVassalagePeacefullyRevoked(ePlayer))
       {
           iAlignment += 1;
       }
       else if (pDiplo->IsAngryAboutPlayerVassalageForcefullyRevoked(ePlayer))
       {
           iAlignment -= 1;
       }
   }

   // Competing for City-States?
   if (pDiplo->GetMinorCivDisputeLevel(ePlayer) >= DISPUTE_LEVEL_STRONG || pDiplo->GetNumTimesPerformedCoupAgainstUs(ePlayer) > 0)
   {
       iAlignment -= 2;

       // Big deal if we're diplomatic...
       if (pDiplo->IsCompetingForVictory() && (GetPlayer()->GetPlayerTraits()->IsDiplomat() || pDiplo->IsDiplomat() || pDiplo->GetVictoryFocus() == VICTORY_FOCUS_DIPLOMATIC))
       {
           iAlignment -= 4;
       }
   }

   // Opinion and approach
   switch (pDiplo->GetMajorCivOpinion(ePlayer))
   {
   case MAJOR_CIV_OPINION_UNFORGIVABLE:
   case MAJOR_CIV_OPINION_ENEMY:
       iAlignment -= 2;
       break;
   case MAJOR_CIV_OPINION_COMPETITOR:
       iAlignment -= 1;
       break;
   case MAJOR_CIV_OPINION_NEUTRAL:
       iAlignment += 0;
       break;
   case MAJOR_CIV_OPINION_FAVORABLE:
   case MAJOR_CIV_OPINION_FRIEND:
       iAlignment += 1;
       break;
   case MAJOR_CIV_OPINION_ALLY:
       iAlignment += 2;
       break;
   }

   switch (pDiplo->GetMajorCivApproach(ePlayer))
   {
   case MAJOR_CIV_APPROACH_WAR:
   case MAJOR_CIV_APPROACH_HOSTILE:
       iAlignment -= 2;
       break;
   case MAJOR_CIV_APPROACH_DECEPTIVE:
   case MAJOR_CIV_APPROACH_GUARDED:
       iAlignment -= 1;
       break;
   case MAJOR_CIV_APPROACH_AFRAID:
   case MAJOR_CIV_APPROACH_NEUTRAL:
       iAlignment += 0;
       break;
   case MAJOR_CIV_APPROACH_FRIENDLY:
       iAlignment += 1;
       break;
   }

   // Backstabber?
   if (bUntrustworthy)
   {
       iAlignment -= 2;

       // A personal betrayal is worse!
       if (pDiplo->IsFriendDeclaredWarOnUs(ePlayer) || pDiplo->IsFriendDenouncedUs(ePlayer) || pDiplo->IsPlayerBrokenVassalAgreement(ePlayer) || pDiplo->IsResurrectorAttackedUs(ePlayer))
       {
           iAlignment -= 2;
       }
       else if (pDiplo->IsPlayerBrokenMilitaryPromise(ePlayer) || pDiplo->IsPlayerBrokenAttackCityStatePromise(ePlayer))
       {
           iAlignment -= 1;
       }
   }
   // Liberator?
   else if (pDiplo->IsPlayerLiberatedCapital(ePlayer) || pDiplo->IsPlayerLiberatedHolyCity(ePlayer))
   {
       if (!pDiplo->IsCompetingForVictory() && !bUntrustworthy && !GetPlayer()->IsAtWarWith(ePlayer))
       {
           return ALIGNMENT_LIBERATOR;
       }

       iAlignment += 2;
   }
   else if (!bUntrustworthy && !GetPlayer()->IsAtWarWith(ePlayer))
   {
       if (pDiplo->IsPlayerReturnedCapital(ePlayer) || pDiplo->IsPlayerReturnedHolyCity(ePlayer))
       {
           iAlignment += 1;
       }
       if (pDiplo->GetNumCitiesLiberatedBy(ePlayer) > 0 && pDiplo->GetNumCitiesCapturedBy(ePlayer) <= 0)
       {
           iAlignment += 1;
       }
   }

   // Captured some of our cities before?
   if (pDiplo->GetNumCitiesCapturedBy(ePlayer) > 0)
   {
       iAlignment -= pDiplo->GetNumCitiesCapturedBy(ePlayer);
   }

   AlignmentLevels eAlignment = ALIGNMENT_NEUTRAL;
   if (iAlignment < -6)
   {
       eAlignment = ALIGNMENT_ENEMY;
   }
   else if (iAlignment < -4)
   {
       eAlignment = ALIGNMENT_HATRED;
   }
   else if (iAlignment < -1)
   {
       eAlignment = ALIGNMENT_RIVAL;
   }
   else if (iAlignment <= 1)
   {
       eAlignment = ALIGNMENT_NEUTRAL;
   }
   else if (iAlignment <= 4)
   {
       eAlignment = ALIGNMENT_FRIEND;
   }
   else if (iAlignment <= 6)
   {
       eAlignment = ALIGNMENT_CONFIDANT;
   }
   else
   {
       eAlignment = ALIGNMENT_ALLY;
   }
   return eAlignment;
}
Code:
--   //////////////////////////////////////
--   // WORLD CONGRESS
--   //////////////////////////////////////

-- They consider us an ally in the World Congress.
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_LIBERATOR', '-25';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_ALLY', '-20';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_CONFIDANT', '-15';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_FRIEND', '-10';

-- (values for Diplomat AIs)
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_LIBERATOR_DIPLOMAT', '-50';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_ALLY_DIPLOMAT', '-40';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_CONFIDANT_DIPLOMAT', '-30';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_FRIEND_DIPLOMAT', '-20';

-- They consider us a rival in the World Congress.
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_RIVAL', '10';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_HATRED', '15';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_ENEMY', '20';

-- (values for Diplomat AIs)
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_RIVAL_DIPLOMAT', '20';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_HATRED_DIPLOMAT', '30';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_LEAGUE_ALIGNMENT_ENEMY_DIPLOMAT', '40';

-- We are their greatest rival in the World Congress.
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_PRIME_LEAGUE_COMPETITOR', '25'; -- if this is true, above modifiers are ignored
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_PRIME_LEAGUE_COMPETITOR_DIPLOMAT', '50'; -- value for Diplomat AIs
 
Last edited:
Additional diplomacy changes for next version:
Code:
Opinion and approach penalties for dispute modifiers now scale with difficulty level, making the AI progressively more aggressive about land, City-States etc. as difficulty rises (AIDeclareWarProb), using the following scale:
- Settler: 50% of normal penalties
- Chieftain: 60%
- Warlord: 70%
- Prince: 80%
- King: 90%
- Emperor: 100%
- Immortal: 112.5%
- Deity: 125%

This affects:
- Territorial disputes
- Wonder competition disputes
- City-State competition disputes
- Victory disputes
- Cultural/scientific advancement disputes
- Reckless expander penalty
- Wonder spammer penalty

- Multiple humans at different difficulty levels in multiplayer will now use the correct AIDeclareWarProb and AIHumanStrengthMod values (AIs use the game value towards each other)

- The penalties above now also scale with leader flavors:
- Territorial disputes (Boldness)
- Wonder competition (WonderCompetitiveness)
- City-State competition (MinorCivCompetitiveness)
- Victory disputes (VictoryCompetitiveness)
- Cultural/technological advancement disputes (DiploBalance)
- Reckless expander penalty (Boldness)
- Wonder spammer penalty (WonderCompetitiveness)

If flavor > 5, increase penalty by (flavor - 5) * 20%
If flavor < 5, decrease penalty in the same way

Bonuses to approach for non-competition also benefit from this in the same way
 
Sorry Recursive, but just to clarify since the joint-war rework: If agreeing to a delayed joint-war (10 turns), it is intended that due to instigation or opportunism, your ally (or yourself) can still attack the target preemptively? If so, is the counter nullified for both parties, or will the other participant still be auto triggered into the war once the 10 turns hit? I would assume the behaviour is normal and the counter simply disappears, allowing the other participant to either join whenever or not engage at all.
 
Sorry Recursive, but just to clarify since the joint-war rework: If agreeing to a delayed joint-war (10 turns), it is intended that due to instigation or opportunism, your ally (or yourself) can still attack the target preemptively? If so, is the counter nullified for both parties, or will the other participant still be auto triggered into the war once the 10 turns hit? I would assume the behaviour is normal and the counter simply disappears, allowing the other participant to either join whenever or not engage at all.

Auto-triggers for both parties if war is declared preemptively.
 
Auto-triggers for both parties if war is declared preemptively.
Hmm, so you still have to really be on your toes despite requesting some prep time. I'll be sure to note that the agreement truly is binding, and I thank you for making that switch to prevent any exploitation or grey area.
 
Hmm, so you still have to really be on your toes despite requesting some prep time. I'll be sure to note that the agreement truly is binding, and I thank you for making that switch to prevent any exploitation or grey area.

You can still cancel by ending your DoF early, denouncing or declaring war on your ally, or befriending/DP'ing the target.

In the future I will add a button you can use to cancel coop war commitments under Discuss.

All of these options, of course, come with a hefty diplomacy penalty.
 
France asked me for a mutual war on Brazil, I said give me 10 turns, but he declared war himself (I checked the DPs, it had to be on Brazil unless he somehow got bribed into declaring on two civs) without dragging me into war.

Using modpack, so you won't be able to load my saves.

Last 1-15 hotfix, I think.
 
France asked me for a mutual war on Brazil, I said give me 10 turns, but he declared war himself (I checked the DPs, it had to be on Brazil unless he somehow got bribed into declaring on two civs) without dragging me into war.

Using modpack, so you won't be able to load my saves.

Last 1-15 hotfix, I think.

If this happens again in 2-4 please post a bug report with logs. I can't find what's causing that but I added code which should trace it to the logs.
 
If this happens again in 2-4 please post a bug report with logs. I can't find what's causing that but I added code which should trace it to the logs.
Was able to isolate it and posted to Git for you to hopefully nullify. Thanks again for your amazing diligence!
 
For next version:
Code:
Added proper gamespeed scaling to all remaining timed opinion modifiers
- Recent trade
- Recent diplomatic actions
- Common foe bonus
- Vassal protection/failed to protect
- Killing/capturing civilians
- Digging up artifacts

Removed more useless memory values

Moved "turns at war/peace" counters to CvPlayer, no idea why that was put in the diplomacy AI
 
I settled a city Ohrid on the other side of my territory and Korea asks me not to settle close to them. How do they calculate it?
 

Attachments

  • 8930_20210210203630_1.png
    8930_20210210203630_1.png
    2.6 MB · Views: 40
I settled a city Ohrid on the other side of my territory and Korea asks me not to settle close to them. How do they calculate it?

This is a new feature whereby the AI will get mad at the player who stole "their" favorite settling spot.

But it needs some tweaking...
 
AI is still more than happy to throw away his best cities in a deal involving a declaration of war.

In this particular example, the issue is exacerbated by the fact Suleiman asked me to join a coop war against Indonesia 9 turns ago, and I agreed asking for 10 more turns to prepare. Hence, the next turn I'd be involved in the war no matter what.
If I ask for a coop war he refuses outright (again, the next turn we'd go war together), while this is the sort of deal he can give me if I go war on my own, at turn 100. Fwiw, trading for his pop 4 minor cities results in an impossible deal.

Spoiler :
civwardec.png


I simply avoid going for these sort of deals but it's gamebreaking if you ask me; I also think AI should never trade away cities in a deal that's not war reparations, nor accept them from a player (that's the easy way to go through the last turns for peaceful victories).
 
Back
Top Bottom