MNAI-U: unofficial build & bugfixes

Hi, I don't know if this is the exactly thread to report this, but I have found some issues in MagisterModMod regarding the AI behavior:

1) The AI is too slow to expand by pacifical means. They take too long to build cities and are more inclined to take barbarian and other civilizations cities.
2) Some civilizations develop very slowly than others. The Sheaim, for example, sometimes only build one city besides their capital during all the game.
3) Barbarians conquer cities, but don't hold them. Instead of taking the city and hold it, the barbarians units just leave ir and go for the next prey (even if they are not successful).
4) Civilization units tend to not guard their cities in the beginning of games. Its pretty common to have one or two civilizations been destroyed because they prefer to use all units to explore and attack goblin forts instead of guard their capitals against barbarian units.
5) The AI builds many forts only to have resources. Maybe this is one of the motivations for the AI don't want to build other cities. The forts turns possible to the AI have cultural control over a tile with resources, making things pretty easy for them.
6) There is a issue with the Barbarian trait that civilizations with it don't lose the protection against barbarians units when having a high score.
7) The AI insists every turn for an POW exchange agreement. Its a bit annoying and I don't know well what is the mechanics that work in the POW agreement.
8) The AI doesn't ask for peace when losing an war (even when all its cities are conquered and only remains one). This doesn't occurs only between the player and the AI.

I'm attaching some saves to help find and fix the issues and thanks for the great work !
 

Attachments

6) There is a issue with the Barbarian trait that civilizations with it don't lose the protection against barbarians units when having a high score.
This one is is caused by Python code in CvEventManager.py that I changed from this:
Code:
       if pPlayer.isHuman():
           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_BARBARIAN')):
               eTeam = gc.getTeam(gc.getPlayer(gc.getBARBARIAN_PLAYER()).getTeam())
               iTeam = pPlayer.getTeam()
               if eTeam.isAtWar(iTeam) == False:
                   if 2 * CyGame().getPlayerScore(iPlayer) >= 3 * CyGame().getPlayerScore(CyGame().getRankPlayer(1)):
                       if iGameTurn >= 20:
                           eTeam.declareWar(iTeam, False, WarPlanTypes.WARPLAN_TOTAL)
                           if iPlayer == CyGame().getActivePlayer():
                               cf.addPopup(CyTranslator().getText("TXT_KEY_POPUP_BARBARIAN_DECLARE_WAR",()), 'art/interface/popups/Barbarian.dds')
To this:
Code:
           if not eTeam.isAVassal():#Vassals do not control their own diplomacy
               if pPlayer.hasTrait(iBarbTrait):
                   if bTeam.isAtWar(iTeam):
                       if 2 * CyGame().getPlayerScore(iPlayer) < 3*CyGame().getPlayerScore(CyGame().getRankPlayer(1)):
                           bTeam.makePeace(iTeam)
                           if pPlayer.isHuman() and iPlayer == CyGame().getActivePlayer():
                               cf.addPopup(CyTranslator().getText("TXT_KEY_POPUP_BARBARIAN_RESTORE_TRUCE",()), 'art/interface/popups/Barbarian.dds')
                   elif not cf.grace():
                       if 3 * CyGame().getPlayerScore(iPlayer) >= 4 * CyGame().getPlayerScore(CyGame().getRankPlayer(1)):

                           for iEvent in [gc.getInfoTypeForString('EVENT_SUMMON_HYBOREM'), gc.getInfoTypeForString('EVENT_SUMMON_JUDECCA'), gc.getInfoTypeForString('EVENT_SUMMON_LETHE'), gc.getInfoTypeForString('EVENT_SUMMON_MERESIN'), gc.getInfoTypeForString('EVENT_SUMMON_OUZZA'), gc.getInfoTypeForString('EVENT_SUMMON_SALLOS'), gc.getInfoTypeForString('EVENT_SUMMON_STATIUS')]:
                               if pPlayer.getEventOccured(iEvent):
                                   break
                           else:
                               if bTeam.canDeclareWar(iTeam):
                                   bTeam.declareWar(iTeam, False, WarPlanTypes.WARPLAN_TOTAL)
                                   if pPlayer.isHuman() and iPlayer == CyGame().getActivePlayer():
                                       cf.addPopup(CyTranslator().getText("TXT_KEY_POPUP_BARBARIAN_DECLARE_WAR",()), 'art/interface/popups/Barbarian.dds')
I felt the Barbarian trait was not useful enough, so rather than making the Barbarian State declare war whenever the player is more than 2/3 of the highest player's score, I intentionally made the Barbarian state declare war on them only when they are above 3/4 of the top player's score and to make peace again if the player falls below 2/3 of the highest player's score.


The rest of the issues are things I too would like lfgr to address.
 
New release: mnai-2.9-beta1u.

Not compatible with 2.8.1u savegames. The next version might again break savegames.

Thanks to @Devils_Advocate, @Bickendan, and @swapoer for bug reports (and, I think, @MagisterCultuum for feature requests).

Download setup
Download archive

The mod now comes with a handy setup, thanks to Valkrionn for the tutorial and MagisterCultuum for making me aware of it. You can also download the archive version if you prefer, but make sure to follow the installation instructions on the download page.
MNAI-U now uses a different Mod folder, "More Naval AI". If you have an old version installed, I recommend completely re-installing vanilla Fall from Haven 0.41 with patch "o". If you want to use a different folder, see here. However, using a different folder makes it a bit harder for me to debug your savegames, so I don't recommend it.

This release, as always, contains a number of bugfixes and small UI improvements. Otherwise, my focus was on the council system. Some non-functional or unfitting resolutions have been removed, and there are now tooltips that provide information on what each resolution does. There also has been some behind-the-scenes work to make adding new resolutions easier.

See here or the file changelog.md included in the download for a full changelog.
Modders should make sure to check the full changelog for added and removed tags.
 
Hi, I don't know if this is the exactly thread to report this, but I have found some issues in MagisterModMod regarding the AI behavior:
I'm fine with general MagisterModMod AI reports/observations, like yours. I don't want to look at MagisterModMod savegames right now, but it's good if you keep them in case I want to look at them later, when I have time.

Also, please keep in mind that I'm not very experienced with all the AI stuff, so I can't make any promises.

1) The AI is too slow to expand by pacifical means. They take too long to build cities and are more inclined to take barbarian and other civilizations cities.
2) Some civilizations develop very slowly than others. The Sheaim, for example, sometimes only build one city besides their capital during all the game.
I did not notice that, but I made a note and look out for it in the future.

3) Barbarians conquer cities, but don't hold them. Instead of taking the city and hold it, the barbarians units just leave ir and go for the next prey (even if they are not successful).
4) Civilization units tend to not guard their cities in the beginning of games. Its pretty common to have one or two civilizations been destroyed because they prefer to use all units to explore and attack goblin forts instead of guard their capitals against barbarian units.
I think I observed both of these things in MNAI, and I hope 4 at least should be fairly easy to fix. I will look into them.

5) The AI builds many forts only to have resources. Maybe this is one of the motivations for the AI don't want to build other cities. The forts turns possible to the AI have cultural control over a tile with resources, making things pretty easy for them.
So, what exactly is the problem? Why do you think they build too much forts?
If you dislike forts spreading culture (the "super forts" mod), you can disable the Advanced Tactics game option.

7) The AI insists every turn for an POW exchange agreement. Its a bit annoying and I don't know well what is the mechanics that work in the POW agreement.
I briefly looked into this POW thing and I think I concluded that it either doesn't do anything or isn't worth including, so I will probably remove it in some future version.

8) The AI doesn't ask for peace when losing an war (even when all its cities are conquered and only remains one). This doesn't occurs only between the player and the AI.
I have to check this.

I'm attaching some saves to help find and fix the issues and thanks for the great work !
You're welcome, I'm glad you enjoy it. Thank you for the your reports.
 
Thanks!

I have it merged with MNAI now, and am in the early stages of playtesting after the merge.

I thought I found an issue with how you check whether votes have passed, as I was getting an error in the GameUtils.py file where it checks whether I can guild Gambling Houses, but it turns out that I had just overlooked your alterations in PyHelpers.py. It all seems to be working fine now.

When I started a clean game with just MNAI-u trying to confirm the bug (before realizing my mistake) I noticed that The Pool of Tears was mislabeled as Odios Prison for some reason. I'm guessing that the Erebus mapscript swapped the unique feature for flavor purposes but failed to update the label.
 
I'm fine with general MagisterModMod AI reports/observations, like yours. I don't want to look at MagisterModMod savegames right now, but it's good if you keep them in case I want to look at them later, when I have time.
Ok.

Also, please keep in mind that I'm not very experienced with all the AI stuff, so I can't make any promises.
I understand. Anyway, I thank you for your time !

So, what exactly is the problem?
I forget to complete this topic. Sorry :D. Some of the problems are that the AI never garrison their forts with ground units, (which is strange the AI build a defensive structure and never garrison it) and the player cannot build them outside their borders, which is not the same case of the AI. Also, the AI can build without having cultural influence in the tile.
 
Just for input, I was playing exclusively MNAI until a few days ago, and...
3) Barbarians conquer cities, but don't hold them. Instead of taking the city and hold it, the barbarians units just leave ir and go for the next prey (even if they are not successful).
4) Civilization units tend to not guard their cities in the beginning of games. Its pretty common to have one or two civilizations been destroyed because they prefer to use all units to explore and attack goblin forts instead of guard their capitals against barbarian units.
Neither of these was happening, ever.
 
I realized that the installer creates a desktop shortcut with the wrong path. I updated the installer download.

To manually fix this without having to re-download, right-click the shortcut, select "properties", go to the "shortcut" tab and change the target from
Code:
... mod=\More Naval AI unofficial
to
Code:
... mod=\More Naval AI

Some of the problems are that the AI never garrison their forts with ground units
I see, I'll see if I can reproduce that.

the player cannot build them outside their borders, which is not the same case of the AI
This is not true in MNAI, everybody can build forts outside cultural borders.
 
Hello!
Is there any way to disable ONLY the Super Fort component? I am not a big fan of Super Fort. Fort-spamming on every resource tile in unowned territory is not my flavour but AIs are doing that very very well...
And thank you for your effort keeping Fall from Heaven alive :)
 
I keep getting bugs like this in my modmod
Code:
Traceback (most recent call last):

  File "CvScreensInterface", line 786, in forceScreenRedraw

  File "CvMainInterface", line 1431, in redraw

  File "CvMainInterface", line 5726, in updateHelpStrings

RuntimeError: unidentifiable C++ exception
ERR: Python function forceScreenRedraw failed, module CvScreensInterface
The problem is in the statement CyInterface().getHelpString()
Code:
    # Will update the help Strings
   def updateHelpStrings( self ):
   
       screen = CyGInterfaceScreen( "MainInterface", CvScreenEnums.MAIN_INTERFACE )

       if ( CyInterface().getShowInterface() == InterfaceVisibility.INTERFACE_HIDE_ALL ):
           screen.setHelpTextString( "" )
       else:
           screen.setHelpTextString( CyInterface().getHelpString() )
       
       return 0

I have tried first checking to see if CyInterface().getHelpString() is equal to -1, or '' or has a length of zero before calling setHelpTextString but that does not help.

I think it has something to do with generating combat odds. I notice it most often when I try t tell a summoned Host of the Einherjar to move into a tile containing an enemy worker with the Blessed promotion.

I have also noticed that combat odds can be very inaccurate when one unit has a lot of its strength in a type to which the other unit has resistance. For instance, my Morrigan units extremely high Death strength makes it say that she is sure to defeat any unit, including those to whom she always ends up losing because of their immunity to death damage.

When you are using a Hidden Nationality Unit to attack a stack that contains units you own as well as units belonging to rivals, the combat odds mouseover tends to show the odds of victory in a fight against your own unit instead of against the unit that your HN unit will actually attack.



---

Can the pedia be changed so that it will show the minumum level requirements for promotions and units?

---

Would it be possible to give units and buildings some ReligionProductionModifiers, like the <BonusProductionModifiers> or <ProductionTraits> tags but based on the religions present in the city where they are built?

I'd love to let the Unblemished give cheaper Infirmaries, the Laeran Cord cheaper Libraries, etc.
 
I'll look into the bugs you mentioned.
Can the pedia be changed so that it will show the minumum level requirements for promotions and units?
Sure, sounds reasonable.

Would it be possible to give units and buildings some ReligionProductionModifiers, like the <BonusProductionModifiers> or <ProductionTraits> tags but based on the religions present in the city where they are built?
This (or a similar thing?) can be done in CvGameUtils.getBuildingCostMod(). For now, I'd prefer if you did it that way.
 
Yeah, I guess I can use getBuildingCostMod for that. I'd have to document it manually in xml strategy tags, but that's ok. I was thinking using new xml tags might be easier on the AI, but it probably would not be worth training it to know to spread certain religions before trying for certain buildings and the cost of some building being a lot lower is probably easy enough for it to understand when evaluating whether to build it.
---

I just did a bit more testing on that CyInterface().getHelpString() bug.

It does not happen if the defending unit has 0 damage.

It happens with any Angel attacking an injured Blessed worker, not just a summoned Einherjar. If I switch out the Blessed promotion for one granting Death damage instead of Holy, then the same issue occurs for any Undead attacker. If I switch it out for one granting Unholy damage then it happens for any Demonic attacker. It is not specifically about workers, as it also happens if I try to attack a Fireball (which in my mod has only Fire Strength) with a Fire Elemental (which has Immune to Fire).

It seems to happen every single time when an injured defender's strength is entirely in a form to which the attacker is immune.


---

I've been getting the "TradeUtil - unknown item type 10" issue after POW exchange trades again, probably related to your commenting out line 589 of TradeUtil.py
 
Last edited:
Yeah, I guess I can use getBuildingCostMod for that. I'd have to document it manually in xml strategy tags, but that's ok. I was thinking using new xml tags might be easier on the AI, but it probably would not be worth training it to know to spread certain religions before trying for certain buildings and the cost of some building being a lot lower is probably easy enough for it to understand when evaluating whether to build it.
I agree, it's nicer as an XML tag. I'll put it on my list, just be aware that it might get buried under other changes that are more important in my opinion.

It seems to happen every single time when an injured defender's strength is entirely in a form to which the attacker is immune.
Thanks for the additional information, that indeed sounds like an edge case that might go wrong.

I've been getting the "TradeUtil - unknown item type 10" issue after POW exchange trades again, probably related to your commenting out line 589 of TradeUtil.py
I'll look into it.
 
Can the pedia be changed so that it will show the minumum level requirements for promotions and units?
For units, iMinLevel ("must be upgraded from...") is already in the help text, right? Or are you requesting something different?
I added iMinLevel to the promotion help text.
 
Is there anywhere that I could put some python code to be triggered upon completing a mission, such as a Trade Mission like those done by Great Merchants?

I was thinking of giving the Stewards of Inequity an ability that works just like a trade mission but causes the city's owner to loose all the gold that the unit's owner gains. I eventually got it to work, but only for units whose xml defines would allow the more traditional trade mechanism. It seems odd to give the same unit two such similar abilities.

(It took me very long time to understand why pCaster.getTradeGold(pPlot) worked fine in its PyRequirement and PyHelp but always returned 0 in the PyResult. It turns out that spells with bHasCasted set the caster as setHasCasted(True) before calling PyResult, and Kael made the code always return 0 if the unit has already casted. Using <bHasCasted>0</bHasCasted> or setHasCasted(True) fixed that. )

I got to thinking it would be cooler if I could adjust the normal trade mission so that it is normally a Positive Sum Game (giving the city owner some gold as well as the merchant's owner) but that when the merchant is of the Stewards of Inequity religion it becomes a Zero Sum Game or even a Negative Sum Game, where the city owner looses as much or more than the Rentier gains.

Edit:
I just noticed from looking through the source code and the BtS reference class that all the functions called within the getTradeGold calculation seem to be exposed to python.
It should not be hard to duplicate its effects for a python spell with iBaseTrade and iTradeMultiplier defined in python instead of xml.
I still think it would be cooler and probably easier on the AI to have positive sum or negative sum trade missions based on the unit's religion, but it is not worth the trouble of making you change anything in the DLL. If that would be required, you can just ignore this whole post.
 
Yeah, if it is not too much trouble.

It might be nice to have similar callbacks for other missions too, like sacrificing a unit for culture/research/production/spreading their religion, although I do not at this point have plans for those.
--

In my modmod there are some spells to summon units that have upgrades, and it is possible to waste money upgrading a unit that will expire in a turn or two. I'd like something to be done about that, although I am not yet sure if I'd prefer to make their upgrades free (or discounted based on how soon the unit will expire) or simply block such upgrades.
--
In my modmod there are enough promotions that have a <iUpgradeDiscount> that a unit with more than one of those promotions could end up having a negative upgrade cost. I'm thinking it would be better to cap the total upgrade discount so that upgrades can be made completely free but the game would never pay a player for upgrading a unit.

--
Can you prevent the popup asking if you want to convert to a religion when it first spreads to your lands when it is not actually possible to convert to said religion due to a <ReligionWeightModifier> with <iWeightModifier>-100 ?

It is a little annoying since no one is able to convert to half of the religions in my modmod.

--

I still wish that <ReligionChanges> from buildings should be applied when the buildings are added in advanced starts just like when they are constructed in the course of the game.
 
In my modmod there are enough promotions that have a <iUpgradeDiscount> that a unit with more than one of those promotions could end up having a negative upgrade cost. I'm thinking it would be better to cap the total upgrade discount so that upgrades can be made completely free but the game would never pay a player for upgrading a unit.
Agreed.

Can you prevent the popup asking if you want to convert to a religion when it first spreads to your lands when it is not actually possible to convert to said religion due to a <ReligionWeightModifier> with <iWeightModifier>-100 ?
Yes.

I still wish that <ReligionChanges> from buildings should be applied when the buildings are added in advanced starts just like when they are constructed in the course of the game.
Ah, of course. When you reported that problem earlier I was under the impression that you were only talking about the world builder, not advanced start.
 
Back
Top Bottom