platyping
Sleeping Dragon
For modders with basic python modding skills trying to figure out what went wrong with their python codes.
1) Activate python exceptions
Locate the CivilizationIV config ini file in My Documents/My Games/Beyond the Sword folder and set HidePythonExceptions = 0
2) Reading the python errors
Now when you encounter a python bug, you will get error messages like this. Read it bottom up. The last sentence tells you what is wrong with the code, in this case, undefined variable error. The next sentence tells you which line and file to locate the error.
You can pretty much ignore the rest, because the rest are usually errors due to the initial error.
P.S.
Error Messages only pop up for errors due to coding, such as the above, indentation error etc.
It will not pop up for logic errors, such as instead of "i + 5", it executes "i - 5", because the codes run fine.
3) Basic Errors
I) "XXX" is not defined
"XXX" would refer to a variable name, so step 1 is to locate the file and line where it is referenced. All variable names are case sensitive, so "Cow", "COW" and "cow" are 3 different variables.
Once you locate the error, read upwards and see if it is defined somewhere before in the same section, unless it is a global variable such as "gc" or defined in the ini section such as "self.xxx".
A simple one will be as above. "pUnit" is definitely not defined anywhere above the error line. In this case, "unit" should be used instead.
A more problematic one is when the variable is defined, but only under certain conditions. In this case, iGold is defined only for human players.
Thus, the obvious solution for this error is to make sure the variable is defined somewhere above, for all conditions.
II) "XXX" object has no attribute "YYY"
CyTeam object has no attribute "changeGold"
In this case, changeGold can only be used for CyPlayer, not CyTeam.
You can find most functions in the API.
A special case is when "Nonetype" object has no attribute "YYY"
If iPlayer is within the limits of 0 and max players, then pPlayer will be a valid CyPlayer object. If iPlayer is -1 or 1546346745, you will expect pPlayer to be None.
Again, by right you can use getType for a Tech Info, but what if iTech is invalid?
This can easily happen with hard coded codes as above, where there may be a spelling error, "TECH_HUNTTING" or "TECH_HUNTING" has been removed from the game, but nobody bothers to remove the codes.
III) Integer Division or Modulo by Zero
Now simple mathematics will tell you, divide anything by 0 and you get an error. So the question is, are you sure under all circumstances "dog" and "rat" will never be 0?
Thus, see what "dog" refers to, maybe culture, gold or unit level whatever, or simply add a non zero check before executing it.
IV) Indentation Error
This kind is obvious. Following a statement ending with a ":", such as if, else, for, while, def, the next statement has to be indented one additional level to the right generally.
I prefer to use "TAB", while there are others who use "SPACE" etc
V) Syntax Error
Syntax Error occurs when your fingers are itchy, and you added an extra ":", "," or ")" etc making the code problematic.
This code works fine, but you are just making your life difficult, and it is prone to syntax error if you miss a "(" or ")" somewhere.
Thus, splitting it into smaller codes will make debugging easier.
VI) Type Object "XXX" has no attribute "YYY"
For certain Type Objects such as Yield and Commerce, you can use this method directly. For others like Bonus Types, it results in an error. For those that do not work, use gc.getInfoTypeForString("BONUS_ALUMINIUM")
VII) Mismatch Input Type
This kind of error occurs when the input is of a wrong type.
changeGold is only meant to take in integers, but a float is given instead.
VIII) Import Error
For certain files like CvMainInterface, you notice there are some Import codes right at the top, such as "Import CvUtil".
These files are imported so that you can use the functions defined there. An import error means the file you are trying to import is invalid. Either a typo error, or you forgot to copy the file from a downloaded mod component.
1) Activate python exceptions
Locate the CivilizationIV config ini file in My Documents/My Games/Beyond the Sword folder and set HidePythonExceptions = 0
2) Reading the python errors

Now when you encounter a python bug, you will get error messages like this. Read it bottom up. The last sentence tells you what is wrong with the code, in this case, undefined variable error. The next sentence tells you which line and file to locate the error.
You can pretty much ignore the rest, because the rest are usually errors due to the initial error.
P.S.
Error Messages only pop up for errors due to coding, such as the above, indentation error etc.
It will not pop up for logic errors, such as instead of "i + 5", it executes "i - 5", because the codes run fine.
3) Basic Errors
I) "XXX" is not defined
"XXX" would refer to a variable name, so step 1 is to locate the file and line where it is referenced. All variable names are case sensitive, so "Cow", "COW" and "cow" are 3 different variables.
Once you locate the error, read upwards and see if it is defined somewhere before in the same section, unless it is a global variable such as "gc" or defined in the ini section such as "self.xxx".
Code:
def onUnitBuilt(self, argsList):
'Unit Completed'
city = argsList[0]
unit = argsList[1]
[COLOR="Red"]pUnit.setName("Cow")[/COLOR]
Code:
def onBeginPlayerTurn(self, argsList):
'Called at the beginning of a players turn'
iGameTurn, iPlayer = argsList
pPlayer = gc.getPlayer(iPlayer)
if pPlayer.isHuman():
iGold = 100
pPlayer.changeGold([COLOR="red"]iGold[/COLOR])
Thus, the obvious solution for this error is to make sure the variable is defined somewhere above, for all conditions.
II) "XXX" object has no attribute "YYY"
Code:
pTeam.changeGold(100)
In this case, changeGold can only be used for CyPlayer, not CyTeam.
You can find most functions in the API.
A special case is when "Nonetype" object has no attribute "YYY"
Code:
pPlayer = gc.getPlayer(iPlayer)
pPlayer.changeGold(100)
Code:
iTech = gc.getInfoTypeForString("TECH_HUNTING")
sType = gc.getTechInfo(iTech).getType()
This can easily happen with hard coded codes as above, where there may be a spelling error, "TECH_HUNTTING" or "TECH_HUNTING" has been removed from the game, but nobody bothers to remove the codes.
III) Integer Division or Modulo by Zero
Code:
x = cow / dog
y = cat % rat
Thus, see what "dog" refers to, maybe culture, gold or unit level whatever, or simply add a non zero check before executing it.
Code:
if dog != 0:
x = cow / dog
IV) Indentation Error
Code:
if i > -1:
iGold = 100
Code:
if i > -1:
iGold = 100
V) Syntax Error
Code:
if i > -1::
Code:
gc.getTeam(gc.getPlayer(CyGame().getActivePlayer()).getTeam()).setHasTech(gc.getInfoTypeForString("TECH_HUNTING"), gc.getTeam(gc.getPlayer(CyGame().getActivePlayer()).getTeam()).isHasTech(gc.getInfoTypeForString("TECH_HUNTING"), CyGame().getActivePlayer(), False, False)
This code works fine, but you are just making your life difficult, and it is prone to syntax error if you miss a "(" or ")" somewhere.
Thus, splitting it into smaller codes will make debugging easier.
Code:
iPlayer = CyGame().getActivePlayer()
iTeam = gc.getPlayer(iPlayer).getTeam()
pTeam = gc.getTeam(iTeam)
iTech = gc.getInfoTypeForString("TECH_HUNTING")
pTeam.setHasTech(iTech, pTeam.isHasTech(iTech), iPlayer, False, False)
VI) Type Object "XXX" has no attribute "YYY"
Code:
x = BonusTypes.BONUS_ALUMINUM
y = YieldTypes.YIELD_FOOD
z = UnitAITypes.NO_UNITAI
VII) Mismatch Input Type

Code:
iGold = 10.5
pPlayer.changeGold(iGold)
changeGold is only meant to take in integers, but a float is given instead.
VIII) Import Error
For certain files like CvMainInterface, you notice there are some Import codes right at the top, such as "Import CvUtil".
These files are imported so that you can use the functions defined there. An import error means the file you are trying to import is invalid. Either a typo error, or you forgot to copy the file from a downloaded mod component.