Missionaries and Inquisitors new logic

tu_79

Deity
Joined
Feb 11, 2016
Messages
7,376
Location
Malaga (Spain)
Hi everyone.

Ilteroi has requested some help in designing a new logic for missionaries and inquisitors. So, let's try to help him in this thread. Remember that the AI has no crystal ball to predict the next turn, so it can only works with whatever is currently going on in the present turn.

My logic scheme:
1. Choosing the religious stance and queue purchases.
2. Managing Great Prophets.
3. Managing Inquisitors.
4. Managing Missionaries.

1.1 Reading context. Here AI just maps each religion in sight: How many cities are under that religion control, how much pressure it exert over the map, making a difference between pressure over already converted cities and pressure over contested cities or cities that follow a different religion.

1.2 Evaluate threats and opportunities. Strengths and weaknesses.
Opportunities to convert are easy. For every city, get the following facts:
A) How long it would take for a missionary purchased in the closest religious city to reach destination and how much strength it might lose in the way (passing through unfriendly territory).
B) How many citizens would turn to followers by a missionary spread action once he arrives, accounting the effect of external religious pressure.
C) How much religious pressure would the city gain (expected minus current), if it can be known.
D) Whether this religion would become major in the city or another religion would lose major status in the city.

Then order this list first by the change of majority religion status (gain majority > others lose it > nothing). This is, a city that will gain my religion as majority will take precedence over a city that just might lose the majority for other religion, and both will take precedence over a city that will not change its majority. Next, order it by the number of citizens that will turn to followers. For example, a city that would turn 4 people to followers and become majority will be converted before another city that would turn 6 people to followers but gain no majority. Next, order by the amount of religious pressure the city will gain. This usually can only be known of owned cities. So if I can convert two cities and both will turn 6 people to followers but one of the cities has a temple, the city with the temple goes first. And finally order by the expected turns until next newborn, so everything equal, cities that are about to grow get converted first.
Now we know how many cities are good targets (gain religion for us), acceptable targets (others will lose religion in one action), or bad ones (turning over requires effort). This list is to be used by our missionaries, but the amount of good targets will be useful to know the opportunities too.

For threats we must identify two risks:
+ Being attacked by foreign missionaries and prophets. It depends on whether our neighbours have their own religion, how close their cities are, but mostly it depends on the percentage of citizens in the city that are not followers since they are easier to convert.
+ Being overwhelmed by foreign religious pressure. If the foreign pressure is relatively much higher than the own.
Then build a list with our cities ordered by the highest risk (for our inquisitors) and a second list with the foreign cities that are threatening our cities the most (for our great prophets).

For strengths we must look at our civ toolkit (is there anything that makes our religion stronger?), look at what things we have that gives us an edge at the religious game (resources that yield faith, policies, beliefs, an early religion). Weaknesses is just looking the strengths of our rivals, especially the closer ones.

1.3 Choosing the strategic stance.
Now it's time to decide one of the following stances:
+ Aggressive spread. We have a big advantage and there are more opportunities than risks. Go converting those cities before anyone else does. Extra Great Prophets might gain more cities to the faith but should be used in cities with presence of other religions. Connect every city with roads if you have not done it yet.
+ Defensive. We have an advantage but risks are higher than opportunities. Enhance and place inquisitors in your cities, extra Great Prophets go to sacred places.
+ Cautious spread. We are weaker, but we still can get some profits before confrontation. Invest in Great Prophets for enhancing earlier, place inquisitors in the border cities and religious buildings to keep a decent defense.
+ Surrender. We are weaker and there are more risks than opportunities, so let's use our resources for other more useful things such as great people.

1.4 Choosing the next item in queue.
Agressive spread will produce missionaries while the opportunities are still high. Once opportunities are little and risk are still low, faith goes to great prophet, religion buildings or other purchases in this order.
Cautious spread will produce first a great prophet for enhancing, then religious buildings for extra religious strength, then missionaries while the opportunities are still high.
Defensive will produce inquisitors while there are cities at risk without inquisitors, then save for great prophets.
Surrender will avoid producing religious units, faith is to be expended in religious buildings and other purchases.


Points 2, 3 and 4 are more or less already handled, but maybe they could make use of the produced ordered lists in the steps above.
 
Another thing that might help to increase diversity is to have the religious queue selection to have some chance of choosing other things.
Say that we have an aggressive stance and our model says that we should produce a missionary. But we have 3 options, missionary, saving for great prophet or purchasing a monastery. Then, instead of simply ordering a missionary, we can make missionaries being chosen three times more often. Instead of 33% chance each item, it would be 60% chance for missionary, 20% for saving for a GP and 20% for the monastery. That way, AI can make wrong choices, but that would be mostly right when taken in bulk.
 
sorry if there was a misunderstanding but i did not say i would implement arbitrarily complex schemes.

please try to keep it simple and changes minimal. ideally refer to the current implementation (search for BuyMissionaryOrInquisitor in the code)
 
designing a new logic for missionaries and inquisitors
Just to let you know that i'm already tired with insane GP attacks.
(Costly) inquisitors should bring a better protection.
I'd like to see more benefits from Faith-Purchase Buildings and faith diversity.
 
BuyMissionaryOrInquisitor
Sure.
In what file?

EDIT. Found it.
Code:
// check whether a missionary or an inquisitor is better
bool CvReligionAI::BuyMissionaryOrInquisitor(ReligionTypes eReligion)
{
    //missionaries for easy targets first
    if (HaveNearbyConversionTarget(eReligion, false, true))
        return BuyMissionary(eReligion);

    //inquisitors second
    if (!HaveEnoughInquisitors(eReligion))
        return BuyInquisitor(eReligion);

    //now missionaries for all targets
    if (HaveNearbyConversionTarget(eReligion, true, false))
        return BuyMissionary(eReligion);

    return false;
}
Code:
// Is there a civ nearby that isn't pressing religion?
bool CvReligionAI::HaveNearbyConversionTarget(ReligionTypes eReligion, bool bCanIncludeReligionStarter, bool bHeathensOnly) const
{
    UnitTypes eMissionary = m_pPlayer->GetSpecificUnitType("UNITCLASS_MISSIONARY");
    int iMissionaryMoves = GC.getUnitInfo(eMissionary)->GetMoves();
    int iMaxRange = iMissionaryMoves * GC.getRELIGION_MISSIONARY_RANGE_IN_TURNS();

    for(int iPlayer = 0; iPlayer < MAX_CIV_PLAYERS; iPlayer++)
    {
        PlayerTypes ePlayer = (PlayerTypes)iPlayer;
        if (m_pPlayer->IsAtWarWith(ePlayer))
            continue;

        CvPlayer& kPlayer = GET_PLAYER(ePlayer);
        bool bStartedOwnReligion = (kPlayer.GetReligionAI()->GetReligionToSpread() > RELIGION_PANTHEON);
        if (bStartedOwnReligion && !bCanIncludeReligionStarter)
            continue;

        int iLoop;
        for(CvCity* pCity = kPlayer.firstCity(&iLoop); pCity != NULL; pCity = kPlayer.nextCity(&iLoop))
        {
            if (m_pPlayer->GetCityDistanceInPlots(pCity->plot()) > iMaxRange)
                continue;

            if (bHeathensOnly)
            {
                CvCityReligions* pRel = pCity->GetCityReligions();
                if (pRel->GetReligiousMajority() != eReligion)
                {
                    int iHeathens = pRel->GetNumFollowers(NO_RELIGION) + pRel->GetNumFollowers(RELIGION_PANTHEON);
                    int iPopMinusTrueReligion = pCity->getPopulation() - pRel->GetNumFollowers(eReligion);

                    //conversion targets should be the majority, ignore cities which already have significant presence from other religions
                    if (iHeathens < iPopMinusTrueReligion / 2)
                        continue;
                }
            }

            if (m_pPlayer->GetReligionAI()->ScoreCityForMissionary(pCity, NULL, eReligion) > 0)
                return true;
        }
    }

    return false;
}
Code:
bool CvReligionAI::CanHaveInquisitors(ReligionTypes eReligion) const
{
    UnitClassTypes eUnitClassInquisitor = (UnitClassTypes)GC.getInfoTypeForString("UNITCLASS_INQUISITOR");
    if(eUnitClassInquisitor != NO_UNITCLASS && m_pPlayer->GetPlayerTraits()->NoTrain(eUnitClassInquisitor))
        return false;

    if (m_pPlayer->GetPlayerTraits()->IsReconquista() && m_pPlayer->GetPlayerTraits()->IsForeignReligionSpreadImmune())
        return false;

    UnitTypes eInquisitor = m_pPlayer->GetSpecificUnitType("UNITCLASS_INQUISITOR");
    CvUnitEntry* pkUnitInfo = GC.getUnitInfo(eInquisitor);
    const CvReligion* pMyReligion = GC.getGame().GetGameReligions()->GetReligion(eReligion, m_pPlayer->GetID());
    if (pMyReligion == NULL || pkUnitInfo == NULL)
        return false;
    if (pkUnitInfo->IsRequiresEnhancedReligion() && !pMyReligion->m_bEnhanced)
        return false;

    return true;
}

This makes the AI decide if it saves faith for enhancing:
Code:
bool bWantToEnhance = ((!bHaveEasyTargets || iDesireToSpread < 1) && bAllConvertedCore && IsProphetGainRateAcceptable()) || bTooManyMissionaries;
 
Last edited:
1.2 should be a focus. Converting something strategically is great, but spending one extra turn to not loose half your missionary strength in someone's borders is better. Can a pathfinding logic that values not losing strength over speed be implemented?
 
1.2 should be a focus. Converting something strategically is great, but spending one extra turn to not loose half your missionary strength in someone's borders is better. Can a pathfinding logic that values not losing strength over speed be implemented?

Honestly, I kinda wish we could drop attrition altogether and balance around that. There's plenty of micromanagement already
 
Well, I'll try to summarize what the code is doing.
First it checks if the conditions for enhancing are good (no owned heathen cities and little benefits from spreading outside) and saves faith for the GP. This means that the very first thing it will do is to convert non puppet heathen cities. This is not what I would do every time. I'd rather enhance first if there are nearby religious foreign cities.
Second it will check if it is better to save faith for great people.
Third, it will try to convert owned non puppet cities. For this purpose, it will check what unit is better right now. In this order, it will produce a missionary if there are owned cities without religion. If all owned non puppet cities are converted, it will produce inquisitors until the amount is enough (*). Then, after the amount of inquisitors is enough, it will produce missionaries again while there are owned cities that are not heathen but can still be converted.
Fourth, it will focus on puppet cities and repeat what it did with non puppet cities.
Fifth, it will check for foreign cities and will decide depending on our civ flavour and whether the neighbor has religious cities.

(*) That's what can be modified if we want to see more inquisitors, I guess.

I still think that it can be a good idea to set a chance for choosing one or other item, so when it needs a missionary it builds a missionary 80% of times or something like that.
 
A few problems with current implementation.
1. AI will never enhance until all core cities are converted, unless it has too many missionaries that it can't use for some reason.
I would enhance earlier if my civ is not very good at spreading, since the enhancer might help with that. I would enhance earlier if my first follower belief were a religious building. I would enhance earlier if my neighbours are already exerting pressure over my cities.
2. When available, it always produces religious units in the Holy City, instead of the closest one to the target.
3. I don't find any logic related to the target city size or the amount of heathen people in the target city, the ones that are easier to convert. I would score higher the owned cities that will become converted upon missionary action since that will enable the follower beliefs. I would also score for every heathen in the target city, since heathens are easier to convert. A city with 5 heathens is better than a city with 2 heathens.
4. Distance is scored, but free borders is not accounted for. My usual tactic is to use the last spread action in a non free border city.
5. It would build every religious building in owned cities before attempting to convert foreign cities. This is not optimal. Being the first to convert a non founder is a plus, not only for civs with a bonus for spreading, but just as a buffer.
6. CvReligionAI::HaveEnoughInquisitors is wrong. We don't need one inquisitor for every city that is not following our religion, we need a few inquisitors standing in border cities too as a defense. They stand against enemy spreading and might be needed fast.

Let there be also a small chance of not purchasing the intended item, and purchase the next item instead. This small randomness will make things more interesting for everyone.
 
You have put a lot of thought into the mechanics.

I usually approach religion in different way. I just dont care. I conquer them holy cities. I dont care about wonders. I just annex wonders for free. I dont even care about religion. I conquer everything
 
1) yes, attrition seems to be yet another AI-unfriendy micromechanic we could do without. it's easy to remove if there is a consensus.
2) adding a random element is also easy, but the AI logic is already quite complex, so the results look quite random to an outside observer.
3) right now there are two independent functions allowing or preventing missionary use (ScoreCityForMissionary) and inquisitor use (ScoreCityForInquisitor) for a given city, but the scores are not commensurable.
ideally there would be a score for "intervention urgency" and a second check "send missionary or inqusitor". i seek simple rules for those two checks.
 
1) yes, attrition seems to be yet another AI-unfriendy micromechanic we could do without. it's easy to remove if there is a consensus.
Iam for a remove.
Maybe give missionaries and Inquisitors then the same movement reduction the siege units have? It's not more illogical than reducing the spread power.
 
Unless I want to roleplay

I have become increasingly convinced that religion is not worth the hassle. I will lose tempo in founding a religion so I would emphasize rather the development of economy and military and culture. Eventually someone will spread their religion to me. Eventually I will reach the Industrial era and buy Great People. And it often happens that I will annex at least one Holy City and harvest the benefits of the founder.

Same goes to Wonders. Why build wonders when you can get them next door ? I am talking about early era wonders. Then if I snowball late game then I will build wonders myself but those early ones...why bother building them.
 
1) yes, attrition seems to be yet another AI-unfriendy micromechanic we could do without. it's easy to remove if there is a consensus.
Maybe give missionaries and Inquisitors then the same movement reduction the siege units have?
I join the idea of having religious units move slowlier in closed border terrain. That way I could let AI handle my units, right now it's a no no.

2) adding a random element is also easy, but the AI logic is already quite complex, so the results look quite random to an outside observer.
I think that could make up for some corner cases and still save the day.

ideally there would be a score for "intervention urgency" and a second check "send missionary or inqusitor". i seek simple rules for those two checks.
You seem to ignore that we need a few STANDING inquisitors, just there, watching for trouble.
Missionaries I would only produce them when I have a purpose, someplace to convert. But inquisitors I want them in my corner cities as sentinels. I believe that's the major disagreement we players have with the current code.

Also, I think the scoring can be improved. I completely disagree with the tactic of converting all owned cities, then having all religious buildings built before spending a few missionaries in the foreign cities. Non founders and city states both are good targets for your religion, especially if you don't have many cities, you will need you neighbours city to produce pressure for you. Otherwise, these neighbours will be converted to other religions and you will stand with a religion that can't hold foreign pressure. Only if you want to go the polytheist route you are better leaving other religions take over yours.
I have to go out this evening with the family, but let me think of some easy rules that follow current code structure.

I have become increasingly convinced that religion is not worth the hassle.
It should not be the case. But also going full warmonger should be a viable option.
 
By saying religion is not worth the hassle, I really mean that actively pursuing to spread your religion to others via spending faith to purchase missionaries and religious prophets comes with a cost. All that faith "wasted" to spread religion could be used to buy other great people, engineers scientists artists etc.

The question becomes is that worth it ? And I doubt that sometimes and I'd rather spend the faith an-block to buy scientists for a massive technology boost once I get to Industrial. This strategy is quite efficient in a Space Race.
 
By saying religion is not worth the hassle, I really mean that actively pursuing to spread your religion to others via spending faith to purchase missionaries and religious prophets comes with a cost. All that faith "wasted" to spread religion could be used to buy other great people, engineers scientists artists etc.

The question becomes is that worth it ? And I doubt that sometimes and I'd rather spend the faith an-block to buy scientists for a massive technology boost once I get to Industrial. This strategy is quite efficient in a Space Race.

I think this deserves a topic of its own if you think putting all faith in great people > putting faith elsewhere, because it's not really relevant to this topic.

I most definitely disagree with you in a general case, but to really say anything concrete, somebody should probably throw math at it. Spreading your religion to others also weakens their religious benefits. Religion gives you world council votes. Unlocking a reformation requires you to spread your religion a certain amount. These reformation beliefs are typically really powerful and scale based on how much you have spread your religion. Shared religion is also a diplomatic modifier. Pursuing religion more actually allows you to pick the beliefs that are relevant towards the kind of game you are playing, instead of having to play with what's left.

If math does conclude that your way is superior in general, then I'd say we would have to nerf that strategy to not have an obsolete system in the game.

----

For the topic of missionaries in enemy territory at hand, I'd prefer new pathfinding logic that prioritizes minimizing attrition > lowering missionaries speed in enemy territory > current solution.

Losing religious power in closed borders is one of the ways to defend against religious rivals and it's an interesting defensive choice to have. The only other defense is basically out-faith your opponent or conquer them. Losing speed will just have that same religious power occur a few turns later.
 
Well, I think the simplest logic is, (and the logic I use)

If your own city doesn't have a religion:
Use a missionary
If it has an opponent's religion:
Use an inquisitor, then station one there in the city

Otherwise, use faith for enhancing.
If there is a target that hasn't founded, buy several missionaries and convert them.

That second part could use some work, but the first part I think is how it should function and it is relatively simple.
 
Top Bottom