Home - Articles

Victory Score Formula

So a while ago, I played a marathon game as Rome, seeking a high score, and registered north of 1,200,000 points. I was still never quite satisfied with that, after reading of a game by WastinTime that topped 3,100,000. How do those numbers work? I had to take a deep dive into the formulas to understand it.

I'll first review how the in-game score works. You receive points in each of four categories: population, land, technology, and wonders. These components are displayed when you mouseover your name on the scoreboard in game, and the total is shown all the time on the scoreboard. The scoring in each of these categories depends on the maximum score available for that category, and on a weight factor found in GlobalDefines.xml.

For each category, Score = Factor * Base / Max.

Population: Factor = 5000. The base value is simply the total population points of your civilization or team, plus half the population (rounded down) of your vassals. The max is calculated specific to each map, as the maximum possible population that could be supported by the aggregate food production of every tile on the map. This calculation doesn't take into account other food sources like supermarkets and settled Great Merchants and of course corporations, so it's possible to exceed the "maximum", which we'll get to later. Angry or unhealthy or revolting population all counts. Each population point is therefore worth 5000/Max points.

Land: Factor = 2000. The base value is 1 per land tile that you or your team have held for at least twenty turns, again plus half that of vassals. Max is the total number of land tiles on the map, which obviously can't be exceeded. Each land tile is therefore worth 2000/Max points.

Tech: Factor = 2000. Every technology is worth 1 base point per its era; ancient techs are worth 1, up to modern techs worth 6 and future techs worth 7. The max score for the whole tech tree adds up to 334 in the unmodded game, including Future Tech 1 but can be exceeded with more Future Techs. Each technology is therefore worth 2000*Era/334 points, which is the well-known among multiplayerists value of 5.988 points per era.

Wonders: Factor = 1000. Every wonder scores 5 base points. National wonders count, including the Palace, as do shrines and corporate HQs. Projects do not. Max is 310 because 62 wonders exist in the unmodded game, making each wonder worth 1000*5/310 = 16.129 points.

The idea is that achieving the maximum mark in a category gives you [Factor] points. Knowing all technologies earns 2000 tech points. If you play a "perfect" game reaching the maximum in all categories, that's a "perfect" score of 10,000 points.

Now for the major topic of this discussion: the score bonus for winning.

A bonus is applied to the winning player's score, commonly called the normalization or exponentiation or extrapolation formula, or victory score. The idea is to give the player exponential credit for winning quickly based on the time remaining before the end of the game in 2050 AD. This exponential credit has been described as "double for each remaining 10% of the game", so if you were to win on turn 350 out of 500 with 30% of the game remaining, you'd get three doublings or an 8x multiplier to the final score. This is the general idea but the real mechanics go much deeper.

Here is the Python function that calculates the score exponentiation, from CvUtil.py, with nonrelevant lines stripped out.

def getScoreComponent(iRawScore, iInitial, iMax, iFactor, bExponential, bFinal, bVictory):

	if bFinal and bVictory:
		fTurnRatio = float(gc.getGame().getGameTurn()) / float(gc.getGame().getEstimateEndTurn())
		if bExponential and (iInitial != 0):
			fRatio = iMax / iInitial
			iMax = iInitial * pow(fRatio, fTurnRatio)
			iMax = iInitial + fTurnRatio * (iMax - iInitial)

	iScore = iFactor * iRawScore / iMax

	if bFinal:
		iScore = ((100 + gc.getDefineINT("SCORE_HANDICAP_PERCENT_OFFSET") + (gc.getGame().getHandicapType()
		       * gc.getDefineINT("SCORE_HANDICAP_PERCENT_PER"))) * iScore) / 100

	return int(iScore)

This function runs separately for each of the four components, truncating to integer at the end, then each result is added together for the final victory score.

iRawScore is your base value for each component, such as 370 population or 204 land tiles or whatever. iMax is the maximum value per component as described above. iFactor is the weighting component as described above. For our purposes, assume that the booleans bExponential and bFinal and bVictory are always true.

iInitial is a value that represents the "starting" score for each component, the intent probably being to discount for a later-era or modded start where you begin with more stuff. In a standard game, iInitial = 1 for population, 21 for land, 6 for technology, and 0 for wonders.

The block at "if bFinal" applies the difficulty modifier after all the extrapolation. This is 100% at Noble 20% per level, so 40% at Settler, 180% at Immortal, and 200% at Deity.

Rearranging all the code into algebraic terms results in this. Square brackets mean round down to integer. (The variable fRatio is misnamed, it actually comes out as an integer, not a float.)

iScore = iFactor * iRawScore * Difficulty modifier
iInitial * [iMax / iInitial] ^ (CurrentTurn / MaxTurn)

There's a lot of interesting things going on here. First let's delve into that exponential term in the denominator of [iMax / iInitial] ^ (CurrentTurn / MaxTurn). This is an unusual way of doing the exponentiation. Rather than take the numerator iRawScore to a large exponent, we take the denominator involving iMax to a fractional exponent, since CurrentTurn/MaxTurn is something like 350/500 or 0.7. I am guessing this was done to avoid very large numbers and overflow problems that might arise if iRawScore were raised to a large positive exponent.

We see that the exponentiation is not done on iRawScore which we might intuitively expect, or on iRawScore/iMax (that's what the score mouseover shows, like 74/334 for technologies.) The exponentiation is done on iMax/iInitial. This ratio represents the possible magnification improvement relative to your starting conditions of 1 pop, 21 land, and 6 technology points. A map with say 105 land tiles allows a 5x improvement from your start. A map with 2100 land tiles allows a 100x improvement from your start.

For that hypothetical 2100-tile map, you are "expected" to reach this 100x magnification at the end of the game in 2050 AD. If you win sooner, your expected value at the moment of victory is reduced by this fractional exponentiation. Suppose you win on turn 275 of 500, which is 55% or 0.55 of the turns in the game. Your "expected" magnification is not 100 times, but only 100 ^ 0.55 = 25 times. If you have actually achieved 100x magnification in the time you're supposed to achieve 25x, you've done 4 times as well as "expected". So this score component receives a 4x bonus, thanks to this denominator getting reduced to 25 instead of 100.

This is why bigger maps are better for victory score. Consider a tiny map with 105 land tiles where only a 5x magnification from your starting 21 land tiles is possible. Fractional exponentiation can only reduce a number asymptotically to 1. So no matter how fast you win, you can only reduce that "expected" 5x magnification to 1x, and you can only pick up a 5x multiplier to the victory score. A bigger map could have a 100x magnification possible and expected, which by winning quickly you could drastically reduce to an expected value of say 3x and pick up a multiplier of 33.3 for victory score. This is how a mundane in-game score value like 10,000 can become a massive victory score number of 300,000 or more.

How fast would you have to win to reduce a 100x expected magnification to 3x for that 33.3 multiplier? 100 ^ T = 3, so T = log 3 / log 100. T = 0.24 so you have to win in the space of 24% of the game turns, which is turn 120 of 500 on normal speed or 360 of 1500 on marathon. That's around 50 AD, just about on the edge of possibility.

To summarize, you are not judged on your component score relative to the map maximums, as you are for score during the game before victory. There are two things wrong with that perception: you are judged on your magnification relative to the game starting values rather than the raw score, and you are judged on your magnification relative to a maximum magnification that is exponentially discounted based on the remaining time in the game. Bigger maps come out ahead because that maximum starts at a higher number with more room to discount.

That's most of the story, but not quite all. That exponentiated value forms most of the denominator for iScore, but there is one more component lurking in that denominator: iInitial. This means your victory score for a component is also divided by the initial value. Those initial values are 1 for population, 21 for land, 6 for technology, and 0 for wonders.

What this means is that population overwhelms the other factors. Because of those initial values, 1 population is as good as 21 land tiles. A map with 2100 grassland tiles allows a 100x improvement from your start in land score, but allows a 2100x improvement from your start in population score. To go for the highest score, find a map that allows the most total population before triggering domination. (A Big and Small map using food from Sid's Sushi is the best known approach, as WastinTime discovered.)

And population overwhelms the other components not only because the small initial value of 1 allows a great magnification, but also since population is the only component where you can drastically exceed the supposed "maximum" value. Obviously you can't own more land tiles than exist on the map, build more wonders than exist on the tech tree, or research much more technology than exists in the civilopedia. (Future Techs are there but don't score enough; you'd need 48 of them to double the baseline.) But thanks to corporation food, it's possible to create double or triple or more population than the map is supposed to support.

Where do those iInitial values come from? The code function is CvGame::initScoreCalculation(). The 1 for population is actually 1 times the number of your starting settlers. The 21 for land comes from your number of starting settlers times NUM_CITY_PLOTS, which is hardcoded defined to 21 as the size of the well-known fat cross. (So it's always 21, not map dependent, it's not considered less starting land score if your capital includes water plots.) Both of these are presumably increased for later era starts with more settlers. The 6 for technology is arrived at by a possibly buggy method: this function loops over all technologies to find starting techs belonging to any civilization, so it always counts all of Fishing, Wheel, Agriculture, Hunting, Mysticism, and Mining.

For wonders, iInitial = 0. (The score formula thinks that you didn't start with a Palace.) This also has a large consequence. Look in the Python function where it tests for iInitial != 0. If iInitial is zero, the code branches to an alternate formula that skips the exponentiation step. Score from wonders does not receive an exponential bonus! Wonders get the expected max discounted only linearly. If you win on turn 350 out of 500, the expected maximum gets discounted to 350/500 = 70% of its original value so you get a modifier of 1/70% = 1.42x. This is peanuts compared to the exponential factors of 4x or 33x or 60x or more that arise from the other components. Wonders are irrelevant.

I have created implementations of this formula in Javascript and in Excel. Enjoy!

- T-hawk, November 5, 2011