Advertisement
Civilization Fanatics' Center

Go Back   Civilization Fanatics' Forums > CIVILIZATION IV > Civ4 - Colonization > Civ4Col - Strategy & Tips > Civ4Col - Strategy Articles

Notices

Reply
 
Thread Tools
Old Sep 27, 2008, 02:16 PM   #1
misterslack
Chieftain
 
Join Date: Jul 2007
Posts: 42
Price Change Mechanics

This is an overview of the mechanics governing the buy/sell prices of commodities in Europe. It's a bit complex and there is some math involved. The game uses the term "yield" to refer to the commodities (horses, silver, rum, etc), so I'll use that term here.

First I'll go over the variables that determine the prices then I'll explain the actual mechanics.

1. YieldBoughtTotal
For each type of yield, this value tracks the total amount of that yield that you've bought minus the total amount you've sold throughout the game. It starts off at zero. For example, if you sell 100 silver, the YieldBoughtTotal for silver goes down by 100. If you buy 300 horses, the YieldBoughtTotal for horses goes up by 300.

2. PriceChangeThreshold
For each multiple of this value that YieldBoughtTotal exceeds (positively or negatively) the price has a higher and higher chance of changing. It's stored in Assets\XML\Terrain\CIV4YieldInfos.xml. The threshold values are:
  • 1500 for cloth, coats, rum, cigars
  • 1000 for food, lumber, cotton, fur, sugar, tobacco, ore
  • 600 for tools, guns, horses, goods
  • 100 for silver (really low!)
This value is modified by handicap percentage based on your difficulty level. The percentages are:
  • Pilgrim 200%
  • Pioneer 120%
  • Explorer 100%
  • Conquistador 90%
  • Governer 80%
  • Patriot 70%
  • Revolutionary 60%
These values are stored in Assets\XML\GameInfo\CIV4HandicapInfo.xml

3. BuyPriceLow, BuyPriceHigh, SellPriceDifference
These values determine the starting price of the yield. The price Europe pays you for the yield, called the "buy price", is simply a random number between BuyPriceLow and BuyPriceHigh, inclusive. The price you pay to Europe for the yield, called the "sell price", is the buy price plus SellPriceDifference. The values are:
  • high, low, difference
  • Food 0, 2, 8
  • Lumber 0, 1, 3
  • Silver 19, 19, 1
  • Cotton 3, 5, 2
  • Fur 4, 6, 2
  • Sugar 4, 6, 2
  • Tobacco 3, 5, 2
  • Ore 2, 4, 3
  • Cloth 8, 12, 1
  • Coats 8, 12, 1
  • Rum 8, 12, 1
  • Cigars 8, 12, 1
  • Tools 1, 2, 1
  • Muskets 3, 5, 3
  • Horses 1, 2, 1
  • Trade Goods 1, 2, 1
Note again that the values are random; start up a game and you'll see cloth, coats, rum and cigars all at different starting prices, even though they all have the same high/low/difference values. Also, these are not in any way limits on the maximum or minimum price. The maximum price for any yield is unbounded (I think), and the minimum price is always 1.

Again these values are stored in Assets\XML\Terrain\CIV4YieldInfos.xml.

4. PriceCorrectionPercent
This value isn't really a percent as it's name says, but a multiplier that helps determines the chance of the price changing when YieldBoughtTotal exceeds PriceChangeThreshold.
The value is 5 for silver, and 1 for everything else. Stored in Assets\XML\Terrain\CIV4YieldInfos.xml.

Now for the actual mechanics. Each turn the game determines a "target price" for each yield, and then does a random check to see if the actual price changes by 1 towards the target price (+1 if the target price is higher, -1 if the target price is lower). The actual price can only change by 1 each turn. The target price starts as a random number between BuyPriceLow and BuyPriceHigh. Then you add YieldBoughtTotal / PriceChangeThreshold (remember YieldBoughtTotal can be negative). The division is an integer division so decimal remainders are dropped. Next you take the absolute value of the difference between the target price and the actual price. and multiply it by PriceCorrectionPercent (5 for silver, and 1 for everything else; silver is volatile). This final value is the percent chance of a price change occurring.

If that seems complex, let's do muskets as an example. The musket starting price is between 3 and 5, so we'll say the game rolls a 4. Initially your YieldBoughtTotal is zero. PriceChangeThreshold for muskets is 600. Let's look at what happens if you don't buy or sell any muskets. Each turn the game computes the target price, which will be another random number between 3 and 5, let's say it rolls a 5. YieldBoughtTotal is zero, so the target price isn't modified. The difference between the target price (5) and the actual price (4) is 1, and the PriceCorrectionPercent for muskets is 1, so there is a 1% chance of a price change this turn. If a price change did occur, it would be +1 from 4 to 5, always towards the target price. Had you rolled a 3 for the target price, the price would have a 1% chance of going down by one this turn. The key here is that the price always has a small chance of fluctuating by a bit even if you don't trade in that yield.

Now let's say you go and buy 1000 muskets to fight the Spanish. Your YieldBoughtTotal is now 1000. The target price will now be computed as random[3, 5] + 1000/600, or random[3, 5] + 1 since decimals are truncated. Let's say the actual price is still 4, and you roll a 5 on the random, then the target price would be 6. The difference is 6-4 = 2, so there would be a 2% chance of the price going up.

The spanish are really pressing you and you've had to buy 3000 more muskets. Your YieldBoughtTotal is now 1000+3000 = 4000. You've gotten lucky however, and the price is hasn't gone up from 4. Now your target price is going to be random[3, 5] + 4000/600 = random[3, 5] + 6 = 9 to 11. Your chance of the price going up is between 5% and 7% each turn.

Let's see how volatile silver is. The high and low are both 19, so the price doesn't have any random variance. The PriceChangeThreshold is only 100(!!), and the PriceCorrectionPercent is 5 instead of the usual one, so your chance of change will be five times higher than it normally would be. Let's say you sell 300 silver so your YieldBoughtTotal is -300 (remember it goes down when you sell). Then the target price is 19 - 300/100 = 16. The starting price is always 19, so the difference is 19-16 = 3%, but we multiply by PriceCorrectionPercent to get 5 * 3% = 15% of the price dropping! Silver is very volatile indeed.

Finally, the Mercantile trait of the Dutch: it simply cuts your trading volume in half. So if you sell 300 tobacco, it only counts as you having sold 150, so your YieldBoughtTotal goes up or down half as quickly. This means you can sell twice as many goods as the competition before you get the same price increase.

Here is C++ pseudo-code for process (the actual function is CvPlayer::doPrices() in CvGameCoreDLL\CvPlayer.cpp).

Code:
for each yield
{
	int newPrice = random(BuyPriceLow, BuyPriceHigh) + (YieldBoughtTotal / PriceChangeThreshold);

	if (random(100) < PriceCorrectionPercent * abs(newPrice - currentPrice))
	{
		newPrice = clamp(currentPrice - 1, newPrice, currentPrice + 1);
		setYieldBuyPrice(newPrice);
	}
}

Last edited by misterslack; Sep 28, 2008 at 09:34 AM.
misterslack is offline   Reply With Quote
Old Sep 28, 2008, 05:50 AM   #2
mboza
Warlord
 
Join Date: Dec 2005
Posts: 293
Nice work.

Couple of points that I want to add.

The actions of other Europeans seem to have no effect on your prices. Does not matter how expensive silver is in Madrid compared to London.

The prices will lag behind the target price. The target price moves linearly as you trade, (and could go negative) but the actual price moves proportionally to the difference between the the target and actual, which will delay the change.

It is worth noting the the price of goods will not recover over time, outside of the random variation between buylow and buyhigh. Silver will only increase in price if you start buying it. Other goods will only recover in price after they reach their target value, as the difference between buylow and buyhigh allows it to oscillate around the target.

If you buy a galleon full of silver, the target price will change by 6, and so the price will move by 6 (hopefully quite soon), allowing you to sell it all at the higher price and pocket the difference. Not really a feasible tactic because you pay tax on the total, not the difference, and you need a lot of gold, and I have not bothered to calculate the time scale for the price change.
mboza is offline   Reply With Quote
Old Sep 28, 2008, 05:56 AM   #3
TechnoMule
Chieftain
 
TechnoMule's Avatar
 
Join Date: Sep 2008
Posts: 86
Very nice work, misterslack. Thanks for posting this.
TechnoMule is offline   Reply With Quote
Old Sep 28, 2008, 06:28 AM   #4
player1 fanatic
Deity
 
player1 fanatic's Avatar
 
Join Date: Mar 2002
Location: Belgrade, Serbia
Posts: 2,266
Gender: Male
Quote:
Originally Posted by mboza View Post
The actions of other Europeans seem to have no effect on your prices. Does not matter how expensive silver is in Madrid compared to London.
Great change compared to original, were prices of muskets inflated and prices of silver deflated like mad on higher difficulties due to AI actions.
player1 fanatic is offline   Reply With Quote
Old Sep 28, 2008, 09:27 AM   #5
misterslack
Chieftain
 
Join Date: Jul 2007
Posts: 42
Quote:
Originally Posted by mboza View Post
The actions of other Europeans seem to have no effect on your prices. Does not matter how expensive silver is in Madrid compared to London.
This is correct and I should have added this. The code is actually present: buying/selling in other European markets would add a percentage of the volume to your totals, so if you're the English, and the Spanish buy 100 guns, and the market correlation constant was 10%, you'd get 100 * 10% = 10 to your totals. However this constant, called EUROPE_MARKET_CORRELATION_PERCENT in the XML, is currently zero.
misterslack is offline   Reply With Quote
Old Sep 28, 2008, 12:27 PM   #6
OSaft
Chieftain
 
Join Date: Oct 2006
Posts: 41
Is there an adjustment for Gamespeed? I can't find it.
More Turns -> More Produktion -> Lower Price at the end of the Epic/Marathon Game.
OSaft is offline   Reply With Quote
Old Sep 28, 2008, 02:34 PM   #7
mboza
Warlord
 
Join Date: Dec 2005
Posts: 293
I guess it got set to zero at some point during development. Shame, as I quite liked selling muskets in Europe in the original, even without using the tax-free soldiers exploit.

I would also have liked to see a units/turn threshold, rather than total to date, and prices updated after each transaction, rather than each turn.
mboza is offline   Reply With Quote
Old Oct 01, 2008, 04:20 AM   #8
kolpo
Warlord
 
Join Date: Sep 2003
Posts: 143
In the original colonization was the price of the 4 finish cash crop goods(coats, cloth, cigars, rum) linked, if the price of one of those would drop, would the price of another of them rise. The overage price of all those 4 always stayed around 10. It seems this is no longer the case in col2.
kolpo is offline   Reply With Quote
Old Oct 02, 2008, 09:14 AM   #9
.Spartan
Chieftain
 
.Spartan's Avatar
 
Join Date: Jul 2007
Posts: 25
Awesomeness. Great thread. I have already revamped my econ system since I play on super huge maps with marathon settings and max civs I doubled all the thresholds and boosted silver 10x.
__________________
modcraft.net
.Spartan is offline   Reply With Quote
Old Oct 02, 2008, 09:44 AM   #10
Turinturambar
Prince
 
Join Date: Dec 2005
Posts: 368
Great post. Does anyone else feel that the price changes for processed goods are far too low? If I understand the math correctly, if you have sold 3000 coats (a rdidicolous amount) the price would only have a 2% chance on average to go down.
Turinturambar is offline   Reply With Quote
Old Oct 02, 2008, 11:02 AM   #11
SerriaFox
King
 
SerriaFox's Avatar
 
Join Date: Mar 2008
Location: Texas
Posts: 751
Images: 2
2% per turn

10 turns= 20% chance of price change, and the more you sell the higher the chance. And yes 10 turn does not quite = 20%, but I don't want to do the math right now.

How hard would it be to increase the number of good allowed before the price changes by, x times the game turn number?
SerriaFox is offline   Reply With Quote
Old Oct 04, 2008, 06:16 PM   #12
Refar
Deity
 
Refar's Avatar
 
Join Date: Apr 2005
Posts: 4,608
So if i read this correctly, changing PriceCorrectionPercent to 0 will fix the prices for the entire game ?
__________________
The graphics in the game doesn't necessarily show you what's going on. Its just the way they've been animated.
So if you ever see any Heavy Bolter squads standing on a slope firing into the air or the ground, you may rest assured they are in fact blasting the enemy.
--------------- From a Dawn of War review.
Refar is offline   Reply With Quote
Old Oct 05, 2008, 03:43 AM   #13
alpaca
King of Ungulates
 
alpaca's Avatar
 
Join Date: Aug 2006
Posts: 2,164
I think the game needs a certain base supply and demand for goods in Europe (i.e. the YieldBoughtTotal should be normalized towards 0)
alpaca is offline   Reply With Quote
Old Oct 05, 2008, 05:02 AM   #14
Refar
Deity
 
Refar's Avatar
 
Join Date: Apr 2005
Posts: 4,608
Yes, Exactly ^^

As it is now only one side of the market is present. Nothing happens in Europe, so basicly all the good you ever sold there stick around at the Docks forever, making the price never recover. I wonder why the Europeans buy all that booze from me, if they are notgoing to drink it.

There need to be some decay factor in the YieldBoughtTotal.

I think it might be good to make it decay quite fast in fact.
With a bit of randomnes to it.
But correlate all 4 euro-markets and make all goods more volatile.

So if the pesky Dutch delivered a Merchantman full of booze just the very turn before your ship arrived, the prices would be very low. But it would recover eventually.
Over not too long - maybe a few turns - so Selling right now or making your Ship wait in europe for a while would become a viable decision.
__________________
The graphics in the game doesn't necessarily show you what's going on. Its just the way they've been animated.
So if you ever see any Heavy Bolter squads standing on a slope firing into the air or the ground, you may rest assured they are in fact blasting the enemy.
--------------- From a Dawn of War review.
Refar is offline   Reply With Quote
Old Oct 05, 2008, 12:20 PM   #15
SerriaFox
King
 
SerriaFox's Avatar
 
Join Date: Mar 2008
Location: Texas
Posts: 751
Images: 2
Should be easy to write in the end of turn script something like:

yeildboughttotal= yeildboughttotal + othernationsyieldboughtthisturn

if yieldboughttotal > 0 then
____ yieldboughttotal=yieldboughttotal - x

else if yieldboughttotal < 0 then
____ yieldboughttotal=yieldboughttotal + x
SerriaFox is offline   Reply With Quote
Old Oct 05, 2008, 09:06 PM   #16
historix69
Warlord
 
Join Date: Sep 2008
Posts: 205
If you implement a "constant" decay, you should think about Europe's population growing during the game and so demands for finished goods will also grow.

Another method would be a decay by a certain percentage, simulating an invisible market which will slowly balance the prices again ... if you sell too much, prices will drop and more people can afford to buy this good until prices recover ... The same with buying a lot of pieces of a certain good ... prices will go up, manufacturers in homeland will increase production ... prices will drop

You could use similar mechanics as the Rebel Sentiment Decay in cities :
yieldboughttotal = ( (iTurnfactor -1) * yieldboughttotal ) / iTurnfactor;
iTurnfactor for Rebel Sentiment is 10 (normal) and 30 (marathon), so on normal the stack would decay by 10% per turn and on marathon by 3.33% ...

If the decay is to strong, you can use smaller values like 1% and 0.33% ... (iTurnfactor = 100 and 300.)
If you do not sell too many goods, the decay will give you stable market prices ... if prices drop, you can stop selling and prices will recover ...

However I have the feeling that people might try to exploit this by massing goods and then selling everything in one turn at high prices ... To counter this, the prices for a good should not only be calculated each turn but also be calculated new after each traded stack of 100 / 300 pieces, including equipment of pioneers, soldiers, dragoons, scouts with tools, guns or horses.

Last edited by historix69; Oct 06, 2008 at 12:03 PM.
historix69 is offline   Reply With Quote
Old Oct 06, 2008, 05:28 AM   #17
alpaca
King of Ungulates
 
alpaca's Avatar
 
Join Date: Aug 2006
Posts: 2,164
What about this option: Add an unlimited size warehouse in Europe where all your sold goods are stored (the number of goods there should be displayed). Each turn, supply and demand in Europe are chosen randomly (could be influenced by any number of factors, for example the price evaluated relative to a certain base value) and the price of the goods would solely depend on supply and demand. Whenever you sell a good, the price is re-checked which will make the good cheaper eventually; when you buy one, it will similarly become more expensive.
Also at the start of turn, the demand should be deducted and the supply should be added to the pool. This is basically the same as a decay but adds a lot of flavor. Furthermore, you can run out of goods if you buy too much of a certain item. Demand should obviously be high for colonial goods while supply should be high for tools, horses and stuff.
alpaca is offline   Reply With Quote
Old Oct 25, 2008, 05:37 AM   #18
Daniel Shays
Chieftain
 
Join Date: Mar 2006
Location: Germany
Posts: 24
market correlation

In case anybody is interested...
it is very easy to correlate the markets of the European colonizing powers.

In GlobalDefines.xml there is an entry for that

<DefineName>EUROPE_MARKET_CORRELATION_PERCENT</DefineName>
<iDefineIntVal>0</iDefineIntVal>

Change it if you want prices in the various countries to influence each other.
Thus if you buy muskets or tools like mad you would also make them more expensive for your rivals.
Daniel Shays is offline   Reply With Quote
Old Oct 25, 2008, 06:25 AM   #19
player1 fanatic
Deity
 
player1 fanatic's Avatar
 
Join Date: Mar 2002
Location: Belgrade, Serbia
Posts: 2,266
Gender: Male
That's one of the things, I would never ever want back from Col1.
player1 fanatic is offline   Reply With Quote
Old Oct 27, 2008, 01:48 PM   #20
benfp
Chieftain
 
benfp's Avatar
 
Join Date: Jul 2008
Location: Paris
Posts: 61
Indeed it is pretty weird some goods consumption algorithm was written for Natives and not for Europeans.
benfp is offline   Reply With Quote
Reply

Bookmarks

Go Back Civilization Fanatics' Forums > CIVILIZATION IV > Civ4 - Colonization > Civ4Col - Strategy & Tips > Civ4Col - Strategy Articles > Price Change Mechanics

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Advertisement

All times are GMT -6. The time now is 10:22 PM.


Powered by vBulletin®
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
This site is copyright Civilization Fanatics' Center.
Support CFC: Amazon.com | Amazon UK | Amazon DE | Amazon CA | Amazon FR