Advanced Civ

#1: CvTeam.cpp, 3983, CvTeam::getBestKnownTechScorePercent, iBestKnownTechScorePercent >= iOurTechScore
Probably a side-effect of the BBAI log being enabled. That causes getBestKnownTechScorePercent to be called on the Barbarians and the asserted condition (this team's tech score being at most as high as that of the most advanced civ team) isn't necessarily true for them (because the Barbarians aren't themselves a civ team).
I couldn’t find a BBAI log.
My mistake probably, sorry. The BBAI log actually requires LoggingEnabled=1 (in My Games\Beyond the Sword\CivilizationIV.ini); MessageLog shouldn't matter. BBAI.log should then get written to My Games\Beyond the Sword\Logs -- unless that folder somehow can't be written to.

But, yes, maybe the last two assertions are clear enough. Something about the Warrior unit in your mod, or whichever unit the AI can train at game start? That unit having a combat limit or a national limit could explain the assertion. Or an instance cost (getting costlier with every instance already owned), some requirement that prevents the capital from training the unit, 0 production cost or 0 combat strength, 0 power or a city defense penalty.
 
Hey, thanks for trying to help. Pretty much all units in my mod have an instance cost modifier, but this has been a feature of it for a long time. None of the base military units have a national limit or a peculiar city defense penalty. Archers still have a 50% city defense and their default AI is city defense. [Edit: The footman has city defense as a non-AI. Would this disqualify it from defending a site? I see footmen near city sites. But, I see in the base mod that warriors have this tag too.]

I'm running tests right now. The two relevant assertions hit after the AI trains it's first settler and archers. It varies somewhat, sometimes soon after an archer, sometimes after a stack of archers.

Edit: Ah, logging enabled! Trying again. Here is first example in log of the problem:

Spoiler :
[188331.609] Player 5 (Assyrian Empire) setTurnActive for turn 30 (4800 BC)
[188331.609] Player 5 (Assyrian Empire) has 1 cities, 1 pop, 18 power, 100 tech percent
[188331.609] Team 5 has met:
[188331.625] AI_settleMove: Moving settler at (65,17)
[188331.625] AI_settleMove: Going through 4 city sites
[188331.625] AI_settleMove: Best found value in area: 2541
[188331.625] AI_settleMove: Group can't defend itself
[188331.625] AI_settleMove: Considering to move to site (65,14)
[188331.625] AI_settleMove: Site not guarded and can't self-defend
[188331.625] AI_settleMove: Considering to move to site (62,17)
[188331.625] AI_settleMove: Site not guarded and can't self-defend
[188331.625] AI_settleMove: Considering to move to site (68,17)
[188331.625] AI_settleMove: Site not guarded and can't self-defend
[188331.625] AI_settleMove: Considering to move to site (66,20)
[188331.625] AI_settleMove: Site not guarded and can't self-defend
[188331.625] AI_settleMove: No valid site to move to
[188331.625] AI_settleMove: Failed to move to any local city site
[188331.625] AI_settleMove: Attempting to meet an escort
[188331.625] AI_settleMove: No escort found
[188331.625] Player 5 (Assyrian Empire) consider tech Fishing with value 69
[188331.625] Player 5 (Assyrian Empire) consider tech The Wheel with value 55
[188331.641] Player 5 (Assyrian Empire) consider tech Pottery with value 26
[188331.641] Player 5 (Assyrian Empire) consider tech Mysticism with value 30
[188331.656] Player 5 (Assyrian Empire) selects tech Fishing with value 69. (Aiming for Mysticism)


That same empire now has 6 archers and 5 footmen (!) in the city center, and 1 archer near a city site, but refuses to settle. Log:
Spoiler :

[188397.094] Player 5 (Assyrian Empire) setTurnActive for turn 99 (2400 BC)
[188397.094] Player 5 (Assyrian Empire) has 1 cities, 7 pop, 76 power, 94 tech percent
[188397.094] Team 5 has met: 3,
[188397.250] AI_settleMove: Moving settler at (65,17)
[188397.250] AI_settleMove: Going through 4 city sites
[188397.250] AI_settleMove: Best found value in area: 3863
[188397.250] AI_settleMove: Best found value overseas: 1881
[188397.250] AI_settleMove: Group can't defend itself
[188397.266] AI_settleMove: Considering to move to site (59,17)
[188397.266] AI_settleMove: Site not guarded and can't self-defend
[188397.266] AI_settleMove: Considering to move to site (69,19)
[188397.266] AI_settleMove: Site not guarded and can't self-defend
[188397.266] AI_settleMove: Considering to move to site (65,14)
[188397.266] AI_settleMove: Site not guarded and can't self-defend
[188397.266] AI_settleMove: Considering to move to site (55,11)
[188397.266] AI_settleMove: Site not guarded and can't self-defend
[188397.266] AI_settleMove: No valid site to move to
[188397.266] AI_settleMove: Failed to move to any local city site
[188397.266] AI_settleMove: Attempting to meet an escort
[188397.266] AI_settleMove: No escort found
[188397.281] City Nineveh finishes production of unit Archer with UNITAI counter
[188397.281] City Nineveh pop 7 considering new production: iProdRank 1, iBuildUnitProb 16, iBestBuildingValue 0


For fun, I gave this AI a bunch of infantry units. Still refused to settle . . .
 
Last edited:
Hey, thanks for trying to help. Pretty much all units in my mod have an instance cost modifier, but this has been a feature of it for a long time.
When estimating increases in military power, the UWAI component tries to determine "typical" offensive and defensive units that a civ has access to. Units with InstanceCostModifier > 5 are disregarded in that context. It's been that way at least since v0.95. Sounds like that part hasn't really been working in your mod for some time then. I guess I should factor the InstanceCostModifier into the unit's production cost instead of just ignoring the unit. (Ideally, the AI should check how many of those units already exist, but that gets a bit too complicated for an ability that I don't currently use myself.)

At any rate, that explains the failed assertions but not the lack of settler escorts (UWAI doesn't affect tactical movement).
The footman has city defense as a non-AI. Would this disqualify it from defending a site? I see footmen near city sites. But, I see in the base mod that warriors have this tag too.
That shouldn't stop a unit from accompanying a settler; attack, reserve and city defense units get to do that. Exploration and reserve units can guard planned city sites.

"Group can't defend itself" – My guess is that no units join the settler's selection group. Meaning that, in Debug mode, Shift+Alt hover would show "Leading Group(...), 1 units" for the settler. I assume that the Archers have the city defense AI type (Ctrl hover would tell). An AI_group(UNITAI_SETTLE, ...) call is right at the start of the AI_cityDefenseMove routine. That call would fail ... if the Settler doesn't have the "settle" AI type, if Settler and Archer don't have the same impassable terrains and features (that could be it perhaps?). Bunch of other conditions that don't seem like likely culprits, but who knows; I may have to insert some more logging code.
 
That call would fail ... if the Settler doesn't have the "settle" AI type, if Settler and Archer don't have the same impassable terrains and features (that could be it perhaps?). Bunch of other conditions that don't seem like likely culprits, but who knows; I may have to insert some more logging code.

The impassables are similar for archers and settlers and, I also gave this AI a bunch of infantry and it still wouldn't settle. Interestingly, one AI in this test game did settle a second city on an island. This AI also has a galley with an archer and a settler inside it, presumably looking to settle somewhere. It really is crazy the stacks of archers the AI is building without settling. One particular AI is sitting on 20 military units. I haven't seen anything like it in prior versions.

Here is the log for the AI that settled:
Spoiler :
[188374.000] Player 6 (Japanese Empire) setTurnActive for turn 87 (2700 BC)
[188374.000] Player 6 (Japanese Empire) has 1 cities, 4 pop, 45 power, 100 tech percent
[188374.000] Team 6 has met:
[188374.047] AI_settleMove: Moving settler at (11,23)
[188374.047] AI_settleMove: Going through 2 city sites
[188374.047] AI_settleMove: Best found value in area: 0
[188374.047] AI_settleMove: Best found value overseas: 1184
[188374.047] AI_settleMove: Looking for a transport
[188374.125] Team 6 (Tokugawa) acquires tech Bronze Working
[188374.125] City Kyoto pop 4 considering new production: iProdRank 1, iBuildUnitProb 13, iBestBuildingValue 216
[188374.141] City Kyoto needs escort for existing settler
[188374.141] City Kyoto pushes production of unit Archer with UNITAI city defense
[188374.141] City Kyoto uses escort existing settler 1 defense


Spoiler :
[188384.594] Player 6 (Japanese Empire) setTurnActive for turn 89 (2650 BC)
[188384.594] Player 6 (Japanese Empire) has 1 cities, 4 pop, 53 power, 100 tech percent
[188384.594] Team 6 has met:
[188384.641] AI_settleMove: Moving settler at (12,26)
[188384.641] AI_settleMove: Going through 2 city sites
[188384.641] Settler founding in place since it's at a city site 12, 26
[188384.656] Player 6 (Japanese Empire) founds new city Osaka at 12, 26
[188384.688] City Osaka pop 1 considering new production: iProdRank 2, iBuildUnitProb 3, iBestBuildingValue 123
[188384.688] City Osaka uses no defenders
[188384.688] City Osaka pushes production of unit Archer with UNITAI city defense
 
Last edited:
The impassables are similar for archers and settlers and, I also gave this AI a bunch of infantry and it still wouldn't settle.
"Similar" might not be good enough though; the code checks for an equal number of impassable terrain plus feature types. For fixing the InstanceCostModifier issue, it would be helpful to know what values you typically use. (Or if you zip up your Civ4UnitInfos.xml and upload it here or in a private message, I'll take a look myself.)

I'm attaching an assert DLL with tracing added to K-Mod's AI_omniGroup function. Again via the BBAI log. Sample output:
Spoiler :
Code:
Player 0 (French Empire) has 1 cities, 3 pop, 36 power, 70 tech percent
    Team 0 has met: 2,
      Unit at (36,36) attempts to form group with a settler. iMaxGroup=2, iMaxPath=3
      Not in cargo. OK.
      can-group-with-AI-type check OK.
      There are settlers on this landmass. OK.
      Our impassable count: 0
      Going through all groups; looking for a settler.
      Group at (36,36)
      Can move to that plot. OK.
      It's a group with settle AI. OK.
      Groups are allowed to join. OK.
      BiggerOnly condition met. OK.
      SafeOnly condition met. OK.
      iMinUnitAI condition met. OK.
      iMaxOwnUnitAI condition met. OK.
      iMaxGroup condition met. OK.
      MissionAIType condition met. OK.
      Checking impassable count
      Impassable counts compatible. OK.
      Able to reach the settler group. OK.
      New best settler group found
      Group at (31,18)
      Can move to that plot. OK.
      Not a group with a settler or otherwise invalid
      Group at (37,35)
      Can move to that plot. OK.
      Not a group with a settler or otherwise invalid
      Group at (36,36)
      Can move to that plot. OK.
      Not a group with a settler or otherwise invalid
      Group at (36,36)
      Can move to that plot. OK.
      Not a group with a settler or otherwise invalid
      Group at (36,36)
      Can move to that plot. OK.
      Not a group with a settler or otherwise invalid
      Attempting to join settler group at (36,36)
      Merging into settler group
    Settler heading for site 40, 34
Interestingly, one AI in this test game did settle a second city on an island. This AI also has a galley with an archer and a settler inside it, [...]
Going by transport probably doesn't involve AI_omniGroup.
 

Attachments

  • CvGameCoreDLL.zip
    2.2 MB · Views: 102
"Similar" might not be good enough though; the code checks for an equal number of impassable terrain plus feature types. For fixing the InstanceCostModifier issue, it would be helpful to know what values you typically use. (Or if you zip up your Civ4UnitInfos.xml and upload it here or in a private message, I'll take a look myself.)

The range is 3 - 18. I attached my unitclassinfos file if you need more information. I'm about to run tests with the new game core.

Terrain/Feature Impassables
Archers: Tundra (compass), Snow (compass); Jungle, Arid, Marsh (compass)
Settlers: Tundra (optics), Snow (optics); Jungle, Arid

The archer impassables are similar to most pre-gunpowder units. Post gunpowder units generally only have Jungle and Arid as impassables.

Log for AI's first attempt at settling:
Spoiler :
Player 6 (Sumerian Empire) setTurnActive for turn 29 (4840 BC)
Player 6 (Sumerian Empire) has 1 cities, 2 pop, 19 power, 100 tech percent
Team 6 has met:
Unit at (15,15) attempts to form group with a settler. iMaxGroup=1, iMaxPath=0
Not in cargo. OK.
can-group-with-AI-type check OK.
Our impassable count: 5
Going through all groups; looking for a settler.
Group at (15,15)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,14)
Group at (15,15)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,15)
Can move to that plot. OK.
It's a group with settle AI. OK.
Groups are allowed to join. OK.
BiggerOnly condition met. OK.
SafeOnly condition met. OK.
iMinUnitAI condition met. OK.
iMaxOwnUnitAI condition met. OK.
iMaxGroup condition met. OK.
MissionAIType condition met. OK.
Checking impassable count
Unit at (15,15) attempts to form group with a settler. iMaxGroup=2, iMaxPath=3
Not in cargo. OK.
can-group-with-AI-type check OK.
Our impassable count: 5
Going through all groups; looking for a settler.
Group at (15,15)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,14)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,15)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,15)
Can move to that plot. OK.
It's a group with settle AI. OK.
Groups are allowed to join. OK.
BiggerOnly condition met. OK.
SafeOnly condition met. OK.
iMinUnitAI condition met. OK.
iMaxOwnUnitAI condition met. OK.
iMaxGroup condition met. OK.
MissionAIType condition met. OK.
Checking impassable count
Unit at (15,15) attempts to form group with a settler. iMaxGroup=1, iMaxPath=0
Not in cargo. OK.
can-group-with-AI-type check OK.
Our impassable count: 5
Going through all groups; looking for a settler.
Group at (15,15)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,14)
Group at (15,15)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,15)
Can move to that plot. OK.
It's a group with settle AI. OK.
Groups are allowed to join. OK.
BiggerOnly condition met. OK.
SafeOnly condition met. OK.
iMinUnitAI condition met. OK.
iMaxOwnUnitAI condition met. OK.
iMaxGroup condition met. OK.
MissionAIType condition met. OK.
Checking impassable count
Unit at (15,15) attempts to form group with a settler. iMaxGroup=2, iMaxPath=3
Not in cargo. OK.
can-group-with-AI-type check OK.
Our impassable count: 5
Going through all groups; looking for a settler.
Group at (15,15)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,14)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,15)
Can move to that plot. OK.
Not a group with a settler or otherwise invalid
Group at (15,15)
Can move to that plot. OK.
It's a group with settle AI. OK.
Groups are allowed to join. OK.
BiggerOnly condition met. OK.
SafeOnly condition met. OK.
iMinUnitAI condition met. OK.
iMaxOwnUnitAI condition met. OK.
iMaxGroup condition met. OK.
MissionAIType condition met. OK.
Checking impassable count


Edit: OK, progress! I simply added Marsh (compass) to Settlers as a feature impassable and now AIs are settling. This is a fine solution to me for that issue as Marsh can't be settled anyways and it is not a wide occurring feature.

I still got the two assertion errors and I'm not sure how this will effect post Gunpowder units that have less impassables.
 

Attachments

  • CIV4UnitClassInfos.xml
    47.7 KB · Views: 98
Last edited:
The range is 3 - 18. I attached my unitclassinfos file if you need more information.
Oh, that's based on unit class, right. Thanks, that's helpful. I guess I'll keep writing off units with cost modifier >=20 as unsuitable for mass production. For values smaller than 20, I'll come up with some formula to convert them into a fixed production cost.
Terrain/Feature Impassables
Archers: Tundra (compass), Snow (compass); Jungle, Arid, Marsh (compass)
Settlers: Tundra (optics), Snow (optics); Jungle, Arid
The archer impassables are similar to most pre-gunpowder units. [...]
Log for AI's first attempt at settling: [...]
Yup, that's 5 != 4 at game start. So a settler can pass through marshes but most other units can't. Meaning that they can't protect the settler there. It won't really need protection there either, but I'm not sure if the AI will manage to split the group up when it reaches a marsh. So just removing the check for impassable counts may not fully solve the problem. Is it important to you that settlers be able to move through (settle on?) marshes? (n/m)
Post gunpowder units generally only have Jungle and Arid as impassables.
At the least, it would be nice if a settler could form a group with units that have fewer impassables than the settler. I don't suppose that would cause problems; the settler would be the group leader (has the highest AI_groupFirstVal).
Edit: OK, progress! I simply added Marsh (compass) to Settlers as a feature impassable and now AIs are settling. This is a fine solution to me for that issue as Marsh can't be settled anyways and it is not a wide occurring feature.
OK, great.
I still got the two assertion errors and I'm not sure how this will effect post Gunpowder units that have less impassables.
So I'll allow settlers to be joined by units with fewer impassables; or maybe, more generally, ensure only that units with higher AI_groupFirstVal don't have fewer impassables. And the assertions will hopefully go away when the instance cost modifier issue is fixed. (Well, I'll upload a release DLL eventually, which won't show failed assertions anyway.)
 
Last edited:
Thanks again, and I hope I not bothering you too much with these issues! Do you want to be notified of assert errors?

Do you think this is tied to the instance cost issue too?

Assert Failed
File: ..\.\InvasionGraph.cpp
Line: 885
Func: InvasionGraph::Node::step
Expression: attCities <= 0
Message: No typical army unit found

Other misc assert errors:

Spoiler :
Assert Failed
File: ..\.\CvSelectionGroupAI.cpp
Line: 161
Func: CvSelectionGroupAI::AI_update
Expression: iAttempts != iMaxAttempts - 5
Message: Unit stuck in a loop

Assert Failed
File: ..\.\CvCity.cpp
Line: 6942
Func: CvCity::setBaseYieldRate
Expression: iNewValue >= 0
Message:

Assert Failed
File: ..\.\CvCity.cpp
Line: 6946
Func: CvCity::setBaseYieldRate
Expression: getYieldRate(eIndex) >= 0
Message:

Assert Failed
File: ..\.\CvGameTextMgr.cpp
Line: 16415
Func: CvGameTextMgr::getAttitudeString
Expression: iTotal == iTotalCached
Message: Attitude cache out of date (OK after loading a save created prior to v0.95 or Alt+Z)

Assert Failed
File: ..\.\CvPlayer.cpp
Line: 13272
Func: CvPlayer::doGold
Expression: isHuman()
Message:

Assert Failed
File: ..\.\CvCity.cpp
Line: 7010
Func: CvCity::changeBonusYieldRateModifier
Expression: getYieldRate(eIndex) >= 0
Message:

Assert Failed
File: ..\.\CitySiteEvaluator.cpp
Line: 1571
Func: AIFoundValue::estimateImprovementProduction
Expression: iYieldChange <= 3
Message: is this much production possible?

Assert Failed
File: ..\.\CvCity.cpp
Line: 6974
Func: CvCity::changeYieldRateModifier
Expression: getYieldRate(eIndex) >= 0
Message:

Assert Failed
File: ..\.\CvUnitAI.cpp
Line: 18653
Func: CvUnitAI::AI_airOffensiveCity
Expression: canAirAttack() || nukeRange() >= 0
Message:

Assert Failed
File: ..\.\CvUnitAI.cpp
Line: 3531
Func: CvUnitAI::AI_attackCityMove
Expression: false
Message: AI_attackCityMove is resorting to AI_solveBlockageProblem

Assert Failed
File: ..\.\CvCityAI.cpp
Line: 7542
Func: CvCityAI::AI_getImprovementValue
Expression: iCorrectedFoodPriority == iFoodPriority || (iCorrectedFoodPriority < iFoodPriority == weighted_yield_diffs[YIELD_FOOD] > 0)
Message:

Assert Failed
File: ..\.\CvUnitAI.cpp
Line: 18627
Func: CvUnitAI::AI_pickupStranded
Expression: false
Message:
 
Last edited:
The new "breaking ground" mechanic works great at slowing down runaways. I've ran two test games and I am pleased with how it works. I also use the BBAI tech diffusion mechanic, so there is less a spread of tech levels from top to bottom. This makes for a more interesting game to me.
 
Do you think this is tied to the instance cost issue too? [...] Message: No typical army unit found
Yes, I assume so. You could test this by setting the instance cost modifier of Warrior to 0. Other units will still not be recognized as "typical" units, so it doesn't solve the problem, but it should shut those assertions up.
Thanks again, and I hope I not bothering you too much with these issues! Do you want to be notified of assert errors?
I'd like the mod to have some robustness wrt. XML modding, so I'm glad to be at least aware of the potential (game-breaking) problems with impassable terrain now. I also don't mind looking into smaller issues, though failed assertion are difficult to diagnose remotely, i.e. without a debugger. So, if you don't mind reporting them (maybe) in vain, do let me know if additional ones come up.

These here are probably harmless:
Spoiler :
"Attitude cache out of date"
That'll happen in some rather rare circumstances, not just the ones stated in the assert message. Not really a concern.

"CvPlayer::doGold"
I also get this one once every few games. It means that the AI has to disband a unit because of a strike. OK if it's rare. Usually, it's only for one turn and happens when the AI goes into more than 1 turn of anarchy (meaning no income) while still having to pay gold for some resource deal. Actually, I'll change the condition to isHuman() || isAnarchy().

"AI_attackCityMove is resorting to AI_solveBlockageProblem"
This one I also see once every couple of games at least. An unresolved problem, but a pretty harmless one.

"iYieldChange <= 3
Message: is this much production possible?"
OK if you do have an improvement that adds 4 or more production to a regular (i.e. non-resource) tile. Civics (and railroads) aren't counted in that context, so a BtS Workshop would only add 3 production.
The others are more worrisome:
Spoiler :
"CvUnitAI::AI_airOffensiveCity"
Apparently, there's a unit with AI type UNITAI_ATTACK_AIR, UNITAI_MISSILE_AIR or UNITAI_ICBM that has a non-positive air combat strength and a negative nuke range – meaning that it's unable to air-attack.

"Unit stuck in a loop"
Could well be related to impassable tiles. If it occurs often, I could insert some tracing code. In any case, I'll at least add some code that writes the group id and map coordinates to the MessageLog (MPLog.txt; the BBAI log is normally disabled from within the DLL) ... Well, dang, such code is already in place. So, if MessageLog is set to 1, it writes the name, coordinates, unit AI type and name of owner to MPLog.txt.

"CvCity::setBaseYieldRate"
These could come from a lot of places; anything that factors into city yield rates. Maybe some ability of a building or specialist that is unused in BtS and not properly implemented, or perhaps a yield penalty, e.g. a building that is supposed to decrease a city's production rate. (Though it's not obvious to me why such a building shouldn't work correctly.)
"CvCity::changeBonusYieldRateModifier" and "CvCity::changeYieldRateModifier"
-- could also be related (though I guess they occurred later than the above ...) and would point toward some bonus resource and a building with a negative yield modifier as the culprits.
If the issue is simply that e.g. a city with 0% production modifier constructs an "Anti-Forge" with -25% production, then it's probably OK as it is. So long as you're noticing any strange behavior.

"CvCityAI::AI_getImprovementValue"
This one I'm pretty clueless about.

Edit: The research penalties – just out of curiosity, how high did you set the per-era penalties?
 
Last edited:
Edit: The research penalties – just out of curiosity, how high did you set the per-era penalties?

From Classic to Future:
10 - 20 - 30 - 30 - 20 - 10

They were half that on the first few run throughs and I didn't notice enough of a difference. These numbers (combined with 100% tech diffusion) create a lot of tech parity. The "big dog" AIs are still leading in tech, but the mid pack AIs are not falling whole eras behind. I may scale back the modern era modifier to speed that era up a bit.

No, I'm not noticing anything unusual with respect to the other errors. After reading your explanations, I think I know what is causing most of them, and it doesn't break the game. The air unit is probably my nuclear bomber. AI manages to use it just fine :lol:

Edit: Btw, the latest game core helped me catch a lot of my own internal XML errors. Thanks :thumbsup:
 
Last edited:
Potential bug: I was at war with a particular AI and we made peace. A few turns after the mandatory no war period expired, this AI offered me a peace treaty in exchange for two cities. We were not at war.

Edit: AI is routinely including peace treaties with normal trade offerings.
 
Last edited:
I've started a branch for v0.97b – not much in it yet except the changes for @Cruiser76; I'll add more (as more issues are discovered) before making a proper release.
- Better handling of per-instance (unit production cost) modifiers and impassable terrain and feature types
- Addresses minor issues with the 2nd AI settler having to wait for an escort sometimes
- Some minor tweaks to the evaluation of potential starting sites
- Tiles with goody huts are no longer off limits as starting sites; the hut gets removed if its tile gets chosen as a starting site.
- Fixes a rare bug that had caused Barbarian Galleys to get "stuck in a loop" – probably inconsequential, but had triggered an assertion. Also disables an assertion about AI civs on strike during anarchy.

DLL: final-release build | assert build

Took a while to work out how "impassables" should affect AI group formation. Not sure if I really got it right either. The basic approach is now that no unit in a group must have more restrictive movement rules than the unit that leads the group. That group leader controls the behavior of the whole group and is determined, as before, mainly based on UNITAI type (function AI_groupFirstValue). For example, UNITAI_SETTLE has the highest priority for group leadership. So, if a Settler can enter, let's say, all terrain/features and a Warrior can't enter Desert, then the Warrior can't join the group and thus can't escort the Settler – because the Settler would remain the group leader. If a Settler - different example - cannot enter Jungle and Snow, while an Infantry can go everywhere except Jungle, then the Infantry is allowed to join the Settler. If the newcomer and group leader have the same AI_groupFirstValue – perhaps both are non-siege city attackers –, then joining is only allowed if they have the exact same impassables (not just the same number impassables). As I type it down now, it seems pretty clear that a suitable number of impassables should never be sufficient for joining a group; set inclusion needs to be checked really. As it is, Infantry that can't enter Desert could still join a Settler that cannot enter Snow and Jungle (but can enter Desert). Not sure if that would really be a problem, but it's at least inconsistent.

[...] The game was acting very buggy and crashing when I would leave the game window.
I've noticed a bug in my old code (now replaced) for handling InstanceCostModifiers. It had treated unit type ids as unit class type ids; that could've crashed the game erratically through out-of-bounds array accesses.
Potential bug: I was at war with a particular AI and we made peace. A few turns after the mandatory no war period expired, this AI offered me a peace treaty in exchange for two cities. We were not at war.
If it was just one city, then I'd assume that this was actually a gift or tribute dialog. Those show the implied peace treaty as a trade item now. But I don't see how the AI could ask for two cities at once that way. From looking at the code, I also don't see the AI could enter peace negotiations while at war or get confused about being at war. The code for that is pretty straightforward.
Edit: AI is routinely including peace treaties with normal trade offerings.
That's OK if they're help requests or tribute demands, i.e. if there's only the peace treaty on your side of the table. If they're actual trade offers, then something is wrong.
From Classic to Future:
10 - 20 - 30 - 30 - 20 - 10
Thanks; nice that this does the job – doesn't sound too drastic.
 
That's OK if they're help requests or tribute demands, i.e. if there's only the peace treaty on your side of the table. If they're actual trade offers, then something is wrong.

So I assume the offer in this screenshot is bugged? I've gotten dozens of these in my current game (0.97a). In my previous game (0.97-pre2, I believe) I didn't get a single one.

Oh, and since I didn't say it earlier - thanks for this mod! Despite small bugs (like Space Race victory being completely broken :)) the AI is a huge improvement over unmodded BtS.
 

Attachments

  • peacedeal.jpg
    peacedeal.jpg
    240.7 KB · Views: 117
So I assume the offer in this screenshot is bugged? [...]
No, that program behavior is fine with me. I got my explanation wrong. I'll try again: It's intentional that the AI offers a peace treaty – and nothing else – when it asks for help or demands tribute. I thought this change would be self-explanatory and a welcome reminder that granted help and tribute result in a peace treaty. Seeing that it confuses more than one person, that may have been the wrong call. Maybe I'll make the peace treaty implicit again; not sure how easy that would be to do.
Oh, and since I didn't say it earlier - thanks for this mod! Despite small bugs (like Space Race victory being completely broken :)) the AI is a huge improvement over unmodded BtS.
Each time I check the forum for alerts, I expect that someone has reported another game-breaking issue; so far, I'm pleasantly surprised. Well, this was the first time that there has been a sort of beta period before the release; that sure helped.
 
Ending a war and signing a peace treaty are different things (as you are aware), but BtS doesn't make that distinction very clear.
(I probably should mention that I'm another Linux user so it also could be a Wine issue.)
I should've guessed from the weird font in the screenshot.
Anyway, I just finished a 15 hour Epic speed large map game - this time with a successful Space Race victory. The game crashed twice in the late game but I couldn't reproduce either of them. I'll post a save file if I can produce something that consistently crashes.
I suppose BtS doesn't randomly crash under Wine, so, while the crash could be Wine-related, it's probably still caused by modified code. That happened in between turns? Enabling assertions and logs – the more the better – might be all we can do. The assert build I've posted doesn't have the BBAI log enabled, but perhaps that's dispensable. The RandLog (CivilizationIV.ini; writes to MPLog.txt and therefore also requires MessageLog=1) tracks AI unit movement and some other parts of the code very closely. Python event logging can be enabled in CvEventManager.py (self.__LOG_ALL=1; writes to PythonDbg.log and therefore requires LoggingEnabled=1 in the .ini).
i think i found some stuff in the code (forcebuilding)
I'll take a look.
 
Ok, the peace treaty inclusion makes sense now. It was always part of the deal, just hidden. I think the name is what is confusing. It is more of a non aggression treaty. Most people think of a peace treaty as ending a war. It is more of a semantic thing.
 
hey,

had this assertion happen :

if (pAreaTargetCity != NULL)
{ /* advc: One way that this can happen: Owner is at war with a civ that
it can only reach through the territory of a third party (no OB) and
is preparing war against the third party.
AI_pickTargetCity will then pick a city of the current war enemy, but
the Area AI will be set to a non-ASSAULT type, meaning that AI_attackCityMove
will (in vain) look for a land path. AI_solveBlockageProblem will then (always?)
fail, and the unit won't move at all. This is probably for the best -- wait
until the preparations are through. Difficult to avoid the assertions below. */
/* this is a last resort. I don't expect that we'll ever actually need it.
(it's a pretty ugly function, so I /hope/ we don't need it.) */
//keldath - f1 suggested to remove this assert.
FAssertMsg(false, "AI_attackCityMove is resorting to AI_solveBlockageProblem");


autoplay


also:

Spoiler :

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// class : CvCultureLevelInfo
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class CvCultureLevelInfo : public CvInfoBase
{
public:
CvCultureLevelInfo();
~CvCultureLevelInfo();
int getCityDefenseModifier() const; // Exposed to Python
int getSpeedThreshold(int i) const; // Exposed to Python
bool read(CvXMLLoadUtility* pXML);
static CultureLevelTypes finalCultureLevel()
{
FAssert(GC.getNumCultureLevelInfos() > 0);
return (CultureLevelTypes)(GC.getNumCultureLevelInfos() - 1);
}
protected:
int m_iCityDefenseModifier;
int* m_paiSpeedThreshold;
}; MISSING ;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// class : CvEmphasizeInfo
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

another missing ';'

else
{
VoronoiCell::iterator pos = kCell.find(ePlotNum);
if (pos != kCell.end())
kCell.erase(pos);
else FAssert(pos != kCell.end());
}
}
in StartingPositionIteration.cpp(304): error C2143: syntax error : missing ';' before '}'

just letting you know.
 
Last edited:
Top Bottom