Jump to content

Trader prices (avg, var)


Bumber

Recommended Posts

I'm trying to figure out how traders calculate their min and max prices for goods, but I'm stumped by an inconsistency.

Here are some trades from an agriculture trader:

Sells:
honeycomb        | avg=1, var=0.25 | calculated range 0.75 to 1.25 | actual price 1
2x beeswax       | avg=2, var=0.5  | calculated range 1.5 to 2.5   | actual price 2
2x cabbage seeds | avg=6, var=1.5  | calculated range 4.5 to 7.5   | actual price 4 to 8

Buys:
woolen shirt      | avg=6, var=1.5  | calculated range 4.5 to 7.5   | actual price 4 to 8
aged wooden crate | avg=3, var=0.75 | calculated range 2.25 to 3.75 | actual price 2 to 4

I got the actual prices from the Extra Info mod handbook, but it seems to line up with the in-game result.

As you can see, the first two seem to result in a single value rather than a range, while the rest have a price range that is rounded down/up for the min/max. Honeycomb not rounding down to 0 is understandable, and 1.25 not rounding up to 2 makes sense if it's consistent everywhere, but why doesn't beeswax result in a price range of 1 to 3 instead of just 2?

Edited by Bumber
Link to comment
Share on other sites

3 hours ago, Bumber said:

why doesn't beeswax result in a price range of 1 to 3 instead of just 2?

How do you know it doesn't?

As in, how do you know the trader only ever offers it at a price of 2? You said you got that info from a mod, but how do you know the mod is correct? Did you visit traders ingame to verify all possible prices? If so, how many, and across how many inventory refreshs?

Honestly, your best bet here is to approach the author of Extra Info and ask them where they got their numbers from. Worst case, you'll be told "I've never seen it anything other than 2, so I wrote that in", but that would surprise me. For more likely is you receiving a tale of code-diving and stumbling over fun little idiosyncracies in Vintage Story's engine, because that's often how modding goes. Everything you want to implement sounds really straightforward, until you go and look up how the game handles such things in other places... ;)

Link to comment
Share on other sites

Checked the mod's source code and found this:

public static int GetMin(NatFloat natFloat) => (int)Math.Max(1, Math.Round(natFloat.avg - natFloat.var));
public static int GetMax(NatFloat natFloat) => (int)Math.Max(1, Math.Round(natFloat.avg + natFloat.var));

Which lines up with https://github.com/anegostudios/vssurvivalmod/blob/master/Systems/Trading/TradeItem.cs:

Price = (int)Math.Max(1, Math.Round(Price.nextFloat(1f, world.Rand))),

And https://github.com/anegostudios/vsapi/blob/master/Math/NatFloat.cs:

rnd = (float)rand.NextDouble() - 0.5f;
return offset + multiplier * (avg + rnd * 2 * var);

Documentation for Math.Round: https://learn.microsoft.com/en-us/dotnet/api/system.math.round?view=net-7.0#system-math-round(system-double)

Turns out the "why" is "floating point issues". The price range is dependent upon the floating point representation of the result.

Given this, there might only be a 1 in 2^23 (or 1:8388608 or 0.000012%) chance of getting the min/max value.

Edited by Bumber
Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.