Based on this thread and a

district cost thread on Reddit, I think I have worked out the

COST_PROGRESSION_GAME_PROGRESS formula. It looks like it is essentially the same as the district cost formula, but with a variable scale and no below-average discount. The value is the fraction of techs or civics complete (whichever is more), expressed as a whole number percentage.

techProgress = # techs / 68

civicProgress = # civics / 51

progress = math.floor(100 * math.max(techProgress, civicProgress))

The maximum cost is based on the

PointProgressionParam1 value, which is a percentage of base cost:

maxCost = baseCost * param / 100

The total cost is then a linear interpolation from base to maximum cost (rounded down):

cost = lerp(baseCost, maxCost, progress / 100)

The

COST_PROGRESSION_NUM_UNDER_AVG_PLUS_TECH formula seems to work the same way, except that the maximum cost is always 1000% (like the Aqueduct and Neighborhood districts). For this progression, the parameter is instead the per cent discount for having fewer than the average number of districts of the type. For the current game rules, that is a 40% discount for all districts.

discountCost = math.floor(baseCost * (1 - param / 100))

I am testing this against save files from a game I just finished. So far the values work out for specialty district costs, aqueduct costs, and district project costs. I have one save with 44/68 techs progress:

progress = math.floor(100 * 44 / 68) = 64%

**specialty district / neighborhood**

baseCost = 54

maxCost = 54 * 1000% = 540

cost = lerp(54, 540, 64%) = 356

**discounted specialty district**

discountCost = math.floor(54 * 0.6) = 32

maxCost = 32 * 1000% = 320

cost = lerp(32, 320, 64%) = 216

**aqueduct**

baseCost = 36

maxCost = 36 * 1000% = 360

cost = lerp(36, 360, 64%) = 243

**district project**

baseCost = 25

maxCost = 25 * 1500% = 375

cost = lerp(25, 375, 64%) = 249

These exactly match the values in my production panel.

EDIT: After measuring a few games, I noticed that some of my numbers were off by one, so I verified counts, and it appears that my example should have been 44/68 = 64% instead of 43/67 = 64%. I suspect that the older threads are missing a tech that wasn't there at launch, perhaps Future Tech? Some of the numbers change depending on exactly how you multiply and round, and this model seems most consistent with my measurements so far.