Modmodding Q&A Thread

Ok, I've finally gotten around to checking everything. All of the XML files are in correct (there aren't any XML errors anymore), but the game is still crashing, despite the PythonLog being empty. I am guessing that I might have screwed up in writing Venice's UHV. I had to write a new definition to check the largest navy.

Here it is:

Spoiler :
Code:
		elif (iPlayer == iRome):
			if (pRome.isAlive()):
				if not pRome.isReborn:
##Roman UHV

				else:
					if (iGameTurn <= getTurnForYear(1210)):
						bConstantinople = self.controlsCity(iRome, tConstantinople)

						if bConstantinople:
							self.setGoal(iRome, 0, 1)
						else:
							self.setGoal(iRome, 0, 0)
					if (iGameTurn == getTurnForYear(1500)):
						if self.getBestNavy(iRome) == iRome:
							self.setGoal(iRome, 1, 1)
						else:
							self.setGoal(iRome, 1, 0)
					if (iGameTurn == getTurnForYear(1000)):
						if (pRome.getGold() >= utils.getTurns(10000)):
							self.setGoal(iRome, 2, 1)
						else:
							self.setGoal(iRome, 2, 0)

And here is my new definition:

Spoiler :
Code:
	def getBestNavy(self, iCiv):
		iCGalley = CvUtil.findInfoTypeNum(gc.getUnitClassInfo, gc.getNumUnitClassInfos(), 'UNITCLASS_GALLEY')
		iCTrireme = CvUtil.findInfoTypeNum(gc.getUnitClassInfo, gc.getNumUnitClassInfos(), 'UNITCLASS_TRIREME')
		iCCaravel = CvUtil.findInfoTypeNum(gc.getUnitClassInfo, gc.getNumUnitClassInfos(), 'UNITCLASS_CARAVEL')
		iCGalleon = CvUtil.findInfoTypeNum(gc.getUnitClassInfo, gc.getNumUnitClassInfos(), 'UNITCLASS_GALLEON')
		iCFrigate = CvUtil.findInfoTypeNum(gc.getUnitClassInfo, gc.getNumUnitClassInfos(), 'UNITCLASS_FRIGATE')
		iCShipOfTheLine = CvUtil.findInfoTypeNum(gc.getUnitClassInfo, gc.getNumUnitClassInfos(), 'UNITCLASS_SHIP_OF_THE_LINE')

		iBestNavy = iCiv
		iLargestNavy = gc.getPlayer(iCiv).getUnitClassCount(iCGalley) + gc.getPlayer(iCiv).getUnitClassCount(iCTrireme) + gc.getPlayer(iCiv).getUnitClassCount(iCCaravel) + gc.getPlayer(iCiv).getUnitClassCount(iCGalleon) + gc.getPlayer(iCiv).getUnitClassCount(iCFrigate) + gc.getPlayer(iCiv).getUnitClassCount(iCShipoftheLine)
		for iLoopCiv in range(con.iNumPlayers):
			iTempNavy = gc.getPlayer(iLoopCiv).getUnitClassCount(iCGalley) + gc.getPlayer(iLoopCiv).getUnitClassCount(iCTrireme) + gc.getPlayer(iLoopCiv).getUnitClassCount(iCCaravel) + gc.getPlayer(iLoopCiv).getUnitClassCount(iCGalleon) + gc.getPlayer(iLoopCiv).getUnitClassCount(iCFrigate) + gc.getPlayer(iLoopCiv).getUnitClassCount(iCShipoftheLine)
			if iTempNavy > iLargestNavy:
				iBestNavy = iLoopCiv
				iLargestNavy = iTempNavy
		return iBestNavy

Are there any problems there? That is the place where I've likely screwed up.
 
Yes, because you edited the scenario with world builder and saved everything in the state it was when you started the game.

Either edit it and save it in a separate file, then only copy over the plotinfo stuff into the scenario, or use Notepad++ to make your changes.

Oh, now I get it. It works perfectly. Thank you very, very much:goodjob:
 
Are there any problems there? That is the place where I've likely screwed up.
The Python code looks okay, and isn't likely to cause a crash right on start anyway.

That you don't get any XML error messages doesn't mean you haven't made any mistakes, especially for the art defines. Have you checked if everything there is okay (civilopedia before launching the game)? I still recommend disabling your XML additions step by step until the crash disappears.
 
The Python code looks okay, and isn't likely to cause a crash right on start anyway.

That you don't get any XML error messages doesn't mean you haven't made any mistakes, especially for the art defines. Have you checked if everything there is okay (civilopedia before launching the game)? I still recommend disabling your XML additions step by step until the crash disappears.

I fixed a major Civilopedia error, and now the scenario crashes after I select the scenario and begin it instead of upon loading. Is there any easy way to disable added features or do I have to do it manually?
 
Manually. The best way to go for art tags is to temporarily change their paths so they point to the art of the unit/building they replace instead.
 
Got that one too. So I replaced all the info of the civs. The scenario that with these changes I already uploaded a few posts above.

My game crashes whenever I try to open it. Are you sure you've fixed everything? Which upload are you referring to?

I get this error message:

File "CvBWInterface", line 47, in applyInitialItems

File "CvBWDesc", line 1706, in applyInitialItems

RuntimeError- unidentifiable c++ exception
 
Seems there is something wrong with the WBSave, I recommend opening WBDesc.py (it's not in the mod folder, but in Beyond the Sword\Assets\Python\pyWB\) on the line mentioned, there will be a method along the lines of add[...]toWB() or something, where [...] can be units, terrain etc., so you know roughly what to look for.
 
Out of curiosity, I made a 3000 BC start, and I got these errors (having to deal with BUG):
 

Attachments

  • Civ4ScreenShot0029.JPG
    Civ4ScreenShot0029.JPG
    94.3 KB · Views: 269
Read your logs.
 
Seems there is something wrong with the WBSave, I recommend opening WBDesc.py (it's not in the mod folder, but in Beyond the Sword\Assets\Python\pyWB\) on the line mentioned, there will be a method along the lines of add[...]toWB() or something, where [...] can be units, terrain etc., so you know roughly what to look for.

Where do I find the error messages to copy and paste? I can't copy from the popup ingame and it only lasts a few seconds before crashing.
 
If you have also enabled logging, in My Games/Beyond the Sword/Logs/PythonErr.log.
 
OK, I decided to use my own save because there wasn't any correlation to his. It has the same problem, but different errors. The bolded is the error message, the code is from CvWBDesc.py.

Traceback (most recent call last):

File "CvWBInterface", line 47, in applyInitialItems


Code:
	def findTokenValue(self, toks, item):
		"Search for a token of the form item=value in the list of toks, and return value, or -1 if not found"
		for tok in toks:
			l=tok.split("=")
			if (item==l[0]):
				if (len(l)==1):
					return item		
				return l[1]
		return -1		# failed

File "CvWBDesc", line 1720, in applyInitialItems

Code:
		# cities
		for pDesc in self.plotDesc:
			pDesc.applyCity()

File "CvWBDesc", line 1152, in applyCity

Code:
	def applyCity(self):
		if self.cityDesc:
			#print "--apply city"
			self.cityDesc.apply()

File "CvWBDesc", line 860, in apply

Code:
	def apply(self):
		"after reading, this will actually apply the data"
		player = getPlayer(self.owner)
		if (player):
			self.city = player.initCity(self.plotX, self.plotY)

File "CvWBDesc", line 24, in getPlayer

Code:
def getPlayer(idx):
	"helper function which wraps get player in case of bad index"
	if (gc.getPlayer(idx).isAlive()):
		return gc.getPlayer(idx)
	return None

AttributeError: 'NoneType' object has no attribute 'isAlive'
ERR: Python function applyInitialItems failed, module CvWBInterface


See anything obviously wrong here?
 
Apparently a city in your WBSave is assigned to a player that doesn't exist (the ID is likely too high).
 
Apparently a city in your WBSave is assigned to a player that doesn't exist (the ID is likely too high).

What does this mean?
 
You have set CityOwner=48 when there are only civs from 0 to 47, for example.
 
How do I find and fix it? I've only edited it in WB.
 
The actual maximum ID for players is 46, just look for anything above that.
 
The actual maximum ID for players is 46, just look for anything above that.

I found that all the barb cities I placed were assigned to 54, so I made them all Native cities. This is the message I got after loading and crashing again:

Traceback (most recent call last):

File "CvWBInterface", line 47, in applyInitialItems


Code:
	def findTokenValue(self, toks, item):
		"Search for a token of the form item=value in the list of toks, and return value, or -1 if not found"
		for tok in toks:
			l=tok.split("=")
			if (item==l[0]):
				if (len(l)==1):
					return item		
				return l[1]
		return -1		# failed

File "CvWBDesc", line 1764, in applyInitialItems

Code:
		# units
		for pDesc in self.plotDesc:
			pDesc.applyUnits()

File "CvWBDesc", line 1147, in applyUnits

Code:
	def applyUnits(self):
		#print "--apply units"		
		for u in self.unitDescs:
			u.apply()

File "CvWBDesc", line 675, in apply

Code:
	def apply(self):
		"after reading, this will actually apply the data"
		player = getPlayer(self.owner)
		if (player):
			# print ("unit apply %d %d" %(self.plotX, self.plotY))
			CvUtil.pyAssert(self.plotX>=0 and self.plotY>=0, "invalid plot coords")		
			unitTypeNum = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), self.unitType)
			if (unitTypeNum < 0):
				unit = None
			else:
				if (self.szUnitAIType != "NO_UNITAI"):
					eUnitAI = CvUtil.findInfoTypeNum(gc.getUnitAIInfo, UnitAITypes.NUM_UNITAI_TYPES, self.szUnitAIType) #pUnitAI.getType()
				else:
					eUnitAI = UnitAITypes.NO_UNITAI
					
				unit = player.initUnit(unitTypeNum, self.plotX, self.plotY, UnitAITypes(eUnitAI), self.facingDirection)
			if (unit):
				if (self.szName != None):
					unit.setName(self.szName)
				#leader unit type
				if(self.leaderUnitType != None):
					leaderUnitTypeNum = CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), self.leaderUnitType)
					if leaderUnitTypeNum >= 0:
						unit.setLeaderUnitType(leaderUnitTypeNum);

File "CvWBDesc", line 24, in getPlayer

Code:
def getPlayer(idx):
	"helper function which wraps get player in case of bad index"
	if (gc.getPlayer(idx).isAlive()):
		return gc.getPlayer(idx)
	return None

AttributeError: 'NoneType' object has no attribute 'isAlive'
ERR: Python function applyInitialItems failed, module CvWBInterface
 
Take a guess.
 
Back
Top Bottom