Game tries to divide the score with 0 on modern era start

NotSoGood

Emperor
Joined
Jan 25, 2009
Messages
1,077
Location
Finland
I'm having problems when starting in modern era (i have only industrial, modern and future eras in my mod). The game crashes right after I start it. Industrial start works fine. So I attached VC to my mod and debugged the crash. It seems to crash when the game calculates the player's score and tries to divide with 0. :nono:
So I hunted down the code that could change the m_iMaxTech (which is returned by getMaxTech()) and the only place where it seems to be changed is when the map is regenerated! :confused:
How on earth is that possible? And why do you think only industrial era start works fine?

EDIT: The future era start works too. I think it could be a xml problem. I'll need to check that...
 
I haven't traced it all the way up. But, the field m_iMaxTech is set in CvGame::initScoreCalculation, which calls CvGameCoreUtils.cpp, getTechScore() on each tech, which returns the value getEra() + 1. So, what this does, is convert each tech to a value of (its era) + 1, and then sum this up across all techs.

I recommend you put your breakpoint in getTechScore and look at the values returned by getEra. If you have deleted the other eras, maybe there is some xml loading problem, and all the eras are getting assigned a value of NO_ERA (-1). Then getEra+1 would return 0 for all techs, and the sum would be zero.
 
That sounds possible. So I tested it starting a game at modern era and placed there few breakpoints. But the breakpoints were never run. Seems like it skipped them completely. But with industrial and future starts they were run normally. :confused:
I think it might be a simple xml error somewhere but atleast I haven't found any. I even used the civcheck tool (it's really handy).
 
So I hunted down the code that could change the m_iMaxTech (which is returned by getMaxTech()) and the only place where it seems to be changed is when the map is regenerated! :confused:
How on earth is that possible? And why do you think only industrial era start works fine?

Since initScoreCalculation is declared using DllExport it is probably called directly by the .exe file at least once.
 
Got some free time so I tried to solve this nasty problem. I commented out that part in dll that caused it to crash. I also accidentaly noticed that it showed player's tech and wonder scores as 0. Then I finally ot through to the game. Everything seemed fine, the free buildings, the tech tree. Only thing was that the score hover info wasn't displayed. :confused: Here's the commented code:
Spoiler :
Code:
		if (iMaxLand > 0)
		{
			iLandScore = (GC.getDefineINT("SCORE_LAND_FACTOR") * iLand) / iMaxLand;
		}
		int iTech = player.getTechScore();
		int iMaxTech = GC.getGameINLINE().getMaxTech();
//		int iTechScore = (GC.getDefineINT("SCORE_TECH_FACTOR") * iTech) / iMaxTech;
//		this is meant to testing I will revert it back as soon as possible...
		int iTechScore = (GC.getDefineINT("SCORE_TECH_FACTOR") * iTech);
		int iWonders = player.getWondersScore();
		int iMaxWonders = GC.getGameINLINE().getMaxWonders();
//		int iWondersScore = (GC.getDefineINT("SCORE_WONDER_FACTOR") * iWonders) / iMaxWonders;
//		this is meant to testing I will revert it back as soon as possible...
		int iWondersScore = (GC.getDefineINT("SCORE_WONDER_FACTOR") * iWonders);
		int iTotalScore = iPopScore + iLandScore + iTechScore + iWondersScore;
		int iVictoryScore = player.calculateScore(true, true);
		if (iTotalScore == player.calculateScore())
		{
			szString.append(gDLL->getText("TXT_KEY_SCORE_BREAKDOWN", iPopScore, iPop, iMaxPop, iLandScore, iLand, iMaxLand, iTechScore, iTech, iMaxTech, iWondersScore, iWonders, iMaxWonders, iTotalScore, iVictoryScore));
		}
	}
}
It doesn't display anything because the if statement isn't true. So the calculateScore seems to do it right but those getMaxWonders and getMaxTech aren't. And this problem seems to be only with the modern era start. :confused:

I would like to hear all help you can give. This kind of errors are the most annoying because they're hard to hunt down.
 
Oh, that's what causes the issue? I had that causing CTD's too a while back, and I put the divisor's in std::max(1, iVar) function calls, and it fixed that.
 
Oh, that's what causes the issue? I had that causing CTD's too a while back, and I put the divisor's in std::max(1, iVar) function calls, and it fixed that.

Hmm, I quess that would atleast not provide any CTD, but I'm trying to find out the reason why this is happening.
Does anyone know where this python function might be:
Spoiler :
Code:
int CvPlayer::calculateScore(bool bFinal, bool bVictory)
{
	PROFILE_FUNC();

	if (!isAlive())
	{
		return 0;
	}

	if (GET_TEAM(getTeam()).getNumMembers() == 0)
	{
		return 0;
	}

	long lScore = 0;

	CyArgsList argsList;
	argsList.add((int) getID());
	argsList.add(bFinal);
	argsList.add(bVictory);
	[COLOR="Red"]gDLL->getPythonIFace()->callFunction(PYGameModule, "calculateScore", argsList.makeFunctionArgs(), &lScore);[/COLOR]

	return ((int)lScore);
}
CvPlayer::calculateScore is called in the check in CvGameTextMgr setScoreHelp and it seems to calculate and return the score correctly.
 
Does anyone know where this python function might be
gDLL->getPythonIFace()->callFunction(PYGameModule, "calculateScore", argsList.makeFunctionArgs(), &lScore);
PYGameModule is defined as "CvGameInterface.py", which defines this function and calls gameUtils.calculateScore, which is in python/CvGameUtils.py. It makes several calls to getScoreComponent.
 
I have been pretty busy these last few days because of all the exams so I haven't had much time to debug this. I tried looking different things that could cause the error but found nothing so I decided just to add the std::max(1, iVar) check as Afforess did and there were no crashes. I run few modern era starts and it seemed to work properly. I don't know what caused the game to do so but atleast it's working now.
 
I like this thread....it starts with the same problem I had.

I'm also trying to make scenario work by reloading a map (I'm pretty sure).

Problem is that I haven't debugged it through it. I managed to stopped crashing in a similar way Afforess did but the score I get from all civs is pretty insane (10000 for all civs, including mine no mater how many turn I play in the scenario). I realized that the later score was cause do to the addition of the following parameters ''SCORE_POPULATION_FACTOR + SCORE_LAND_FACTOR + SCORE_WONDER_FACTOR + SCORE_TECH_FACTOR) in the function 'calculateScore' in the python file CvGameUtils.py

I hate Python...it's too lose and indentation dependent (yuck !) to me to feel good making it work right.

If someone would tell me what to write in the previous file so that I could output the results in a file...I would be most gracious.
 
If someone would tell me what to write in the previous file so that I could output the results in a file...I would be most gracious.

I am not able to understand this question. Do you mean, "how do I print to a file in python?"
Code:
f = open("c:\\foo.txt", "a")
f.write("Hello world")
f.close()
 
I managed to get the score fixed.

I was also having problems with the score being stuck at either 10000 or 0. After trying to get some fprintf working in the CvGame::initScoreCalculation() I never got a log file being created. So I decided to include a call to the latter function inside one of the accessor called CvGame::getInitPopulation().

I changed the following :

Spoiler :
int CvGame::getInitPopulation() const {
return m_iInitPopulation; }


to

Spoiler :
int CvGame::getInitPopulation() {
initScoreCalculation();
return m_iInitPopulation; }


I think the game wasn't calling the initScoreCalculation() function because I was only working with scenarios.
 
Well I noticed that my idea and fix doesn't completely work :(

The problem I have now is that the number that indicates how the respective civs score value has changed since the last turn only changes if the score goes down (negative).

I've been trying to fire up the initScoreCalculation() in python through the CvMainInterface class but I'm having problems.

As anyone ever had a similar problem with this and if so how did you (I hope) fixed it
 
Back
Top Bottom