In market.cs, the important function is supplyDemand(). It's used in changeSupply(), as changePrice(eIndex, supplyDemand(getWholePrice(eIndex))). eIndex is the resource index. changePrice() calls setPrice(), setPrice() sets the price, clamping between 1-1000.
if (iWholePrice > 100)
{
iValue = (iValue / 100) + 20;
}
else if (iWholePrice > 10)
{
iValue = (iValue / 100) + 10;
}
Letting p be the current price, we learn the important formulas:
p += k(p/100 + 20) for p > 100
p += k(p/100 + 10) for p > 10
p += kp for p < 10
k is a constant which depends on the player count. From standard ODE, we derive three exponential curves as a piecewise function:
p = ce^(x/m) - 2000 for p > 100, where c and m are some constants
p = be^(x/j) - 1000 for p > 10, where b and j are some constants
p = ae^(x/i) for p < 10, where a and i are some constants
Here's how you can guarantee that Mohawk doesn't understand how its own price algorithm works. For 10 < p < 100, the change is almost a straight line, but is in fact very slightly nonlinear, for no purpose whatsoever. Notice how p/100 + 10 varies by only 9% across the range of p. For 100 < p, the change is also very slightly non-linear, also for no purpose whatsoever, with a discrepancy of only 9% for p < 300. For p < 10 it is exponential, which is where it is most complicated, and also matters least since the resource is worth nothing. The only effect of the exponential curve is to specify how many units can be sold before clamping kicks in. Here's the graph of the price change after selling a single resource: https://www.wolframalpha.com/input/?i=Plot[Piecewise[{{x,+x+%3C+10},+{10+%2B+x%2F100,+10+%3C+x+%3C+100},+{20+%2B+x%2F100,++x+%3E+100}}],+{x,+1,+200}] Notice how it is very slightly non-horizontal in each of the regions, just enough to mess with you, but not enough to affect anything.
So, what would be a better system? We can keep all the mechanics of the current system, but take out the useless complexity which has near-zero effect. This makes prices very easy to understand. If you buy 15 units, and the price is between 10 and 100, the price will change by a constant amount. If you buy 15 units, and the price is more than 100, the price will change by double that amount. For prices < 10, the price linearly tells you how far you have to go until clamping kicks in. For prices < 300, the following code has 2% standard deviation from the current system, while being much more logical. We get: https://www.wolframalpha.com/input/?i=Plot[Piecewise[{{9%2Flog+10,+x+%3C+10},+{10,+10+%3C+x+%3C+100},+{20,++x+%3E+100}}],+{x,+1,+200}]
if (iWholePrice > 100)
{
iValue = 22;
}
else if (iWholePrice > 10)
{
iValue = 10.5;
}
else iValue = 3.91;
A small edit to the constants would make everything a nice number:
if (iWholePrice > 100)
{
iValue = 20;
}
else if (iWholePrice > 10)
{
iValue = 10;
}
else iValue = 5;
EDIT: You could also remove the sudden thresholds at p=10, 100, and replace the system with a single formula, dp = p^(log 2/log10). Here, if the price becomes *10, the price change becomes *2. This makes the market hard to understand, but it's smooth and there are no jumps. Its behavior at p =10, 100 is the same as the existing formula, and it can handle even higher prices. http://www.wolframalpha.com/input/?i=plot+x^%28log2+%2F+log10%29+from+x+%3D+0+to+200
iValue = 4 * iWholePrice^(0.30103)