Quick Modding Questions Thread

Do you know any mod, that logs reasons of OOS? Or modder must guess the error's line

No such mod exists, it's not really possible. OOS errors are never caused by a single line of code, but rather code design that doesn't take multiplayer into consideration. I strongly recommend reading this guide for an understanding of how they occur and how to try solve them.

Are python mods less stable in multiplayer then SDK ones?

No.
 
Thank you, Xyth, I have already read that guide. Do you know something about the debug mode in multiplayer?

It's not possible, as far as I know.
 
So um... haven't played civ4 in years. I think it was 7 years since I last played it. Suddenly decided to give it a go and damn it's a good game after all.

Anyway thought about installing a few mods and I hit a wall. I realized I have no idea (not anymore at least) how this game was supposed to be modded. After some research around download section, mods threads and looking at how the game loads mods, it seems to me it's impossible to install say 4 different mods and play them all at once? I don't really want to go extreme with mods, it's more about nostalgia, so those "modpacks" mods seem way too excessive for me with their 250+ new this and 500+ new that and whatnot. For example I'd like more religion options and I found "Just Another Religion Mod" which seems to do exactly what I want. I'd also maybe like "Culturally Linked Starts", maybe "Ethnic Artstyles". And while I'd like those to work with "Next War" mod/scenario/whatever, it's not a must. So I'm quite lost here as to what to do and what can be done. If I'm to download "Just Another Religion Mod", does it mean I'll have to "LOAD MOD" it from main menu > advanced for it to work, meaning it won't work with "Next War" or with those other mods I mentioned? Which in turn would need to be loaded in a similar fashion, meaning only one mod can be played at a time?

In V or VI you just find all the mods you want and drop them into mods folder and that's it. There may be incompatibilities, but if you're not a complete idiot you usually can tell when something probably shouldn't mix.

Another problem is I'd like a simple vanilla style 18-civ earth map/scenario with TSL but different civs and/or old world civs only and maybe more than 18 civs. Haven't found an appropriate one for that. I saw plenty, but they seem to be, based on descriptions, out of date i.e. not compatible with the latest 3.19 build or otherwise something confusing about them.

Anyway, would love me some help/advice if you may.

Cheers.
 
Python mods are easy to merge for me. I know python better, than C++. Are python mods less stable in multiplayer then SDK ones?
I know it's a month old, but I feel like the answers fail to really tell what OOS issues are all about or what to do about them. As somebody who started out fixing OOS issues even before civ4 was released, I feel like I can contribute.

A game (all network games) desync if one of the following happens:
  1. something, which happens on one computer is not transmitted to the other computers
  2. something, which is calculated in sync doesn't provide the same result on all computers
1 is usually clicking buttons or keyboard keys to do something. Say a random event asks you to buy a unit for X gold. If you say yes, the other computers needs to know that you lost gold and a new unit exists.

2 is more evil. It can be a result of 1 happening first, meaning they fail to get the same input data to do the calculations. It could also be something like using system random instead of the game random. It can even be that the C++ code enters undefined code and the same code will not behave the same on all computers. Luckily all players use x86 and the same compiler, meaning this is not a likely scenario for us, but it can be a really annoying problem for cross platform games if they aren't using nice code.

It doesn't matter if you mod the DLL or python. Both can create and avoid desyncs. Both can send info across the network and both can fail to do so when they should have done so. The idea is that say for a city, call sendDoTask() when you have something to send on one computer and it will call CvCity::doTask() with the same arguments on all computer. There are similar functions for players, units etc. If you want to go really advanced, you can even define your own network functions, but most modders will have their needs covered by the vanilla functions (though they might be modded and with more enum values).

I merged some heavy mod components and created my own (SDK+Python) mod for BTS to play with friends. I works normally in singleplayer, but in multiplayer we have OOS error every time units compat. It is very difficult to test mod in multiplayer without console, worldbuilder and hotkeys.
My first suspicion would be aimed at the combat code itself. Check if random is called instead of the game random. The game random would look like this
PHP:
GC.getGameINLINE().getSorenRandNum(10, "some string for the log entry");
This provides a random number from 0 to 9. Python has the very same function as part of CyGame and can be used with the same arguments.

random() or getASyncRand() will give a completely random number while getSorenRandNum() gives a predictable random number. While this may sound like an oxymoron, it's actually a real scientific challenge to generate what feels like completely random numbers, but still can be predicted. The game does this and it will ensure that the same random number will appear on all computers. Do note that calling it twice will not give the same number twice and as such the function will break if called on just one computer.

The next one: Do you know any mod, that logs reasons of OOS? Or modder must guess the error's line.
The game calculates some sort of checksum based on a lot of stuff in the memory and it just transmit the checksum and it goes into OOS mode if two computers figures out they have different numbers. The checksum is a one way calculation, meaning it can't be used to tell what went wrong, only that something is different.

I have an idea on helping to find the cause. If in OOS mode, one player sends a message to make all computers save at the same time. Comparing the savegames can then tell what went wrong. However sadly the savegames aren't really human readable (possible, but a really massive task!). Instead it should print a text based savegame, telling a bunch of variables for plot 0, plot 1, unit 0 and so on. I might code this in some distant future, but so far the size of the project has given it too low priority to even start.
 
Anyway thought about installing a few mods and I hit a wall. I realized I have no idea (not anymore at least) how this game was supposed to be modded. After some research around download section, mods threads and looking at how the game loads mods, it seems to me it's impossible to install say 4 different mods and play them all at once?
The game can only load one mod at a time. This means if you want to use more than one, you have to merge them manually. It is possible to install mods as modules into an existing mod, but it has a bunch of pitfalls and shortcomings, particular if the DLL file is modded. I have never personally used modules inside a mod.
 
I know it's a month old, but I feel like the answers fail to really tell what OOS issues are all about or what to do about them. As somebody who started out fixing OOS issues even before civ4 was released, I feel like I can contribute.

A game (all network games) desync if one of the following happens:
  1. something, which happens on one computer is not transmitted to the other computers
  2. something, which is calculated in sync doesn't provide the same result on all computers
1 is usually clicking buttons or keyboard keys to do something. Say a random event asks you to buy a unit for X gold. If you say yes, the other computers needs to know that you lost gold and a new unit exists.

2 is more evil. It can be a result of 1 happening first, meaning they fail to get the same input data to do the calculations. It could also be something like using system random instead of the game random. It can even be that the C++ code enters undefined code and the same code will not behave the same on all computers. Luckily all players use x86 and the same compiler, meaning this is not a likely scenario for us, but it can be a really annoying problem for cross platform games if they aren't using nice code.

It doesn't matter if you mod the DLL or python. Both can create and avoid desyncs. Both can send info across the network and both can fail to do so when they should have done so. The idea is that say for a city, call sendDoTask() when you have something to send on one computer and it will call CvCity::doTask() with the same arguments on all computer. There are similar functions for players, units etc. If you want to go really advanced, you can even define your own network functions, but most modders will have their needs covered by the vanilla functions (though they might be modded and with more enum values).


My first suspicion would be aimed at the combat code itself. Check if random is called instead of the game random. The game random would look like this
PHP:
GC.getGameINLINE().getSorenRandNum(10, "some string for the log entry");
This provides a random number from 0 to 9. Python has the very same function as part of CyGame and can be used with the same arguments.

random() or getASyncRand() will give a completely random number while getSorenRandNum() gives a predictable random number. While this may sound like an oxymoron, it's actually a real scientific challenge to generate what feels like completely random numbers, but still can be predicted. The game does this and it will ensure that the same random number will appear on all computers. Do note that calling it twice will not give the same number twice and as such the function will break if called on just one computer.


The game calculates some sort of checksum based on a lot of stuff in the memory and it just transmit the checksum and it goes into OOS mode if two computers figures out they have different numbers. The checksum is a one way calculation, meaning it can't be used to tell what went wrong, only that something is different.

I have an idea on helping to find the cause. If in OOS mode, one player sends a message to make all computers save at the same time. Comparing the savegames can then tell what went wrong. However sadly the savegames aren't really human readable (possible, but a really massive task!). Instead it should print a text based savegame, telling a bunch of variables for plot 0, plot 1, unit 0 and so on. I might code this in some distant future, but so far the size of the project has given it too low priority to even start.
Thank you very much. I have already fixed the error, exporting functions to python and using onModNetMessage function. It is long, but it works. I will try the another way too.
 
Hello.
I posted over in unit design, but figured its more code related so I post here as well, in case someone could figure this out.

I got weird problem with unit crashing the game.

I have slightly modified version of original Phalanx which does the following:

If Phalanx attacks a War Elephant - all is fine

If War Elephant attacks a Phalanx - game crashes.

I have tested this by swapping phalanx models with generic spearman and still get same crash conditions, so it is not model related. War Elehphant is original BTS so I assume it is fine too.

So the problem got to be in the stats I modified for the Phalanx.

Here is the unit file info

Spoiler :


<UnitInfo>
<Class>UNITCLASS_SPEARMAN2</Class>
<Type>UNIT_GREEK_PHALANX</Type>
<UniqueNames/>
<Special>NONE</Special>
<Capture>NONE</Capture>
<Combat>UNITCOMBAT_MELEE</Combat>
<Domain>DOMAIN_LAND</Domain>
<DefaultUnitAI>UNITAI_COUNTER</DefaultUnitAI>
<Invisible>NONE</Invisible>
<SeeInvisible>NONE</SeeInvisible>
<Description>TXT_KEY_UNIT_GREEK_PHALANX</Description>
<Civilopedia>TXT_KEY_UNIT_GREEK_PHALANX_PEDIA</Civilopedia>
<Strategy>TXT_KEY_UNIT_GREEK_PHALANX_STRATEGY</Strategy>
<Advisor>ADVISOR_MILITARY</Advisor>
<bAnimal>0</bAnimal>
<bFood>0</bFood>
<bNoBadGoodies>0</bNoBadGoodies>
<bOnlyDefensive>0</bOnlyDefensive>
<bNoCapture>0</bNoCapture>
<bQuickCombat>0</bQuickCombat>
<bRivalTerritory>0</bRivalTerritory>
<bMilitaryHappiness>1</bMilitaryHappiness>
<bMilitarySupport>1</bMilitarySupport>
<bMilitaryProduction>1</bMilitaryProduction>
<bPillage>1</bPillage>
<bSpy>0</bSpy>
<bSabotage>0</bSabotage>
<bDestroy>0</bDestroy>
<bStealPlans>0</bStealPlans>
<bInvestigate>0</bInvestigate>
<bCounterSpy>0</bCounterSpy>
<bFound>0</bFound>
<bGoldenAge>0</bGoldenAge>
<bInvisible>0</bInvisible>
<bFirstStrikeImmune>0</bFirstStrikeImmune>
<bNoDefensiveBonus>0</bNoDefensiveBonus>
<bIgnoreBuildingDefense>0</bIgnoreBuildingDefense>
<bCanMoveImpassable>0</bCanMoveImpassable>
<bCanMoveAllTerrain>0</bCanMoveAllTerrain>
<bFlatMovementCost>0</bFlatMovementCost>
<bIgnoreTerrainCost>0</bIgnoreTerrainCost>
<bNukeImmune>0</bNukeImmune>
<bPrereqBonuses>0</bPrereqBonuses>
<bPrereqReligion>0</bPrereqReligion>
<bMechanized>0</bMechanized>
<bSuicide>0</bSuicide>
<bHiddenNationality>0</bHiddenNationality>
<bAlwaysHostile>0</bAlwaysHostile>
<UnitClassUpgrades>
<UnitClassUpgrade>
<UnitClassUpgradeType>UNITCLASS_SPEARMAN3</UnitClassUpgradeType>
<bUnitClassUpgrade>1</bUnitClassUpgrade>
</UnitClassUpgrade>
</UnitClassUpgrades>
<UnitClassTargets/>
<UnitCombatTargets/>
<UnitClassDefenders/>
<UnitCombatDefenders/>
<FlankingStrikes/>
<UnitAIs>
<UnitAI>
<UnitAIType>UNITAI_ATTACK</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
<UnitAI>
<UnitAIType>UNITAI_RESERVE</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
<UnitAI>
<UnitAIType>UNITAI_COUNTER</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
<UnitAI>
<UnitAIType>UNITAI_CITY_DEFENSE</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
</UnitAIs>
<NotUnitAIs/>
<Builds/>
<ReligionSpreads/>
<CorporationSpreads/>
<GreatPeoples/>
<Buildings/>
<ForceBuildings/>
<HolyCity>NONE</HolyCity>
<ReligionType>NONE</ReligionType>
<StateReligion>NONE</StateReligion>
<PrereqReligion>NONE</PrereqReligion>
<PrereqCorporation>NONE</PrereqCorporation>
<PrereqBuilding>NONE</PrereqBuilding>
<PrereqTech>TECH_IRON_WORKING</PrereqTech>
<TechTypes/>
<BonusType>NONE</BonusType>
<PrereqBonuses>
<BonusType>NONE</BonusType>
<BonusType>NONE</BonusType>
</PrereqBonuses>
<ProductionTraits/>
<Flavors/>
<iAIWeight>0</iAIWeight>
<iCost>60</iCost>
<iHurryCostModifier>0</iHurryCostModifier>
<iAdvancedStartCost>100</iAdvancedStartCost>
<iAdvancedStartCostIncrease>0</iAdvancedStartCostIncrease>
<iMinAreaSize>-1</iMinAreaSize>
<iMoves>1</iMoves>
<bNoRevealMap>0</bNoRevealMap>
<iAirRange>0</iAirRange>
<iAirUnitCap>0</iAirUnitCap>
<iDropRange>0</iDropRange>
<iNukeRange>-1</iNukeRange>
<iWorkRate>0</iWorkRate>
<iBaseDiscover>0</iBaseDiscover>
<iDiscoverMultiplier>0</iDiscoverMultiplier>
<iBaseHurry>0</iBaseHurry>
<iHurryMultiplier>0</iHurryMultiplier>
<iBaseTrade>0</iBaseTrade>
<iTradeMultiplier>0</iTradeMultiplier>
<iGreatWorkCulture>0</iGreatWorkCulture>
<iEspionagePoints>0</iEspionagePoints>
<TerrainImpassables/>
<FeatureImpassables/>
<TerrainPassableTechs/>
<FeaturePassableTechs/>
<iCombat>6</iCombat>
<iCombatLimit>100</iCombatLimit>
<iAirCombat>0</iAirCombat>
<iAirCombatLimit>0</iAirCombatLimit>
<iXPValueAttack>4</iXPValueAttack>
<iXPValueDefense>2</iXPValueDefense>
<iFirstStrikes>0</iFirstStrikes>
<iChanceFirstStrikes>0</iChanceFirstStrikes>
<iInterceptionProbability>0</iInterceptionProbability>
<iEvasionProbability>0</iEvasionProbability>
<iWithdrawalProb>0</iWithdrawalProb>
<iCollateralDamage>0</iCollateralDamage>
<iCollateralDamageLimit>0</iCollateralDamageLimit>
<iCollateralDamageMaxUnits>0</iCollateralDamageMaxUnits>
<iCityAttack>-25</iCityAttack>
<iCityDefense>-25</iCityDefense>
<iAnimalCombat>0</iAnimalCombat>
<iHillsAttack>0</iHillsAttack>
<iHillsDefense>0</iHillsDefense>
<TerrainNatives/>
<FeatureNatives/>
<TerrainAttacks/>
<TerrainDefenses/>
<FeatureAttacks/>
<FeatureDefenses/>
<UnitClassAttackMods/>
<UnitClassDefenseMods/>
<UnitCombatMods>
<UnitCombatMod>
<UnitCombatType>UNITCOMBAT_MOUNTED</UnitCombatType>
<iUnitCombatMod>100</iUnitCombatMod>
</UnitCombatMod>
<UnitCombatMod>
<UnitCombatType>UNITCOMBAT_MELEE</UnitCombatType>
<iUnitCombatMod>25</iUnitCombatMod>
</UnitCombatMod>
</UnitCombatMods>
<UnitCombatCollateralImmunes/>
<DomainMods/>
<BonusProductionModifiers>
<BonusProductionModifier>
<BonusType>BONUS_IRON</BonusType>
<iProductonModifier>0</iProductonModifier>
</BonusProductionModifier>
</BonusProductionModifiers>
<iBombRate>0</iBombRate>
<iBombardRate>0</iBombardRate>
<SpecialCargo>NONE</SpecialCargo>
<DomainCargo>NONE</DomainCargo>
<iCargo>0</iCargo>
<iConscription>2</iConscription>
<iCultureGarrison>4</iCultureGarrison>
<iExtraCost>0</iExtraCost>
<iAsset>2</iAsset>
<iPower>4</iPower>
<UnitMeshGroups>
<iGroupSize>3</iGroupSize>
<fMaxSpeed>1.75</fMaxSpeed>
<fPadTime>1</fPadTime>
<iMeleeWaveSize>3</iMeleeWaveSize>
<iRangedWaveSize>0</iRangedWaveSize>
<UnitMeshGroup>
<iRequired>3</iRequired>
<EarlyArtDefineTag>ART_DEF_UNIT_PHALANX</EarlyArtDefineTag>
</UnitMeshGroup>
</UnitMeshGroups>
<FormationType>FORMATION_TYPE_DEFAULT</FormationType>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<FreePromotions>
<FreePromotion>
<PromotionType>PROMOTION_COMBAT1</PromotionType>
<bFreePromotion>1</bFreePromotion>
</FreePromotion>
</FreePromotions>
<LeaderPromotion>NONE</LeaderPromotion>
<iLeaderExperience>0</iLeaderExperience>
</UnitInfo>


Anyone has ANY idea what could be a problem here???

Just in case War Elephant info:

Spoiler :



<UnitInfo>
<Class>UNITCLASS_WAR_ELEPHANT</Class>
<Type>UNIT_WAR_ELEPHANT</Type>
<UniqueNames/>
<Special>NONE</Special>
<Capture>NONE</Capture>
<Combat>UNITCOMBAT_MOUNTED</Combat>
<Domain>DOMAIN_LAND</Domain>
<DefaultUnitAI>UNITAI_ATTACK</DefaultUnitAI>
<Invisible>NONE</Invisible>
<SeeInvisible>NONE</SeeInvisible>
<Description>TXT_KEY_UNIT_WAR_ELEPHANT</Description>
<Civilopedia>TXT_KEY_UNIT_WAR_ELEPHANT_PEDIA</Civilopedia>
<Strategy>TXT_KEY_UNIT_WAR_ELEPHANT_STRATEGY</Strategy>
<Advisor>ADVISOR_MILITARY</Advisor>
<bAnimal>0</bAnimal>
<bFood>0</bFood>
<bNoBadGoodies>0</bNoBadGoodies>
<bOnlyDefensive>0</bOnlyDefensive>
<bNoCapture>0</bNoCapture>
<bQuickCombat>0</bQuickCombat>
<bRivalTerritory>0</bRivalTerritory>
<bMilitaryHappiness>1</bMilitaryHappiness>
<bMilitarySupport>1</bMilitarySupport>
<bMilitaryProduction>1</bMilitaryProduction>
<bPillage>1</bPillage>
<bSpy>0</bSpy>
<bSabotage>0</bSabotage>
<bDestroy>0</bDestroy>
<bStealPlans>0</bStealPlans>
<bInvestigate>0</bInvestigate>
<bCounterSpy>0</bCounterSpy>
<bFound>0</bFound>
<bGoldenAge>0</bGoldenAge>
<bInvisible>0</bInvisible>
<bFirstStrikeImmune>0</bFirstStrikeImmune>
<bNoDefensiveBonus>1</bNoDefensiveBonus>
<bIgnoreBuildingDefense>0</bIgnoreBuildingDefense>
<bCanMoveImpassable>0</bCanMoveImpassable>
<bCanMoveAllTerrain>0</bCanMoveAllTerrain>
<bFlatMovementCost>0</bFlatMovementCost>
<bIgnoreTerrainCost>0</bIgnoreTerrainCost>
<bNukeImmune>0</bNukeImmune>
<bPrereqBonuses>0</bPrereqBonuses>
<bPrereqReligion>0</bPrereqReligion>
<bMechanized>0</bMechanized>
<bSuicide>0</bSuicide>
<bHiddenNationality>0</bHiddenNationality>
<bAlwaysHostile>0</bAlwaysHostile>
<UnitClassUpgrades>
<UnitClassUpgrade>
<UnitClassUpgradeType>UNITCLASS_KNIGHT</UnitClassUpgradeType>
<bUnitClassUpgrade>1</bUnitClassUpgrade>
</UnitClassUpgrade>
<UnitClassUpgrade>
<UnitClassUpgradeType>UNITCLASS_GUN_ELEPHANT</UnitClassUpgradeType>
<bUnitClassUpgrade>1</bUnitClassUpgrade>
</UnitClassUpgrade>
</UnitClassUpgrades>
<UnitClassTargets/>
<UnitCombatTargets/>
<UnitClassDefenders/>
<UnitCombatDefenders/>
<FlankingStrikes/>
<UnitAIs>
<UnitAI>
<UnitAIType>UNITAI_ATTACK</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
<UnitAI>
<UnitAIType>UNITAI_COUNTER</UnitAIType>
<bUnitAI>1</bUnitAI>
</UnitAI>
</UnitAIs>
<NotUnitAIs/>
<Builds/>
<ReligionSpreads/>
<CorporationSpreads/>
<GreatPeoples/>
<Buildings/>
<ForceBuildings/>
<HolyCity>NONE</HolyCity>
<ReligionType>NONE</ReligionType>
<StateReligion>NONE</StateReligion>
<PrereqReligion>NONE</PrereqReligion>
<PrereqCorporation>NONE</PrereqCorporation>
<PrereqBuilding>NONE</PrereqBuilding>
<PrereqTech>TECH_ELEPHANT</PrereqTech>
<TechTypes>
<PrereqTech>NONE</PrereqTech>
<PrereqTech>NONE</PrereqTech>
</TechTypes>
<BonusType>BONUS_IVORY</BonusType>
<PrereqBonuses/>
<ProductionTraits/>
<Flavors/>
<iAIWeight>0</iAIWeight>
<iCost>150</iCost>
<iHurryCostModifier>0</iHurryCostModifier>
<iAdvancedStartCost>100</iAdvancedStartCost>
<iAdvancedStartCostIncrease>0</iAdvancedStartCostIncrease>
<iMinAreaSize>-1</iMinAreaSize>
<iMoves>1</iMoves>
<bNoRevealMap>0</bNoRevealMap>
<iAirRange>0</iAirRange>
<iAirUnitCap>0</iAirUnitCap>
<iDropRange>0</iDropRange>
<iNukeRange>-1</iNukeRange>
<iWorkRate>0</iWorkRate>
<iBaseDiscover>0</iBaseDiscover>
<iDiscoverMultiplier>0</iDiscoverMultiplier>
<iBaseHurry>0</iBaseHurry>
<iHurryMultiplier>0</iHurryMultiplier>
<iBaseTrade>0</iBaseTrade>
<iTradeMultiplier>0</iTradeMultiplier>
<iGreatWorkCulture>0</iGreatWorkCulture>
<iEspionagePoints>0</iEspionagePoints>
<TerrainImpassables/>
<FeatureImpassables/>
<TerrainPassableTechs/>
<FeaturePassableTechs/>
<iCombat>12</iCombat>
<iCombatLimit>100</iCombatLimit>
<iAirCombat>0</iAirCombat>
<iAirCombatLimit>0</iAirCombatLimit>
<iXPValueAttack>4</iXPValueAttack>
<iXPValueDefense>2</iXPValueDefense>
<iFirstStrikes>0</iFirstStrikes>
<iChanceFirstStrikes>0</iChanceFirstStrikes>
<iInterceptionProbability>0</iInterceptionProbability>
<iEvasionProbability>0</iEvasionProbability>
<iWithdrawalProb>10</iWithdrawalProb>
<iCollateralDamage>0</iCollateralDamage>
<iCollateralDamageLimit>0</iCollateralDamageLimit>
<iCollateralDamageMaxUnits>0</iCollateralDamageMaxUnits>
<iCityAttack>-100</iCityAttack>
<iCityDefense>-100</iCityDefense>
<iAnimalCombat>0</iAnimalCombat>
<iHillsAttack>0</iHillsAttack>
<iHillsDefense>0</iHillsDefense>
<TerrainNatives/>
<FeatureNatives/>
<TerrainAttacks/>
<TerrainDefenses/>
<FeatureAttacks>
<FeatureAttack>
<FeatureType>FEATURE_JUNGLE</FeatureType>
<iFeatureAttack>-50</iFeatureAttack>
</FeatureAttack>
<FeatureAttack>
<FeatureType>FEATURE_FOREST</FeatureType>
<iFeatureAttack>-50</iFeatureAttack>
</FeatureAttack>
<FeatureAttack>
<FeatureType>FEATURE_SWAMP</FeatureType>
<iFeatureAttack>-50</iFeatureAttack>
</FeatureAttack>
</FeatureAttacks>

<FeatureDefenses>
<FeatureDefense>
<FeatureType>FEATURE_JUNGLE</FeatureType>
<iFeatureDefense>-50</iFeatureDefense>
</FeatureDefense>
<FeatureDefense>
<FeatureType>FEATURE_FOREST</FeatureType>
<iFeatureDefense>-50</iFeatureDefense>
</FeatureDefense>
<FeatureDefense>
<FeatureType>FEATURE_SWAMP</FeatureType>
<iFeatureDefense>-50</iFeatureDefense>
</FeatureDefense>
</FeatureDefenses>
<UnitClassAttackMods/>
<UnitClassDefenseMods/>
<UnitCombatMods>
<UnitCombatMod>
<UnitCombatType>UNITCOMBAT_MOUNTED</UnitCombatType>
<iUnitCombatMod>50</iUnitCombatMod>
</UnitCombatMod>
</UnitCombatMods>
<UnitCombatCollateralImmunes/>
<DomainMods/>
<BonusProductionModifiers/>
<iBombRate>0</iBombRate>
<iBombardRate>0</iBombardRate>
<SpecialCargo>NONE</SpecialCargo>
<DomainCargo>NONE</DomainCargo>
<iCargo>0</iCargo>
<iConscription>0</iConscription>
<iCultureGarrison>4</iCultureGarrison>
<iExtraCost>2</iExtraCost>
<iAsset>3</iAsset>
<iPower>10</iPower>
<UnitMeshGroups>
<iGroupSize>2</iGroupSize>
<fMaxSpeed>1.75</fMaxSpeed>
<fPadTime>1</fPadTime>
<iMeleeWaveSize>2</iMeleeWaveSize>
<iRangedWaveSize>2</iRangedWaveSize>
<UnitMeshGroup>
<iRequired>2</iRequired>
<EarlyArtDefineTag>ART_DEF_UNIT_WAR_ELEPHANT</EarlyArtDefineTag>
</UnitMeshGroup>
</UnitMeshGroups>
<FormationType>FORMATION_TYPE_DEFAULT</FormationType>
<HotKey/>
<bAltDown>0</bAltDown>
<bShiftDown>0</bShiftDown>
<bCtrlDown>0</bCtrlDown>
<iHotKeyPriority>0</iHotKeyPriority>
<FreePromotions/>
<LeaderPromotion>NONE</LeaderPromotion>
<iLeaderExperience>0</iLeaderExperience>
</UnitInfo>




UPDATE:

Ok I think I figure it out in case anyone else runs into this problem.
I gave War Elephant higher Attack, and in exchange gave it -100% city strength to show realistically that it was a powerful unit in the field and useless in/vs cities.
However the issue is, that whenever a unit has -100% modifier runs into another unit that has some sort of +% bonus vs it, the game doesn't like that and crashes (perhaps modifiers do not add up correctly and cause division by 0 or something).
So I set Elephant to -75% city strength and now it works fine ;)
 
Last edited:
Anyone know where this error could be coming from?

With debug DLL, getting error that info for BTS buildings that I removed can't be found. No longer have Buildings_Academy in my mod, happens for a lot of buildings (obelisk, grand palace etc.), not sure the source though

This error only comes up (that I can find) when i click on the specialists pedia section, doesn't seem to cause any other problems
 

Attachments

  • IMG_2178 (1).JPG
    IMG_2178 (1).JPG
    130.5 KB · Views: 98
BUILDING_ACADEMY is apparently used in force controls. Either you removed BUILDING_ACADEMY or you try to load force control before buildingInfos.

If you remove a type, make sure you remove it in all files. GrepWin, Notepad++ or similar can be useful in searching all the XML files without actually manually opening everything and searching manually. If your intension is to rename a type, you need to rename it everywhere. I wrote a perl script to do just that. It's in the M:C git repository.

If you use a type before it's loaded due to load order, then it's not a quick question. Load order is hardcoded in the DLL and can use readPass2 and readPass3 to get around this issue. You could also start to mess with the load order or if you go really advanced (like I did in M:C), load all types and then load all files as this provides access to all types without the readPass stuff. How to do that is also not a quick question.
 
Debug DLL tends to say the error is coming from ForceControlInfos when its actually coming from another xml document. Forcecontrolinfos.xml is a very small file

I can't find any place where building_Academy remains. I opened ALL of the xml files in the mod, theres no place it say building_academy.

I also opened ALL xml files in generic BTS, generic Warlords, and generic vanilla files, and searched for building_academy in all files, and there aren't any references that I havent removed.
 
CIV4CityLSystem.xml is not mentioned in the DLL. It is however mentioned inside the EXE, meaning anything we know about it would be pure speculation. Since it acts up, I will assume that it works like text XML files and it will read ArtRef from original, then overwrite from warlords, then from BTS, then from the mod.
PHP:
       <ArtRef Name="building:BUILDING_ACADEMY">
           <Attribute Class="Rotation">0,180</Attribute>
           <Scale>2.0</Scale>
       </ArtRef>
The only thing I can think of is to somehow overwrite this to not exist. However I can't think of any way to tell "forget this one".

Just to be sure, are you sure you are not using XML cache?
 
Do you have your source files in a repository somewhere that we can look at?
I think that is the way to go now. The only thing left that I can think of is to attach a debugger and look at the call stack when it asserts to see where the string comes from. Actually I would recommend this approach as the first step when a mystery assert like this one appears. However I didn't mention it because it seems very few people are able to use the debugger and it doesn't work with the steam version.
 
I need help in using the game fonts file. I have roughly the following font file, similar to the BUG base including some changes for my mod:

norm.jpg


In particular, I need to know how to address some of these icons in Python code. I know how to handle everything from the happy face char onwards (use FontSymbols enum, and export new additions to Python wrapper if needed). I need to add about 16 icons, and with the current fonts file there is not enough space in the row where I know how it works. But if I go about adding icons into other rows, how do I actually reference them in Python?

For example, the row right above it contains icons for space ship projects (coming from BUG iirc), but I cannot find where they are actually used to learn how it works. Can I put new icons into this row, and if so, how can I address them?

BUG is completely integrated into my mod, so if it comes with utilities that would help doing this that's possible.
 
Last edited:
Back
Top Bottom