Bug Reports

Kailric

Jack of All Trades
Joined
Mar 25, 2008
Messages
3,100
Location
Marooned, Y'isrumgone
Post bug reports here. Please make note of what version you are playing, either the Git version or Official version. I'll post some other bug hunting related info later.

List of known Failed Asserts:
Some asserts I have been added purposely in order to track the AI's movement and such. I'll make note of these in red in the main post.

Link to Git version
https://github.com/Nightinggale/Medieval_Tech/wiki/Known-Asserts

Code:
File:  CvPlayerAI.h
Line:  24
Expression:  ePlayer >= 0
Message:  Player is not assigned a valid value
[COLOR="Red"]Fixed in Current Git, AI Europe Popes and Kings were trying to use Trader AI units and this was causing errors.[/COLOR]

File:  CvUnitAI.cpp
Line:  86
Expression:  isGroupHead()
Message:  isGroupHead is expected to be true

File:  CvUnit.cpp
Line:  965
Expression:  m_pUnitInfo->getDefaultUnitAIType() == AI_getUnitAIType()
[COLOR="Red"]This is a development Assert to test the AI's movement[/COLOR]

File: CvTeam.cpp
Line: 997
Expression: eTeam != getID()
Message: eTeam is not expected to be equal with getID()
[COLOR="Red"]This is propaply because of Vassal Lords joining your team. This FA will have no adverse effects.[/COLOR]

File:  CvUnit.cpp
Line:  11298
Expression:  false
Message:  Unit can not have profession
[COLOR="Red"]Fixed in Git Version[/COLOR]

File: CvUnit.cpp
Line: 1252
Expression: pCity != NULL
[COLOR="Red"]This is a development Assert to test new Feature[/COLOR]

File: CvUnit.cpp
Line: 6486
Expression: kCity.foodDifference() < 0
Message

File: CvGameTextMgr.cpp
Line: 8514
Expression: iModifiedProduction == aiYields[eYieldType]

File: CvGameTextMgr.cpp
Line: 8285
Expression: iBaseProduction == city.getBaseRawYieldProduced(eYieldType)
Message: 

File: CvGameTextMgr.cpp
Line: 9222
Expression: eYield == NO_YIELD || kPlayer.getSellToEuropeProfit(eYield, iAmount * (100 - iCommission) / 100) == iGross

File: CvPlayer.cpp
Line: 14645
Expression: iPrice <= getGold()
[COLOR="Red"]Commented Out in Current Git[/COLOR]

File: CvPlayer.cpp
Line: 15109
Expression: eYield < NUM_YIELD_TYPES
Message: 

Assert Failed
File: CvPlayer.cpp
Line: 15101
Expression: eYield < NUM_YIELD_TYPES
Message:

File:  CvPlayer.cpp
Line:  4958
Expression:  GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(eUnitClass) == eUnit
Message:
[COLOR="Red"]Fixed in Current Git, AI Popes and Kings had wrong Class assigned to Artillery aka Trebuchets.[/COLOR] 

File:  CvPlayer.cpp
Line:  5097
Expression:  GC.getCivilizationInfo(getCivilizationType()).getCivilizationBuildings(eBuildingClass) == eBuilding
[COLOR="Red"]Fixed in Current Git, added code to first check for Civilization Buildings before cities are assigned a Free Building[/COLOR]

File: CvInfos.cpp
Line: 15607
Expression: i < GC.getUnitInfo((UnitTypes) j).getGroupDefinitions((ProfessionTypes) m)
Message: Index out of bounds
[COLOR="Red"]Fixed in Git Version[/COLOR]
 
Nightinggale said:
I have an assert in CvPlayer::canTrain() and it makes little sense to me.

The current civilization is CIVILIZATION_TURKS.

CvCityAI::AI_bestUnitAI()
eLoopUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(50))); sets eLoopUnit to 12 (UNIT_SQUIRE)

CvPlayer::canTrain()
Out of this comes UnitClass 3 (UNITCLASS_SQUIRE)

UnitClass 3 for the current civilization is read as 18 (UNIT_ARAB_SQUIRE)

Now I get an assert because 12 is different from 18.


It appears to me that getCivilizationUnits(50) should return 18, not 12 like Christian civs. However I looked in the XML files and they appear to look ok. Maybe it's my lack of experience with XML (specially civ4 XML).

Do you have a clue to what could be wrong or should I really step through getCivilizationUnits() to see how it reads the wrong value, possibly step through the code which fills the data getCivilizationUnits() reads. That could be a bit time consuming, but I will do it if we have no other options.

I think my progress with M:C at the moment is horrible. Everything I touch turns into tricky problems :(

One good thing is coming out of this. I added m_szType to some info classes, which contain Type from XML. That makes it easier to figure out what goes on when debugging. I'm considering going through all of CvInfos.h/cpp to add it everywhere.


This is the strangest thing...

Actually, in CvCityAI it loops to 50 like you say but the 50th class is the Arab Missionary. Which is Unit 12.. so all that is correct. Where the error comes in is when is in CvPlayer doing the check for the class of unit 12...

eUnit being 12

eUnitClass = ((UnitClassTypes)(GC.getUnitInfo(eUnit).getUnitCla ssType()));

It returns eUnitClass as "3" Squire instead of "50" for Arab Missionary. At this point I am stumped on why when it reads the Unit infos for the Arab Missionary (12) it returns the class for Squire...

EDIT: well, this is what's happening in my current game, yours may be different

EDIT: if you continue on through the loop the numbers correct and in CvPlayer the next eUnitClass is 51, then 52...

EDIT: For one thing the Sunni Missionary doesn't even appear in the game? All the other alternate Arab units do however. I know I have seem them roaming around before...

EDIT: There is something Stupid weird going on. If I delete the Sunni Missionary all is fine, if I add him back in order before the Benedict Monk then the Benedict Monk disappears, if I add him back after the Monk then the Sunni is not in the game....

EDIT: Well, this is some strange stuff. If you add any more units The Arab specific units start to disappear. So, I am going to convert the Elephant into a Sunni Missionary and see what happens
 
Clearly the game is not reading the XML like we think it is. Looks like the best approach is to go through the XML reading code to see how it actually stores the data in vectors. This might be a bit time consuming so I better get started. I discovered this bug, but it looks to me like the underlying mechanics are flawed and as such can produce even more bugs like this, which we haven't discovered yet. This mean the bug which needs fixing is likely not found where the code asserts.

One thing which really worries me is that you count units and unit classes from XML and I read them using the ingame strings and we end up with different units for the same IDs.
 
Clearly the game is not reading the XML like we think it is. Looks like the best approach is to go through the XML reading code to see how it actually stores the data in vectors. This might be a bit time consuming so I better get started. I discovered this bug, but it looks to me like the underlying mechanics are flawed and as such can produce even more bugs like this, which we haven't discovered yet. This mean the bug which needs fixing is likely not found where the code asserts.

One thing which really worries me is that you count units and unit classes from XML and I read them using the ingame strings and we end up with different units for the same IDs.

Well, my programming experience is limited but in my experience at modding I have encounter strange "anomalies" like this before that I could not figure out the problem. One of the last one's I had was adding the new art for the Trade Screen. I added it to the same folder all the other screen art was in but when I loaded the game it crashed, then when I removed the art the game loaded. I had to put the art in different folder and the game worked fine. :crazyeye:
 
I looked into how the debugger views the Turks and came up with the following results. I used sprintf() and OutputDebugString() to make those big tables as doing it manually would take forever.

Now we know what it does. Next step is to figure out what is wrong and why.

XML read overwrite
Name|Unit|UnitClass
colonist|1|11
scout |8|41
veteran|16|45
squire|18|3
nobleman|20|12
pioneer|10 |46
missionary|12|50
general|76 |87
regular|-1|40

Output of getCivilizationUnits()
Spoiler :
ClassID|ClassName|UnitID|UnitName
0|UNITCLASS_CANNON|54|UNIT_CANNON
1|UNITCLASS_TREBUCHET|55|UNIT_TREBUCHET
2|UNITCLASS_COTTER|3|UNIT_COTTER
3|UNITCLASS_SQUIRE|18|UNIT_ARAB_SQUIRE
4|UNITCLASS_PAGE|17|UNIT_PAGE
5|UNITCLASS_RELIC|69|UNIT_RELIC
6|UNITCLASS_SUPPLY_TRAIN|66|UNIT_SUPPLY_TRAIN
7|UNITCLASS_SLAVE|77|UNIT_SLAVE
8|UNITCLASS_JESTER|24|UNIT_JESTER
9|UNITCLASS_PILGRAM|70|UNIT_PILGRAM
10|UNITCLASS_MARAUDER|71|UNIT_MARAUDER
11|UNITCLASS_COLONIST|1|UNIT_ARAB_COLONIST
12|UNITCLASS_NOBLEMAN|20|UNIT_ARAB_NOBLEMAN
13|UNITCLASS_INDENTURED_SERVANT|2|UNIT_INDENTURED_SERVANT
14|UNITCLASS_CRIMINAL|4|UNIT_CRIMINAL
15|UNITCLASS_CONVERTED_NATIVE|5|UNIT_CONVERTED_NATIVE
16|UNITCLASS_MINER|26|UNIT_MINER
17|UNITCLASS_LUMBERJACK|28|UNIT_LUMBERJACK
18|UNITCLASS_COTTON_PLANTER|31|UNIT_COTTON_PLANTER
19|UNITCLASS_BARLEY_PLANTER|33|UNIT_BARLEY_PLANTER
20|UNITCLASS_VINEYARD_PLANTER|32|UNIT_VINEYARD_PLANTER
21|UNITCLASS_FARMER|34|UNIT_FARMER
22|UNITCLASS_TRAPPER|35|UNIT_TRAPPER
23|UNITCLASS_QUARRYMAN|27|UNIT_QUARRYMAN
24|UNITCLASS_FISHERMAN|36|UNIT_FISHERMAN
25|UNITCLASS_BLACKSMITH|39|UNIT_BLACKSMITH
26|UNITCLASS_GUNSMITH|40|UNIT_GUNSMITH
27|UNITCLASS_TANNER|43|UNIT_TANNER
28|UNITCLASS_CARPENTER|42|UNIT_CARPENTER
29|UNITCLASS_COAT_MAKER|44|UNIT_COAT_MAKER
30|UNITCLASS_SILVERMINER|45|UNIT_SILVERMINER
31|UNITCLASS_DISTILLER|46|UNIT_DISTILLER
32|UNITCLASS_WEAVER|37|UNIT_WEAVER
33|UNITCLASS_RANCHER|49|UNIT_RANCHER
34|UNITCLASS_HERDSMAN|29|UNIT_HERDSMAN
35|UNITCLASS_SHEPARD|30|UNIT_SHEPARD
36|UNITCLASS_BAKER|48|UNIT_BAKER
37|UNITCLASS_BUTCHER|47|UNIT_BUTCHER
38|UNITCLASS_WINE_MAKER|38|UNIT_WINE_MAKER
39|UNITCLASS_ARMORSMITH|41|UNIT_ARMORSMITH
40|UNITCLASS_REGULAR|-1|
41|UNITCLASS_SCOUT|8|UNIT_ARAB_SCOUT
42|UNITCLASS_INN_KEEPER|25|UNIT_INN_KEEPER
43|UNITCLASS_TRADER|23|UNIT_TRADER
44|UNITCLASS_HUNTSMAN|6|UNIT_HUNTSMAN
45|UNITCLASS_VETERAN|16|UNIT_ARAB_VETERAN
46|UNITCLASS_PIONEER|10|UNIT_ARAB_PIONEER
47|UNITCLASS_DIGNITARY|21|UNIT_DIGNITARY
48|UNITCLASS_PREACHER|53|UNIT_PREACHER
49|UNITCLASS_INVENTOR|22|UNIT_INVENTOR
50|UNITCLASS_CHRISTIAN_MISSIONARY|12|UNIT_SQUIRE
51|UNITCLASS_WAGON_TRAIN|68|UNIT_WAGON_TRAIN
52|UNITCLASS_CARAVEL|59|UNIT_CARAVEL
53|UNITCLASS_MERCHANTMAN|60|UNIT_MERCHANTMAN
54|UNITCLASS_PRIVATEER|61|UNIT_PRIVATEER
55|UNITCLASS_GALLEON|63|UNIT_GALLEON
56|UNITCLASS_FRIGATE|64|UNIT_FRIGATE
57|UNITCLASS_FOOD|94|UNIT_FOOD
58|UNITCLASS_LUMBER|96|UNIT_LUMBER
59|UNITCLASS_SILVER|97|UNIT_SILVER
60|UNITCLASS_COTTON|98|UNIT_COTTON
61|UNITCLASS_FUR|99|UNIT_FUR
62|UNITCLASS_SUGAR|100|UNIT_SUGAR
63|UNITCLASS_ORE|102|UNIT_ORE
64|UNITCLASS_CLOTH|103|UNIT_CLOTH
65|UNITCLASS_COATS|104|UNIT_COATS
66|UNITCLASS_RUM|105|UNIT_RUM
67|UNITCLASS_TOOLS|106|UNIT_TOOLS
68|UNITCLASS_MUSKETS|107|UNIT_MUSKETS
69|UNITCLASS_HORSES|108|UNIT_HORSES
70|UNITCLASS_TRADE_GOODS|109|UNIT_TRADE_GOODS
71|UNITCLASS_CATTLE|110|UNIT_CATTLE
72|UNITCLASS_SHEEP|112|UNIT_SHEEP
73|UNITCLASS_GRAIN|95|UNIT_GRAIN
74|UNITCLASS_WOOL|113|UNIT_WOOL
75|UNITCLASS_STONE|114|UNIT_STONE
76|UNITCLASS_GOLD|115|UNIT_GOLD
77|UNITCLASS_SPICES|116|UNIT_SPICES
78|UNITCLASS_BARLEY|111|UNIT_BARLEY
79|UNITCLASS_GRAPES|117|UNIT_GRAPES
80|UNITCLASS_WINE|118|UNIT_WINE
81|UNITCLASS_LEATHER|101|UNIT_LEATHER
82|UNITCLASS_LEATHER_ARMOR|119|UNIT_LEATHER_ARMOR
83|UNITCLASS_SCALE_ARMOR|120|UNIT_SCALE_ARMOR
84|UNITCLASS_MAIL_ARMOR|121|UNIT_MAIL_ARMOR
85|UNITCLASS_PLATE_ARMOR|122|UNIT_PLATE_ARMOR
86|UNITCLASS_TREASURE|74|UNIT_TREASURE
87|UNITCLASS_GREAT_GENERAL|76|UNIT_ARAB_GREAT_GENERAL
88|UNITCLASS_AI_PEDLER|67|UNIT_AI_PEDLER
89|UNITCLASS_BEAR_BLACK|78|UNIT_BEAR_BLACK
90|UNITCLASS_BEAR_BROWN|79|UNIT_BEAR_BROWN
91|UNITCLASS_BEAR_POLAR|80|UNIT_BEAR_POLAR
92|UNITCLASS_COUGAR|81|UNIT_COUGAR
93|UNITCLASS_DOG|83|UNIT_DOG
94|UNITCLASS_ELEPHANT|84|UNIT_ELEPHANT
95|UNITCLASS_HYENA|85|UNIT_HYENA
96|UNITCLASS_LION|86|UNIT_LION
97|UNITCLASS_PANTHER|87|UNIT_PANTHER
98|UNITCLASS_PIG|88|UNIT_PIG
99|UNITCLASS_BOAR|89|UNIT_BOAR
100|UNITCLASS_DEER|90|UNIT_DEER
101|UNITCLASS_WOLF|91|UNIT_WOLF
102|UNITCLASS_LEAD_HUNTSMAN|93|UNIT_LEAD_HUNTSMAN
103|UNITCLASS_TRADER_GUARD|82|UNIT_TRADER_GUARD

GC.getUnitInfo() output.
Spoiler :
First 3 are read from UnitInfos while the last two are read from UnitClassInfos.
Type|ID|UnitClass|Type|ID
UNIT_COLONIST|0|UNITCLASS_COLONIST|UNITCLASS_COLONIST|11
UNIT_ARAB_COLONIST|1|UNITCLASS_COLONIST|UNITCLASS_COLONIST|11
UNIT_INDENTURED_SERVANT|2|UNITCLASS_INDENTURED_SERVANT|UNITCLASS_INDENTURED_SERVANT|13
UNIT_COTTER|3|UNITCLASS_COTTER|UNITCLASS_COTTER|2
UNIT_CRIMINAL|4|UNITCLASS_CRIMINAL|UNITCLASS_CRIMINAL|14
UNIT_CONVERTED_NATIVE|5|UNITCLASS_CONVERTED_NATIVE|UNITCLASS_CONVERTED_NATIVE|15
UNIT_HUNTSMAN|6|UNITCLASS_HUNTSMAN|UNITCLASS_HUNTSMAN|44
UNIT_SCOUT|7|UNITCLASS_SCOUT|UNITCLASS_SCOUT|41
UNIT_ARAB_SCOUT|8|UNITCLASS_SCOUT|UNITCLASS_SCOUT|41
UNIT_PIONEER|9|UNITCLASS_PIONEER|UNITCLASS_PIONEER|46
UNIT_ARAB_PIONEER|10|UNITCLASS_PIONEER|UNITCLASS_PIONEER|46
UNIT_CHRISTIAN_MISSIONARY|11|UNITCLASS_CHRISTIAN_MISSIONARY|UNITCLASS_CHRISTIAN_MISSIONARY|50
UNIT_SQUIRE|12|UNITCLASS_SQUIRE|UNITCLASS_SQUIRE|3
UNIT_VETERAN|13|UNITCLASS_VETERAN|UNITCLASS_VETERAN|45
UNIT_MONGOL_VETERAN|14|UNITCLASS_VETERAN|UNITCLASS_VETERAN|45
UNIT_VIKING_VETERAN|15|UNITCLASS_VETERAN|UNITCLASS_VETERAN|45
UNIT_ARAB_VETERAN|16|UNITCLASS_VETERAN|UNITCLASS_VETERAN|45
UNIT_PAGE|17|UNITCLASS_PAGE|UNITCLASS_PAGE|4
UNIT_ARAB_SQUIRE|18|UNITCLASS_SQUIRE|UNITCLASS_SQUIRE|3
UNIT_NOBLEMAN|19|UNITCLASS_NOBLEMAN|UNITCLASS_NOBLEMAN|12
UNIT_ARAB_NOBLEMAN|20|UNITCLASS_NOBLEMAN|UNITCLASS_NOBLEMAN|12
UNIT_DIGNITARY|21|UNITCLASS_DIGNITARY|UNITCLASS_DIGNITARY|47
UNIT_INVENTOR|22|UNITCLASS_INVENTOR|UNITCLASS_INVENTOR|49
UNIT_TRADER|23|UNITCLASS_TRADER|UNITCLASS_TRADER|43
UNIT_JESTER|24|UNITCLASS_JESTER|UNITCLASS_JESTER|8
UNIT_INN_KEEPER|25|UNITCLASS_INN_KEEPER|UNITCLASS_INN_KEEPER|42
UNIT_MINER|26|UNITCLASS_MINER|UNITCLASS_MINER|16
UNIT_QUARRYMAN|27|UNITCLASS_QUARRYMAN|UNITCLASS_QUARRYMAN|23
UNIT_LUMBERJACK|28|UNITCLASS_LUMBERJACK|UNITCLASS_LUMBERJACK|17
UNIT_HERDSMAN|29|UNITCLASS_HERDSMAN|UNITCLASS_HERDSMAN|34
UNIT_SHEPARD|30|UNITCLASS_SHEPARD|UNITCLASS_SHEPARD|35
UNIT_COTTON_PLANTER|31|UNITCLASS_COTTON_PLANTER|UNITCLASS_COTTON_PLANTER|18
UNIT_VINEYARD_PLANTER|32|UNITCLASS_VINEYARD_PLANTER|UNITCLASS_VINEYARD_PLANTER|20
UNIT_BARLEY_PLANTER|33|UNITCLASS_BARLEY_PLANTER|UNITCLASS_BARLEY_PLANTER|19
UNIT_FARMER|34|UNITCLASS_FARMER|UNITCLASS_FARMER|21
UNIT_TRAPPER|35|UNITCLASS_TRAPPER|UNITCLASS_TRAPPER|22
UNIT_FISHERMAN|36|UNITCLASS_FISHERMAN|UNITCLASS_FISHERMAN|24
UNIT_WEAVER|37|UNITCLASS_WEAVER|UNITCLASS_WEAVER|32
UNIT_WINE_MAKER|38|UNITCLASS_WINE_MAKER|UNITCLASS_WINE_MAKER|38
UNIT_BLACKSMITH|39|UNITCLASS_BLACKSMITH|UNITCLASS_BLACKSMITH|25
UNIT_GUNSMITH|40|UNITCLASS_GUNSMITH|UNITCLASS_GUNSMITH|26
UNIT_ARMORSMITH|41|UNITCLASS_ARMORSMITH|UNITCLASS_ARMORSMITH|39
UNIT_CARPENTER|42|UNITCLASS_CARPENTER|UNITCLASS_CARPENTER|28
UNIT_TANNER|43|UNITCLASS_TANNER|UNITCLASS_TANNER|27
UNIT_COAT_MAKER|44|UNITCLASS_COAT_MAKER|UNITCLASS_COAT_MAKER|29
UNIT_SILVERMINER|45|UNITCLASS_SILVERMINER|UNITCLASS_SILVERMINER|30
UNIT_DISTILLER|46|UNITCLASS_DISTILLER|UNITCLASS_DISTILLER|31
UNIT_BUTCHER|47|UNITCLASS_BUTCHER|UNITCLASS_BUTCHER|37
UNIT_BAKER|48|UNITCLASS_BAKER|UNITCLASS_BAKER|36
UNIT_RANCHER|49|UNITCLASS_RANCHER|UNITCLASS_RANCHER|33
UNIT_REGULAR|50|UNITCLASS_REGULAR|UNITCLASS_REGULAR|40
UNIT_CRUSADER_REGULAR|51|UNITCLASS_REGULAR|UNITCLASS_REGULAR|40
UNIT_OTTOMAN_REGULAR|52|UNITCLASS_REGULAR|UNITCLASS_REGULAR|40
UNIT_PREACHER|53|UNITCLASS_PREACHER|UNITCLASS_PREACHER|48
UNIT_CANNON|54|UNITCLASS_CANNON|UNITCLASS_CANNON|0
UNIT_TREBUCHET|55|UNITCLASS_TREBUCHET|UNITCLASS_TREBUCHET|1
UNIT_ARTILLERY|56|UNITCLASS_TREBUCHET|UNITCLASS_TREBUCHET|1
UNIT_NATIVE|57|UNITCLASS_COLONIST|UNITCLASS_COLONIST|11
UNIT_LONGSHIP|58|UNITCLASS_CARAVEL|UNITCLASS_CARAVEL|52
UNIT_CARAVEL|59|UNITCLASS_CARAVEL|UNITCLASS_CARAVEL|52
UNIT_MERCHANTMAN|60|UNITCLASS_MERCHANTMAN|UNITCLASS_MERCHANTMAN|53
UNIT_PRIVATEER|61|UNITCLASS_PRIVATEER|UNITCLASS_PRIVATEER|54
UNIT_RAIDER_GALLEY|62|UNITCLASS_PRIVATEER|UNITCLASS_PRIVATEER|54
UNIT_GALLEON|63|UNITCLASS_GALLEON|UNITCLASS_GALLEON|55
UNIT_FRIGATE|64|UNITCLASS_FRIGATE|UNITCLASS_FRIGATE|56
UNIT_MAN_O_WAR|65|UNITCLASS_FRIGATE|UNITCLASS_FRIGATE|56
UNIT_SUPPLY_TRAIN|66|UNITCLASS_SUPPLY_TRAIN|UNITCLASS_SUPPLY_TRAIN|6
UNIT_AI_PEDLER|67|UNITCLASS_AI_PEDLER|UNITCLASS_AI_PEDLER|88
UNIT_WAGON_TRAIN|68|UNITCLASS_WAGON_TRAIN|UNITCLASS_WAGON_TRAIN|51
UNIT_RELIC|69|UNITCLASS_RELIC|UNITCLASS_RELIC|5
UNIT_PILGRAM|70|UNITCLASS_PILGRAM|UNITCLASS_PILGRAM|9
UNIT_MARAUDER|71|UNITCLASS_MARAUDER|UNITCLASS_MARAUDER|10
UNIT_SARACEN|72|UNITCLASS_MARAUDER|UNITCLASS_MARAUDER|10
UNIT_BANDIT|73|UNITCLASS_MARAUDER|UNITCLASS_MARAUDER|10
UNIT_TREASURE|74|UNITCLASS_TREASURE|UNITCLASS_TREASURE|86
UNIT_GREAT_GENERAL|75|UNITCLASS_GREAT_GENERAL|UNITCLASS_GREAT_GENERAL|87
UNIT_ARAB_GREAT_GENERAL|76|UNITCLASS_GREAT_GENERAL|UNITCLASS_GREAT_GENERAL|87
UNIT_SLAVE|77|UNITCLASS_SLAVE|UNITCLASS_SLAVE|7
UNIT_BEAR_BLACK|78|UNITCLASS_BEAR_BLACK|UNITCLASS_BEAR_BLACK|89
UNIT_BEAR_BROWN|79|UNITCLASS_BEAR_BROWN|UNITCLASS_BEAR_BROWN|90
UNIT_BEAR_POLAR|80|UNITCLASS_BEAR_POLAR|UNITCLASS_BEAR_POLAR|91
UNIT_COUGAR|81|UNITCLASS_COUGAR|UNITCLASS_COUGAR|92
UNIT_TRADER_GUARD|82|UNITCLASS_TRADER_GUARD|UNITCLASS_TRADER_GUARD|103
UNIT_DOG|83|UNITCLASS_DOG|UNITCLASS_DOG|93
UNIT_ELEPHANT|84|UNITCLASS_ELEPHANT|UNITCLASS_ELEPHANT|94
UNIT_HYENA|85|UNITCLASS_HYENA|UNITCLASS_HYENA|95
UNIT_LION|86|UNITCLASS_LION|UNITCLASS_LION|96
UNIT_PANTHER|87|UNITCLASS_PANTHER|UNITCLASS_PANTHER|97
UNIT_PIG|88|UNITCLASS_PIG|UNITCLASS_PIG|98
UNIT_BOAR|89|UNITCLASS_BOAR|UNITCLASS_BOAR|99
UNIT_DEER|90|UNITCLASS_DEER|UNITCLASS_DEER|100
UNIT_WOLF|91|UNITCLASS_WOLF|UNITCLASS_WOLF|101
UNIT_DOG_PACK|92|UNITCLASS_DOG|UNITCLASS_DOG|93
UNIT_LEAD_HUNTSMAN|93|UNITCLASS_LEAD_HUNTSMAN|UNITCLASS_LEAD_HUNTSMAN|102
UNIT_FOOD|94|UNITCLASS_FOOD|UNITCLASS_FOOD|57
UNIT_GRAIN|95|UNITCLASS_GRAIN|UNITCLASS_GRAIN|73
UNIT_LUMBER|96|UNITCLASS_LUMBER|UNITCLASS_LUMBER|58
UNIT_SILVER|97|UNITCLASS_SILVER|UNITCLASS_SILVER|59
UNIT_COTTON|98|UNITCLASS_COTTON|UNITCLASS_COTTON|60
UNIT_FUR|99|UNITCLASS_FUR|UNITCLASS_FUR|61
UNIT_SUGAR|100|UNITCLASS_SUGAR|UNITCLASS_SUGAR|62
UNIT_LEATHER|101|UNITCLASS_LEATHER|UNITCLASS_LEATHER|81
UNIT_ORE|102|UNITCLASS_ORE|UNITCLASS_ORE|63
UNIT_CLOTH|103|UNITCLASS_CLOTH|UNITCLASS_CLOTH|64
UNIT_COATS|104|UNITCLASS_COATS|UNITCLASS_COATS|65
UNIT_RUM|105|UNITCLASS_RUM|UNITCLASS_RUM|66
UNIT_TOOLS|106|UNITCLASS_TOOLS|UNITCLASS_TOOLS|67
UNIT_MUSKETS|107|UNITCLASS_MUSKETS|UNITCLASS_MUSKETS|68
UNIT_HORSES|108|UNITCLASS_HORSES|UNITCLASS_HORSES|69
UNIT_TRADE_GOODS|109|UNITCLASS_TRADE_GOODS|UNITCLASS_TRADE_GOODS|70
UNIT_CATTLE|110|UNITCLASS_CATTLE|UNITCLASS_CATTLE|71
UNIT_BARLEY|111|UNITCLASS_BARLEY|UNITCLASS_BARLEY|78
UNIT_SHEEP|112|UNITCLASS_SHEEP|UNITCLASS_SHEEP|72
UNIT_WOOL|113|UNITCLASS_WOOL|UNITCLASS_WOOL|74
UNIT_STONE|114|UNITCLASS_STONE|UNITCLASS_STONE|75
UNIT_GOLD|115|UNITCLASS_GOLD|UNITCLASS_GOLD|76
UNIT_SPICES|116|UNITCLASS_SPICES|UNITCLASS_SPICES|77
UNIT_GRAPES|117|UNITCLASS_GRAPES|UNITCLASS_GRAPES|79
UNIT_WINE|118|UNITCLASS_WINE|UNITCLASS_WINE|80
UNIT_LEATHER_ARMOR|119|UNITCLASS_LEATHER_ARMOR|UNITCLASS_LEATHER_ARMOR|82
UNIT_SCALE_ARMOR|120|UNITCLASS_SCALE_ARMOR|UNITCLASS_SCALE_ARMOR|83
UNIT_MAIL_ARMOR|121|UNITCLASS_MAIL_ARMOR|UNITCLASS_MAIL_ARMOR|84
UNIT_PLATE_ARMOR|122|UNITCLASS_PLATE_ARMOR|UNITCLASS_PLATE_ARMOR|85

Next I have tables where end result should be the same as the original, but isn't.

Class->Unit->Class
40|-1|-1|This one appears ok even though 40 != -1
50|12|3|We already knew this one

Unit->Class->Unit
Spoiler :
0|UNIT_COLONIST|11|UNITCLASS_COLONIST|1|UNIT_ARAB_COLONIST
7|UNIT_SCOUT|41|UNITCLASS_SCOUT|8|UNIT_ARAB_SCOUT
9|UNIT_PIONEER|46|UNITCLASS_PIONEER|10|UNIT_ARAB_PIONEER
11 | UNIT_CHRISTIAN_MISSIONARY | 50 | UNITCLASS_CHRISTIAN_MISSIONARY | 12 | UNIT_SQUIRE
12|UNIT_SQUIRE|3|UNITCLASS_SQUIRE|18|UNIT_ARAB_SQUIRE
13|UNIT_VETERAN|45|UNITCLASS_VETERAN|16|UNIT_ARAB_VETERAN
14|UNIT_MONGOL_VETERAN|45|UNITCLASS_VETERAN|16|UNIT_ARAB_VETERAN
15|UNIT_VIKING_VETERAN|45|UNITCLASS_VETERAN|16|UNIT_ARAB_VETERAN
19|UNIT_NOBLEMAN|12|UNITCLASS_NOBLEMAN|20|UNIT_ARAB_NOBLEMAN
50|UNIT_REGULAR|40|UNITCLASS_REGULAR|-1|
51|UNIT_CRUSADER_REGULAR|40|UNITCLASS_REGULAR|-1|
52|UNIT_OTTOMAN_REGULAR|40|UNITCLASS_REGULAR|-1|
56|UNIT_ARTILLERY|1|UNITCLASS_TREBUCHET|55|UNIT_TREBUCHET
57|UNIT_NATIVE|11|UNITCLASS_COLONIST|1|UNIT_ARAB_COLONIST
58|UNIT_LONGSHIP|52|UNITCLASS_CARAVEL|59|UNIT_CARAVEL
62|UNIT_RAIDER_GALLEY|54|UNITCLASS_PRIVATEER|61|UNIT_PRIVATEER
65|UNIT_MAN_O_WAR|56|UNITCLASS_FRIGATE|64|UNIT_FRIGATE
72|UNIT_SARACEN|10|UNITCLASS_MARAUDER|71|UNIT_MARAUDER
73|UNIT_BANDIT|10|UNITCLASS_MARAUDER|71|UNIT_MARAUDER
75|UNIT_GREAT_GENERAL|87|UNITCLASS_GREAT_GENERAL|76|UNIT_ARAB_GREAT_GENERAL
92|UNIT_DOG_PACK|93|UNITCLASS_DOG|83|UNIT_DOG
A brief look at this one revealed just one bug. The rest appears to be ok based on the names (I didn't dig into the details).

EDIT: I noticed one interesting thing.

UNIT_CHRISTIAN_MISSIONARY|11
UNIT_SQUIRE|12
UNIT_VETERAN|13
UNIT_PAGE|17
UNIT_ARAB_SQUIRE|18
UNIT_NOBLEMAN|19

If you read the XML file it should have been
UNIT_CHRISTIAN_MISSIONARY|11
UNIT_UNIT_ARAB_MISSIONARY|12
UNIT_VETERAN|13
UNIT_PAGE|17
UNIT_SQUIRE|18
UNIT_ARAB_SQUIRE|19
UNIT_NOBLEMAN|20

It would appear that the bug is in UNIT_SQUIRE. For some reason it overwrites UnitInfo[12] instead of appending to the end like it should. Now the real question is how can it do that? Is something written incorrectly in the XML or is it a really strange vanilla bug. I don't think we are the first to encounter such a vanilla bug meaning UNIT_SQUIRE should be closely examined in the XML file.
 
It would appear that the bug is in UNIT_SQUIRE. For some reason it overwrites UnitInfo[12] instead of appending to the end like it should. Now the real question is how can it do that? Is something written incorrectly in the XML or is it a really strange vanilla bug. I don't think we are the first to encounter such a vanilla bug meaning UNIT_SQUIRE should be closely examined in the XML file.

I looked into this as well but can not make heads or tails of it. I did replace the Elephant, which isn't used, with the Sunni Missionary now all the units seem to appear in the game...


EDIT: WRONG!! Now the Veteran Soldier is missing and guess what has replaced it... THE SQUIRE!!!

EDIT: Well, I tried moving the Squire around. If I move him up in order he eventually disappears in the game and another unit takes his place, just like

EDIT: K, I totally removed the Squire unit and replaced him with the Page as far as game references goes. I played two games over a 100 turns on Autoplay and did not get the error... Now, to see if I can add the unit back with out errors.
 
Finally I made a breakthrough. I located the bug to CvXMLLoadUtility::SetGlobalClassInfo, or more precisely the line
Code:
iIndex = GC.getInfoTypeForString(pClassInfo->getType(), true);
If iIndex is -1, then the new unit is added at the end. Otherwise it will replace whatever is at iIndex.

Now the question is why does this function see UNIT_SQUIRE as the same as UNIT_ARAB_MISSIONARY. It must do that because the function returns 12, which makes it overwrite rather than add at the end. If I add a breakpoint to stop execution after UNIT_ARAB_MISSIONARY is added, but before UNIT_SQUIRE is read from XML, then UNIT_ARAB_MISSIONARY is where it is supposed to be.

The problem now is that getInfoTypeForString() is far from trivial and it's generic vanilla code for reading a lot of XML files. Figuring out what goes on inside it appears to be a bit tricky. At least tricky enough for me to postpone it until I was sure that it is important for this bug.
 
Finally I made a breakthrough. I located the bug to CvXMLLoadUtility::SetGlobalClassInfo, or more precisely the line
Code:
iIndex = GC.getInfoTypeForString(pClassInfo->getType(), true);
If iIndex is -1, then the new unit is added at the end. Otherwise it will replace whatever is at iIndex.

Now the question is why does this function see UNIT_SQUIRE as the same as UNIT_ARAB_MISSIONARY. It must do that because the function returns 12, which makes it overwrite rather than add at the end. If I add a breakpoint to stop execution after UNIT_ARAB_MISSIONARY is added, but before UNIT_SQUIRE is read from XML, then UNIT_ARAB_MISSIONARY is where it is supposed to be.

The problem now is that getInfoTypeForString() is far from trivial and it's generic vanilla code for reading a lot of XML files. Figuring out what goes on inside it appears to be a bit tricky. At least tricky enough for me to postpone it until I was sure that it is important for this bug.

I've seen strange things in the XML readings. It is like if you edit a file sometimes it has glitches. I added some notes to the Squire unit about the "Caste System", I have seen it sometimes where adding notes can mess up a XML.

Well, I played around on autoplay for a while and haven't encountered that bug sense I removed the Squire unit. I have encountered a couple new AI trade system bugs and also a Crash bug where Water starting Civs like Mongols try to purchase ships but the Ships never actually appear then it causes a crash eventually. I am working on fixing that one atm.
 
I found and fixed the bug! (NOT committed. That's a task for Kailric)

It turned out to be coder error in XML. Not wrong XML syntax (I checked that earlier), but coder error :wallbash:

When it reads CIV4UnitInfos.xml it goes
Code:
 <UnitInfo>
    <Type>UNIT_SQUIRE</Type>
It will then check if UNIT_SQUIRE is known and in GlobalTypes.xml it says
Code:
<ModCodeTypes>
...
    <ModCodeType>UNIT_SQUIRE</ModCodeType>

It will then see this string and go "I know this string. It's at index 12. Some modder made a mistake and wrote the same unit twice. Now it will just be overwritten and it will still work". Maybe it's some support for multiple xml files of the same type (like avoiding to merge XML files when merging two MODs).

Renaming either will make it work. As Kailric decided on the names he should be the one to decide which one to rename and what it should be renamed to. Hopefully we will not have more nameclashes like this.

Now that I think about it, it should be possible to check for this. All I have to do is to add a counter in the XML reader and once it's done it should run the following line:
Code:
FAssert(GC.getNumUnitInfos() == counterNumUnitInfos);
This would assert as it read one unit more from the XML file than appeared in the vector.
I think I will start to implement this for all XML files, or at least for those which have a getNum* function because tracking down bugs like this is not something I want to do again!

Oh and fixing this bug mean one more unit, which in turn breaks all savegames. Perhaps this minor change in the savegame is minor enough for my failed savegame converter to handle it. At least if it will ever work, then it should be now as it's the most simple scenario it can encounter.
 
I found and fixed the bug! (NOT committed. That's a task for Kailric).

:mad::mad::cry::crazyeye::hammer2::shake::ar15: Kailric

I caused this bug!! The ModCodeTypes is something I had in the works and just haven't completed yet. My lack of coding knowledge caused this bug to be more correct. You know how I in CivUnitInfos it talks about the Caste System. Well the caste system lets you determine things like Can't work in buildings, or travel outside of player's borders. I added the ModCodes to better keep up with these attributes because of now I just have them Number as in 1 = NoBuilingsWorked; 2 = NoneMilitary; 3 = Squire;.

Ugggh!! I just need to change the Moder Code Unit_Squire to something else, like ModCode_Squire... Duh!!

Ok, I'll fix this. I also fixed that bug I mentioned above. Gonna run some AI autoplay sessions and see if I encounter any more of failed asserts....

Thanks so much for figuring this out.. I owe you "one" (if you haven't been counting :))
 
Oh and fixing this bug mean one more unit, which in turn breaks all savegames. Perhaps this minor change in the savegame is minor enough for my failed savegame converter to handle it. At least if it will ever work, then it should be now as it's the most simple scenario it can encounter.
A quick hack to convert failed. Saving savegames from XML changes will most likely never work. I will quick trying and just discard my savegames.... again :cry:

Now that I think about it, it should be possible to check for this. All I have to do is to add a counter in the XML reader and once it's done it should run the following line:
Code:
FAssert(GC.getNumUnitInfos() == counterNumUnitInfos);
This would assert as it read one unit more from the XML file than appeared in the vector.
I think I will start to implement this for all XML files, or at least for those which have a getNum* function because tracking down bugs like this is not something I want to do again!
That's what I will do now. Better be safe than sorry.

:mad::mad::cry::crazyeye::hammer2::shake::ar15: Kailric

I caused this bug!! The ModCodeTypes is something I had in the works and just haven't completed yet. My lack of coding knowledge caused this bug to be more correct.
I didn't know either. However now that I think about it I guess it makes sense. I suspect that the storage where all strings are unique and is global for all XML files is the source of getDefineINT(). While it would seem bad at first to include the risk of such bugs, it does provide us with the ability to write GC.getDefineINT("UNIT_SQUIRE") and get 12/18. We might need that ability some day. In fact it looks like we use it already as the code has stuff like
getDefineINT("PROFESSION_INVENTOR");
getDefineINT("UNITARMOR_LEATHER");
getDefineINT("UNITCLASS_PIONEER");
Granted it's in the cache generating code, but it's still the DLL, which reads an int from XML, which makes it able to survive different XML orders. That would kill savegames, but the DLL itself will not have to be recompiled.

Thanks so much for figuring this out.. I owe you "one" (if you haven't been counting :))
I lost count of all the issues I found and/or fixed. However I noticed I never received any stars. Oh well whenever I win prizes I wonder what I should do with them anyway :lol:

Also another thing. Remember not to commit too much at once. Tracking newly introduced bugs will become horrible if you do. One fix/feature, one commit.
 
I lost count of all the issues I found and/or fixed. However I noticed I never received any stars. Oh well whenever I win prizes I wonder what I should do with them anyway :lol:

Also another thing. Remember not to commit too much at once. Tracking newly introduced bugs will become horrible if you do. One fix/feature, one commit.

Well, I have been adjusting the Trader code I introduced last patch fixing errors in that I found and crashes. Then I went and Fixed the error you found so that is two I did. I simply changed the enums to have a moder tag as in MODER_CODE_SQUIRE. I'll run some AI games and see if I find anything else.
 
New bug
I implemented the XML name test and pushed it. Now it asserts at startup because UNIT_SQUIRE wasn't the only problem. It will only report one assert for each vector meaning the fixing approach is as follows: run the game and it will tell you a duplicated name. Once you fixed it, (re)start the game again and the next one will appear. Continue until the game can start without asserting.

I will postpone starting a new game (again) until this is fixed as it can break savegames again.
 
New bug
I implemented the XML name test and pushed it. Now it asserts at startup because UNIT_SQUIRE wasn't the only problem. It will only report one assert for each vector meaning the fixing approach is as follows: run the game and it will tell you a duplicated name. Once you fixed it, (re)start the game again and the next one will appear. Continue until the game can start without asserting.

I will postpone starting a new game (again) until this is fixed as it can break savegames again.

Ok, I fixed those and pushed to git. I also adjusted the AI a little to focus on building at least one ship if the Civ was land start.
 
Are you sure you pushed to git? I can't pull any XML changes and Github also fails to spot any non-DLL changes.

That is probably because I had 2010 Express open when I pulled and it wouldn't merge the DLL. So, I finally figured out I ened up Re building the DLL, commit the changes, and then Push everything. I may have thrown everything out of sync? There was just three duplicates, two in the Civ4effects and one in Eventtriggers.
 
That is probably because I had 2010 Express open when I pulled and it wouldn't merge the DLL.
That happened for me a few times. The correct solution is to right click on the dll and select git->revert. I think it will open a window to select which files to revert. You will figure that out if it does, but do remember not to delete uncommitted work :)
Alternatively you can do it from command line where the command is
Code:
git.exe checkout CvGameCoreDLL.dll

Naturally this approach can be used on all files, but the DLL file is the one, which is hit each time.

Having VC++ open shouldn't affect this problem at all. At most when you return to it, it will tell of modified files and ask if they should be reloaded, which you should unless you have a really good reason not to (I can't think of any).

So, I finally figured out I ened up Re building the DLL, commit the changes, and then Push everything. I may have thrown everything out of sync? There was just three duplicates, two in the Civ4effects and one in Eventtriggers.
It should not be possible to go out of sync like that. It's more like you didn't commit the XML changes before you pushed. I see you pushed the changes while I wrote this. Problem solved :)

EDIT:
EDIT: Actually, I just now pushed the changes. I thought it pushed them when I pushed the AI changes... guess not :)
It should have pushed all commits (I think). However it's always good to verify that uploaded files actually arrived and pushing files with git is basically just uploading files.
 
Not a bug report, just a heads-up, the Windows Presentation Foundation Font Cache service (installed as part of MS .NET 4.0 when I installed 2010 Express, hereafter WPFFC) can cause issues with Civ4Col's font engine and cause a program fault on a 32-bit system. Since the fault occurred every time as the game loaded screen got to the game's font engine, that's my guess where the conflict occurs. And I figured this may relate to Nightinggale's problem loading M:C on his 32-bit system (laptop?), I'd post something about it.

I had to disable the WPFFC service from starting in order to get M:C to load. I did a Goggle search and it seems that WPFFC is known to cause software memory conflicts on 32-bit systems, so the bug is not limited to Civ4Col. I'm guessing (again) that the problem is due to Col trying to use some memory range that WPFFC is using as protected memory on 32-bit systems.

The MSKB article says it has to do with video drivers, but that information is suspect as there was no issue with loading M:C until I installed Express 2010 (yesterday).
 
I now get an assert in CvPlayer::doTurn()

FAssert(checkPower(false)); (at the end of function)

Looks to me like it calculates the combined power of all units and then compares it with the cached combined power, which failed because they are different. It then compares assets against cache, which fails too.

|cached|actual
Power|327|302
Assets|2258|2333
On top of that it also fails the check mapAreaPower[pArea->getID()] = pArea->getPower(getID())

(own notes to find this again later)
pArea->getID() = 57359
getID() = 10

The civilization in question is Visigoths.

What did the AI do to drop 25 power while gaining 75 assets?

And I figured this may relate to Nightinggale's problem loading M:C on his 32-bit system (laptop?), I'd post something about it.
Perfect timing. I may have to go out of town next week or the week after that. It would be great if I could get the laptop to work before I leave.
 
Top Bottom