OK, I've done some more fiddling and looking at code in the DLL. The news is not so good.
The fact that is sometimes crashes and sometimes doesn't would seem to indicate that there is a problem in some area that has a random chance applied to it. This is probably only indirectly the case (down in the section labeled in Part II is a more specific probable cause).
Based on adding a print statement to the doGold callback, I can say that it seems to always crash before it gets to that but after the end of the onBeginPlayerTurn Python function's processing of the beginPlayerTurn event. This narrows it down some (after line 2568 and before line 2597 of CvPlayer.cpp), but quite a bit happens in that interval.
So first some stuff about things I fixed (Part I) then some bad news (Part II).
Part I:
Via XML adjustments I have the crash rate is down to something like 20% of the time for the posted save - most of the time you can click on the second end turn and it does not crash. (So there are issues with the XML that may cause crashes, but it is possible that the XMl adjustments just shifted things around in memory a little which had an indirect accidental effect on the specific crash cause.)
Much later in a game, continued from the save, I have seen a couple of crashes. Mostly right after loading from a save. I also got a weird occurrence: it appeared to lock up, so it went to the task manager to kill it and noticed that it was doing a fair amount of I/O. I found that it was creating an ever increasing in size autosave file - it was up to about 19.5MB when I killed it.
Here is a list of stuff I fixed in the XML:
Code:
CIV4ArtDefines_Unit.xml:
- ART_DEF_UNIT_THORUSHKA: the NIF and SHADERNIF sepcify the wrong folder
NIF says Art/Units/Dilgar_Imperium_Ships/Dilgar_Thorun/Dilgar_AdvFighter.nif
this should be Art/Units/Dilgar_Imperium_Ships/Dilgar_Thorushka/Dilgar_AdvFighter.nif
SHADERNIF says Art/Units/Dilgar_Imperium_Ships/Dilgar_Thorun/Dilgar_AdvFighter_FX.nif
there is no such .nif file anywhere, so it should probably match the corrected regular NIF
- ART_DEF_UNIT_SEKHMET: the NIF entry has a typo
NIF says ">Art/Units/Dilgar_Imperium_Ships/Dilgar_Sekhmet/Dilgar_Sekhmet.nif", note the leading extraneous ">"
- the defense units (ODS, PDS, ODP) had bad sound defines for SelectionSound and ActionSound
all set to AS3D_UN_FIGHTER_COMMAND_PATROL changed to AS3D_UN_FF_FIGHTER_COMMAND_PATROL
and thsoe with PatrolSound set to AS3D_UN_FIGHTER_PATROL changed to AS3D_UN_FF_FIGHTER_PATROL
- Also, just in case:
changed Narn_ToReth to Narn_Toreth to match the actual case of the folder
changed Narn_RonGoth.nif to Narn_Rongoth.nif to match the actual file name
In CIV4TechInfos.xml TECH_B5_ADV_CYBERNETICS has a prereq of B5_TECH_CYBERNETICS, which should be TECH_B5_CYBERNETICS
AudioDefines.xml:
- SND_TECH_B5_SMALL_ATTACK_CRAFT is missing, added entry for it (sound file did exist)
CIV4BuildingInfos.xml
- BUILDING_MANUFACTURING_PLANT had an extra iCostModIncrease entry at the end
CIV4LeaderHeadInfos.xml
- LEADER_BARBARIAN had a specifically set favorite civic of NONE, like so:
<FavoriteCivics>
<FavoriteCivic>
<CivicType>NONE</CivicType>
<bFavoriteCivic>1</bFavoriteCivic>
</FavoriteCivic>
</FavoriteCivics>
which seems like a bad plan, changed to "<FavoriteCivics/>"
CIV4UnitInfos.xml - has some bad XML:
- 2 units with UnitClassTargets (UNIT_ALIEN_INVASION_SHIP and UNIT_ALIEN_SCOUT)
and 3 with UnitClassDefenders (UNIT_PLANETARY_DEFENSE_I, _II, and _III) that are are specified wrong
they just give a unit class instead of having the required sub-tags, i.e.
UNIT_ALIEN_INVASION_SHIP has <UnitClassTargets>UNITCLASS_STARBASE_I</UnitClassTargets>
when it should have
<UnitClassTargets>
<UnitClassTarget>
<UnitClassTargetType>UNITCLASS_STARBASE_I</UnitCombatTargetType>
<bUnitClassTarget>1</bUnitCombatTarget>
</UnitClassTarget>
</UnitClassTargets>
THe first few art define issues where identified by running CivChecker on the mod. The rest were found by identifying the causes of various messages in all the log files and such.
I also applied some Python fixes, at least some of which were mentioned earlier in this thread (that I though had already been applied). Also, some of these were just to reduce the clutter in the PythonDbg.log file.
Also, Config\Unit Naming.xml is missing from the mod.
The promotions seem to be a bit of a mess, but I didn't try to sort it out. Their relationships are so convoluted that the function that maps the upgrade paths you can follow can't do it.
After all that messing around, it is not fixed.
Anyhow, now we get to some pretty bad news...
Part II:
I found something in the DLL that leads me to beleive that having units classes with a default unit type of NONE (or the various non-existant ship times like BATTLESHIP_I, which are effectively identical to NONE) won't work.
In fact, I'm surprised it doesn't crash more. Like the instant an AI spots somebody else's ship.
The issue is in the CvPlayerAI::AI_doEnemyUnitData() function.
Lines 16720 and 16721 in CvPlayerAI.cpp:
Code:
UnitTypes eUnit = (UnitTypes)GC.getUnitClassInfo((UnitClassTypes)iI).getDefaultUnitIndex();
m_aiUnitCombatWeights[GC.getUnitInfo(eUnit).getUnitCombatType()] += m_aiUnitClassWeights[iI];
The first line there gets the default unit type for a unit class. Most unit classes in B5 do not have a valid default unit type. They are all effectively "NONE" which, in this case, translates to a value of -1 being assigned to eUnit (which is the NO_UNIT value in the UnitTypes enumeration).
The second line tries get a unit info for that unit type of -1. This is not valid. If a debug DLL was being used the getUnitInfo would fire off a failed assert, but asserts do nothing when not using a debug DLL. Therefore, it will return random junk (whatever is pointed to by the value in memory right before the start of the array) interpreted as a unit info type object. It then gets the unit combat type of the junk (which I'm a little surprised actually works) and uses that junk number as an index into the m_aiUnitCombatWeights array (it could easily be way outside the bounds of the actual array, negative or past the end - but since it frequently doesn't crash, I'm thinking it is probably lucking out most of the time and getting a 0 since a lot of memory is set to 0 a lot of the time).
That is assuming it gets this far before the crash (I suspect it is, but I'm not sure).
A debug version of the 1.72 DLL would probably locate the problem more directly, but I haven't got one. (You'd have to click through a couple hundred failed assertions when loading the XML relating to non-existant buildings and units - I know because I clicked past them using a 1.73 debug DLL which works up until it loads the options from the save game, since 1.73 has an additional option causing it to fail then.)
The actual crash could also be after this, but this code all by itself leads to one conclusion:
You can not actually get away with using unit classes that do not have valid default units. Even it it doesn't crash at this location it can not possibly be correctly evaluating the other civs' units (that's what those two lines of code are part of).
As unfortunate as it seems, I think you have to go though and make the ship classes into proper unique units. That would be the "option A"
I mentioned over in post #35 in the Final Frontier Plus BUG thread, and mentioned again at the end of post #43 over there. Evidently it is not just BUG that wants this, it is the DLL (I knew there were issues with either buildings or units with invalid default types, but can never remember which - it looks like it is units, although I suppose it could be both).