MNAI-U: unofficial build & bugfixes

Someone out there is either a seriously troubled prankster or absolutely bonkers. In at least CvPlayerAI.cpp and CvTeamAI.cpp there are at least 2 places where an if statement checks to see if 1 is less than 2. Seriously it's written like this
Code:
    if (1 < 2)
    {
        if (GET_TEAM(getTeam()).getAnyWarPlanCount(true) > 0)
        {
            return DENIAL_NO_GAIN;
        }
    }
I'm guessing that is just a stylistic preference someone chose to use in lieu of If (True) or If (False) when they wanted to test enabling or disabling code that used to rely on some other conditional. Usually such placeholders are only temporary.


Notepad++ quickly identifies 8 such places in the source code, and 1 where it checks for the opposite

Search "if (1 < 2)" (8 hits in 3 files of 214 searched)
C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\Mods\more-naval-ai\CvGameCoreDLL\CvPlayer.cpp (1 hit)
Line 6494: if (1 < 2) // human as vassal
Code:
    case TRADE_VASSAL:
    case TRADE_SURRENDER:
        //if (!isHuman() || GET_PLAYER(eWhoTo).isHuman()) //  human can't be vassal of AI
        if (1 < 2) // human as vassal
        {
            CvTeam& kVassalTeam = GET_TEAM(getTeam());
            CvTeam& kMasterTeam = GET_TEAM(GET_PLAYER(eWhoTo).getTeam());
            if (kMasterTeam.isVassalStateTrading()) // the master must possess the tech
            {
                if (!kVassalTeam.isAVassal() && !kMasterTeam.isAVassal() && getTeam() != GET_PLAYER(eWhoTo).getTeam())
                {
                    if ((kMasterTeam.isAtWar(getTeam()) || item.m_iData == 1) && item.m_eItemType == TRADE_SURRENDER)
                    {
/************************************************************************************************/
/* Afforess                      Start                                                                */
/* Advanced Diplomacy                                                                           */
/************************************************************************************************/
C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\Mods\more-naval-ai\CvGameCoreDLL\CvPlayerAI.cpp (2 hits)
Line 12927: if (1 < 2)
Code:
/************************************************************************************************/
/* Afforess                      Start        03/19/10                                               */
/*                                                                                              */
/* Ruthless AI: Don't change civics when planning war                                           */
/************************************************************************************************/
//    if (GC.getGameINLINE().isOption(GAMEOPTION_RUTHLESS_AI))
    if (1 < 2)
    {
        if (GET_TEAM(getTeam()).getAnyWarPlanCount(true) > 0)
        {
            return DENIAL_JOKING;
        }
    }
/************************************************************************************************/
/* Afforess                         END                                                            */
/************************************************************************************************/
Line 13017: if (1 < 2)
Code:
/************************************************************************************************/
/* Afforess                      Start        03/19/10                                               */
/*                                                                                              */
/* Ruthless AI: Don't Change Religions When we are planning war (Anarchy is bad)                */
/************************************************************************************************/
//    if (GC.getGameINLINE().isOption(GAMEOPTION_RUTHLESS_AI))
    if (1 < 2)
    {
        if (GET_TEAM(getTeam()).getAnyWarPlanCount(true) > 0)
        {
            return DENIAL_NO_GAIN;
        }
    }
/************************************************************************************************/
/* Afforess                         END                                                            */
/************************************************************************************************/
C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\Mods\more-naval-ai\CvGameCoreDLL\CvTeamAI.cpp (5 hits)
Line 2088: if (1 < 2)
Code:
/************************************************************************************************/
/* Afforess                      Start        03/19/10                                               */
/* Ruthless AI: Don't Sell Our Military Secrets                                                 */
/************************************************************************************************/
    //if (GC.getGameINLINE().isOption(GAMEOPTION_AGGRESSIVE_AI))
    if (1 < 2)
    {
        //if (GC.getTechInfo(eTech).getFlavorValue(GC.getInfoTypeForString("FLAVOR_MILITARY")) > 3)
        if (GC.getTechInfo(eTech).getFlavorValue(0) > 3)
        {
            //We don't want to spread military techs when we are gearing for war
            //If there is tech brokering, selling the tech to anyone could get it in the hands of our enemy. If there is no brokering, just worry about the current team.
            if (getAnyWarPlanCount(true) > 0 && (!GC.getGameINLINE().isOption(GAMEOPTION_NO_TECH_BROKERING) || AI_getWarPlan(eTeam) != NO_WARPLAN))
            {
                return DENIAL_NO_GAIN;
            }
        }
    }
/************************************************************************************************/
/* Afforess                         END                                                            */
/************************************************************************************************/
Line 2247: if (1 < 2)
Code:
/************************************************************************************************/
/* Afforess                      Start        03/19/10                                               */
/* Ruthless AI                                                                                  */
/************************************************************************************************/
    //if (GC.getGameINLINE().isOption(GAMEOPTION_AGGRESSIVE_AI))
    if (1 < 2)
    {
        //Planning war against the team, we need their map!
        if (AI_getWarPlan(eTeam) != NO_WARPLAN)
        {
            iValue *= 15;
        }
Line 2332: if (1 < 2)
Code:
/************************************************************************************************/
/* Afforess                      Start        03/30/10                                               */
/* Ruthless AI: Selling Maps right before we go to war is stupid                                */
/************************************************************************************************/
    //if (GC.getGameINLINE().isOption(GAMEOPTION_AGGRESSIVE_AI))
    if (1 < 2)
    {
        if (AI_getWarPlan(eTeam) != NO_WARPLAN)
        {
            return DENIAL_MYSTERY;
        }
Line 3973: if (1 < 2)
Code:
/************************************************************************************************/
/* Afforess                      Start        03/30/10                                               */
/* Ruthless AI: Get Open Borders with Nearby Allies, reject them with enemies                   */
/************************************************************************************************/
    //if (GC.getGameINLINE().isOption(GAMEOPTION_AGGRESSIVE_AI))
    if (1 < 2)
    {
        bool bWarplans = getAnyWarPlanCount(true) > 0;
        if (AI_getWarPlan(eTeam) == NO_WARPLAN && bWarplans)
Line 5144: if (1 < 2)
Code:
/************************************************************************************************/
/* Afforess                      Start        02/19/10                                               */
/* Ruthless AI: Attack Weaker, Closer targets                                                   */
/************************************************************************************************/
    //if (GC.getGameINLINE().isOption(GAMEOPTION_AGGRESSIVE_AI))
    if (1 < 2)
    {
        iRand /= 2;
    }
/************************************************************************************************/
/* Afforess                         END                                                            */
/************************************************************************************************/

Search "if (1 > 2)" (1 hit in 1 file of 214 searched)
C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\Mods\more-naval-ai\CvGameCoreDLL\CvTeam.cpp (1 hit)
Line 4101: if (1 > 2)
Code:
            // Keep war againt those this team has met
            for (iI = 0; iI < MAX_CIV_TEAMS; iI++)
            {
                if( iI != getID() && !(GET_TEAM((TeamTypes)iI).isBarbarian()) && !(GET_TEAM((TeamTypes)iI).isMinorCiv()) )
                {
                    if( abHasMet[iI] )
                    {
                        //if( GC.getGameINLINE().isOption(GAMEOPTION_START_AS_MINORS) )
                        if (1 > 2)
                        {
                            if( !isAtWar((TeamTypes)iI) )
                            {
                                declareWar((TeamTypes)iI, true, NO_WARPLAN);
                            }
                        }
 
He, I think that was Tholal. Probably to "temporarily" enable or disable something without having to remove braces and correct indentation. I don't know why not "if(true)", though.
A couple of these will be gone in the next version, by the way (replaced by a check for the new Ruthless AI gameoption).

EDIT: Missed Magister's post. Yeah, looks like it's mostly the Ruthless AI code.
 
Last edited:
That's kinda hilarious and relatable. But the 1<2 vs true part is strange. :D Edit: Though it makes sense when you want to change a specific set of checks to "true" temporarily, and then later on find them quickly, since such a condition typically won't be used anywhere else.
 
The fishing technology says it enables trade connections on rivers and sailing says it enable it via coast, yet just having fishing is sufficient for a coastal trade connection with no roads.
 
I have a question about the getbuildingkey function as well as where it is called in CvCustomizableDomesticAdvisor.py.
Code:
    def getBuildingKey(self, index):

       info = gc.getBuildingInfo(index)
       desc = info.getType()
       key = "_"
       key = key.join(desc.split())
       key = key.upper()
       return key

From this, unless I am grossly misunderstanding something, it would appear that changing the number or order of buildings in the building defines XML would only have an effect on the index called based on all its uses in the code. But even with all the indices as 1, the domestic advisor still doesn't load. This seems to be the only hard coding in the interface I've had trouble with and is there something I could be missing? I have changed a great deal in the XMLs, python, and DLL files but this is the one thing that's been giving me grief. Any insights would be greatly appreciated, especially if you suspect it isn't this function (I know that's hard without the full code base but it will be a full weeks until I'm ready to release outside of some friends for prototype testing)!
 
Sorry, I don't really understand what the problem is. The Customizable Domestic Advisor doesn't load for you? Do you get any python exceptions? Did you try enabling/disabling it via the BUG options (you need to restart the game to apply them)?

But even with all the indices as 1, the domestic advisor still doesn't load.
Are you talking about the calls for getBuildingKey() of the following form?
Code:
(self.getBuildingKey(3), 70, "text"),
You can simply delete those lines if they're giving you problems. They're just setting up some default columns in the CDA. This is horrible programming style, of course, I don't know why they're hard coding the indices.

As for the function itself: It should simply always return info.getType() (e.g., BUILDING_ACADEMY). The last 4 lines are just for dealing with the case that there is whitespace in the building <Type>. This doesn't happen in FfH or any other mod that I know of. Maybe that's what you're doing and it's confusing other parts of the code?

Still looking forward to your mod, btw. :)
 
It doesn't load at all and while it did give an error (about the HUNTING_LODGE line), now it just doesn't load which I imagine is because there are no longer hunting lodges, mage guilds, and stables. Deleting the entries doesn't seem to help either. And thanks for the heads up, I missed the tick box in the BUG menus even though it's pretty obvious. All the BUG and various other mods merged in via Python are still pretty new to me so it might have to wait for a fresher pair of eyes to look over it. :crazyeye:

And it's coming along, thanks! :p Hoping to get some friend and family play testing done for some "balance" and general flow feedback before a more wide release here, but that's very soon. Thanks for all the work on the mod(mod)!
 
The frostlings have been spotted in the wastes event at minimum should not be able to spawn them on a city (ideally it wouldn't exist at all). I just died on turn 8 on marathon speed because the event happened on my unguarded city. Having to settle in tundra is already a punishment, having to guard every city on top of that is ridiculous.
 
It might have to be moved back to only appear at later turns, but in itself, event variance is nice. :D
 
It doesn't load at all and while it did give an error (about the HUNTING_LODGE line), now it just doesn't load which I imagine is because there are no longer hunting lodges, mage guilds, and stables.
I don't want it to break from just editing XML. If you managed to get the other one working, then I guess I'll take a look at what happens in your mod when it's out.

Regarding the frostling event: Spawning on a city is clearly not intended. I'll consider also requiring a tech or something like that, maybe it isn't much fun very early in the game.
 
How possible would it be to manually edit out the Ruthless AI changes? I've been quite frustrated of late. Or does it require editing the DLL?
 
MNA 2.9u

My group has been running a few test games with the AI controlling certain factions and we noticed a few issues.

Budget:
1. I noticed this lot when at least starting in classical era, the AI likes to drop it's sciences to zero and gain money, but then perceives to increase their sciences up to hundred percent for a few turns, and then drops it back down to zero, etc etc. It's just strange that the budgeting AI is doing that.

Research:
The AI researches tech that they either have no use for or they get some really expensive tech when their are like a hundred other things they should get. For example in one game the Doviello was research fishing when the Doviello had no access to the sea much less fish. In another game starting in classical era the AI for some reason beelined Drama and spend many turn researching it, only to stop when it had 6 turns left and switch it's research to something else.

Also in a lot of cases in the ancient era start the AI loves to get animal husbandry, even if their is no resources like horse or cow nearby. Also with religion a lot of AI do it right, like the elf's and dwarves, but a lot of the the other AI love to get religion tech. That is after someone else beat them to it. In my opinion in terms of research, research priority should be looked at. Some AI go well over 100+ turns not getting mining, archery, bronze working, and many other important tech.

3. Economy
Another issue is the AI economy. Ill use a example here. I let the Khazad AI get about 200+ plus turn in; Now they had plenty of cottages which is good, but they researched writing at least 60+ turns when I decided to stop the testing and out of 8 cities none of them had a library build. Or for that matter any science buildings like the elder council. It really put them behind. Also I noticed the AI loves the cottages, but I never really see them specialize a city in say one hundred percent production/ food. Like in my opinion they should focus on sciences and gold improvements in cottage cities and unit production buildings/wonders in production cities.

4. Naval and Sea
Ok this one is rather interesting. I thought the more naval AI would well....make the AI smarter in regards to naval activity, however that does not seem to be the case. The way it is the AI does not even seem to invade a enemy if they are only accessible with the use of boats. It's kinda a big deal. lol

Ill include more when I get a chance later cause I'm going to run quite a few test games later.
 
Last edited:
In the dynamic civ naming feature, Commune and Federation have an erroneous space leading them [ Commune of x]
 
Last edited:
4. Naval and Sea
Ok this one is rather interesting. I thought the more naval AI would well....make the AI smarter in regards to naval activity, however that does not seem to be the case. The way it is the AI does not even seem to invade a enemy if they are only accessible with the use of boats. It's kinda a big deal. lol
I have seen an AI send naval landings around when on a different land mass (I had one extremely interesting game where a Lanun AI started on the main continent, but then colonised a different island where it had about 10 cities compared to the mainland's ~5, and it even moved its capital onto the island (on its own, it was never captured). From then on, they sent some annoying naval raids to a civ on the mainland every now and then. Enough to do damage, but not enough to conquer. But it should probably be more.

What is however a big problem is when an AI shares the same landmass with a different civ, but is 100% seperated by mountains. Then I have never seen any AI use navy to ship around these mountains.
 
I have seen an AI send naval landings around when on a different land mass (I had one extremely interesting game where a Lanun AI started on the main continent, but then colonised a different island where it had about 10 cities compared to the mainland's ~5, and it even moved its capital onto the island (on its own, it was never captured). From then on, they sent some annoying naval raids to a civ on the mainland every now and then. Enough to do damage, but not enough to conquer. But it should probably be more.

What is however a big problem is when an AI shares the same landmass with a different civ, but is 100% seperated by mountains. Then I have never seen any AI use navy to ship around these mountains.

Was this with the most recent version of MNA?
 
1. I noticed this lot when at least starting in classical era, the AI likes to drop it's sciences to zero and gain money, but then perceives to increase their sciences up to hundred percent for a few turns, and then drops it back down to zero, etc etc. It's just strange that the budgeting AI is doing that.
I don't see an issue with this, you won't notice this as a player normally. In fact, I believe it is slightly more efficient, since you don't lose commerce to rounding errors.


For example in one game the Doviello was research fishing when the Doviello had no access to the sea much less fish.
Fishing also allows trading on rivers, I assume that's what they were going for.

In another game starting in classical era the AI for some reason beelined Drama and spend many turn researching it, only to stop when it had 6 turns left and switch it's research to something else
Also in a lot of cases in the ancient era start the AI loves to get animal husbandry, even if their is no resources like horse or cow nearby.
It's basically impossible for me to see what went wrong here without a savegame, unfortunately.

Also with religion a lot of AI do it right, like the elf's and dwarves, but a lot of the the other AI love to get religion tech. That is after someone else beat them to it.
Do you mean they get multiple religions? Because it totally makes sense to get a religion even when you don't get the holy city, it's +1 happiness in each of your cities, basically.


To explain what can and can't be done in regards to AI, let me briefly explain how the AI works. So, when deciding what tech to research next, the AI isn't really following some kind of overarching strategy. It simply calculates a score for each tech, and then chooses the one with the highest score. The scores are partially based of current circumstances, of course; for example, the more other teams we know that can't already trade with us, the higher we value a tech that allows tech trading. There is also some very limited strategizing on the level of "I want to win a cultural victory, so I want culture buildings somewhat more than normal". Choosing units and buildings works basically the same.

So what I can do (without rewriting large parts of AI logic) is to change how existing factors a valued for this "score" or add new factors. The problem is that each such change has a global effect that is generally hard to predict. For example, I could lower the value of "river trading". This might improve the performance of an AI without access to water (since it prioritizes other techs), but it may hurt AIs with access to water: maybe the current value of "makes fish available" is balanced around the (implicit) assumption that "river trading" is valued as it is now. This is all hypothetical, but my point is that the whole machinery is fragile and easy to get out of whack.

The conclusion is that even small changes to the AI should be accompanied by extensive testing. Unfortunately, I don't have enough time to do that, and the player base is often not large enough to get meaningful data. I'm not saying your observations are invalid or something, but the AI will never be perfect (or even just reasonable) 100% of the time, and I need more data before I can conclude that what you saw is not just an isolated incident. If I had infinite time, I would also try to fix those isolated incidents, but, alas, I don't.

All that said, sometimes there are straight bugs in the code, this has happened before (e.g., the AI was often canceling open borders in the misguided belief you'd be about to win a religious victory). So if there's a single choice that is obviously unreasonable (like researching Animal Handling without the resources), I'm interested in seeing a savegame. If the AI is doing evaluations that are generally reasonable, just not in this specific instance, then I probably won't change anything. But if there's a bug, I can try to fix it.

Also, if you can provide me with some kind of hard data that the AI is consistently undervaluing some tech, then I would also consider doing something about that.

4. Naval and Sea
Ok this one is rather interesting. I thought the more naval AI would well....make the AI smarter in regards to naval activity, however that does not seem to be the case. The way it is the AI does not even seem to invade a enemy if they are only accessible with the use of boats. It's kinda a big deal. lol
I also remember naval assaults, like Alekseyev_. I could have broken this at some point, although I think that's unlikely. I'll make a note to check this at some point. But keep in mind that MNAI naval AI is still awful, just not as awful as vanilla FfH's naval AI. :)

In the dynamic civ naming feature, Commune and Federation have an erroneous space leading them [ Commune of x]
Thanks, fixed for the next release.
 
Top Bottom