Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm working on a gam (naturally), and the primary activity for the player is to buy and sell commodities at various marketplaces.

Each commodity has the following properties:

Base Price: if all things were otherwise equal, this would be the measure of value for the commodity Supply Factor: when a player sells one unit of this commodity in a market, the "supply" goes up by this factor Demand Factor: when a player purchases one unit of this commodity in a market, the "demand" goes up by this factor.

Within each market, the commodities are given the following local properties: Local Supply Local Demand

To keep things "simple", I have these values generated randomly with the equivalent of a 3d6, so Supply and Demand can be anywhere from 3-18.

The price for one unit of a commodity in a particular market is calculated like so:

Price = BasePrice * (LocalDemand+DemandFactor*UnitsDemanded) / (LocalSupply+SupplyFactor*UnitsSupplied)

In this way, player purchases will drive the price up, and player sales will drive the price down.

Now comes the problem, and I'll use a concrete example as it is not entirely obvious from just looking at the formula.

We have commodity X with a base price of 100, and local demand and local supply both of 10, and a supply and demand factor each of 1.

So, desiring to purchase a single unit, I calculate the price:

Price = 100 * (10+1*0) / (10+1*0) = 100

And I purchase the unit, which drives up the price to:

Price = 100 * (10+1*1) / (10+1*0) = 110

And if the player then sells the commodity at that price, he immediately profits 10.

This is no good.

So, my first pass at this solution is to calculate the price based on what the supply or demand WILL BE after the purchase is over, which works after a fashion, but consider that in the example above, the purchase of 1 unit will be 110, whereas the purchase of 10 units will have a unit price of:

(100 * (10+1*10) / (10+1*0)) = 200 (total of 2000 to buy 10 units)

So, naturally this is unfair, and so the player would get the best price for purchasing one unit at a time.

And I don't want the player to have to do that, so I want to calculate the price one unit at a time.

This in itself is relatively easy, just loop through the units I want to purchase, and add it up.

Unfortunately, it doesn't exactly take care of the fractional units.

I might not have mentioned that you can own fractional units of commodities. You can.

Another thing to compound the issue is that the "currency" is simply another commodity, which can itself have supply, demand, supply factor, demand factor, sales, purchases, and so on.

So purchasing is a two step problem.

First, for a particular number of units of a commodity, determine the "value" of them in a way that ensure that buying and then immediately selling is a losing proposition.

Second, for a particular "value", determine the number of units that would need to be "sold" in order to make up that value.

Another wrinkle: it should not be advantageous to purchase fractional units. The price for buying half a unit, and then buying another half a unit should not be better or worse than buying one whole unit at one time.

share|improve this question
add comment

3 Answers

TokPhobia's answer contains the seed of a good idea, but the arithmetic average he recommends only gives the right answer if the price is a linear function of the amount of available units.

If the price is a non-linear function of availability, the correct price can instead be obtained by integrating the per-unit price from the amount available before the transaction to the amount available afterwards. Indeed, this is basically what your loop-and-add-up solution is doing, except that you're approximating the integral with a finite sum, which introduces some inaccuracy.

You could try to address the problem by using a better numerical integration method, but there's an easier solution: instead of trying to calculate the integral based on the spot price function, define the spot price in terms of the integral.

Specifically, start by defining a function P(x) which gives the total cost of buying the entire local supply of the product when that supply consists of x units (excluding seller profits, transaction costs, etc.). You can make that function look like anything you want, as long as it's monotone increasing. Typically, you'd also want to make sure it's concave, i.e. that the marginal cost of a single unit goes down as the amount of units available increases.

(In particular, note that, for all the calculations below, adding a constant value to P(x) doesn't actually change the results. Thus if, say, buying the last few units would be disproportionately expensive, it might be numerically more convenient to replace P(x) with the function Q(x) = P(x) - P(c), where c is e.g. the "typical" amount of the product available. Essentially, Q(x) then gives the cost/profit of bringing the local supply from x to c units.)

Then, if the current locally available amount of the product is x, and the player wants to buy y units, the total cost of the purchase should be P(x) - P(x-y) (times the seller's markup, plus any fixed transaction costs), while if they want to sell y units, they amount of money they should receive is P(x+y) - P(x) (minus markup and transaction costs again, of course; even virtual vendors have to eat, don't they?).

If you want to quote a per-unit spot price to your players, you can just approximate it with P(x) - P(x-1), i.e. the price of buying one unit of the product. I would, however, recommend that you also allow your virtual merchants to offer direct quotes for buying/selling y items, so that your players can know in advance how much they'd be paying.

Of course, the function P(x) can change over time, or between different locations; indeed, it should, if you want your players to have meaningful trading opportunities. Also, naturally, the local availability x should more or less gradually return to its "typical" value in the absence of player trading, to simulate the actions of unseen local traders.

share|improve this answer
add comment

When computing the price for the units that the player is trading, don't use the final number of units left after the transaction. Instead, use the arithmetic mean of the two quantities, before and after the transaction.

For example: if the player wants to purchase 1 unit out of 10 available units, use the price of the commodity as it would be at 9.5 units available. If the player instead wants to do two transactions of 0.5 units each, you'd first pay him at 9.75 price and then at 9.25 price, thus giving him the same amount of currency.

This should also solve the issue of buying, immediately selling and thus generating a profit, since in both instances you would sell for an average number of units, which would be equal in both instances. In our previous example the player would buy 1 unit out of 10 at the price of 9.5 units, then sell that unit back at the price of 9.5 units, therefore gaining just as much currency as he lost.

Another advantage to this approach is that you should no longer need that loop you mentioned.

share|improve this answer
    
Note that the arithmetic average is only right if the pricing is linear. For more details, see my answer. –  Ilmari Karonen Apr 27 '13 at 23:15
add comment

If you simply delay the price adjustment until a later time then any immediate "gaming the system" will be thwarted. You can argue that players will figure this out and still game the system for profit... but that's what trading is... gaming the system for profit.

In multi-player game usually the inherent market price is kept at a constant and low value to stabilize the economy and give a baseline "meager living wage" if no one live participates. Live players then set the real value via their trading strategies.

Since you don't have live players in this game and assuming that you want the markets to feel fluid then I suggest following what I described above, but substitute "AI traders" for the live players. Build a bunch of trading strategies and set them loose on the market, let the player go against their algorithms.

This obviously is not a direct answer to your original math question, if you're looking for that please follow @TokPhobia and try his answer.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.