There is an even stranger division later on. The formula you presented is not the whole thing.

Possibly, although the results seemed pretty accurate. Lets enlighten ourselves about how the algorithm works together just to be sure.

For this demonstration let us assume pak64 coal. We all love coal and it makes far too much money.

Let us look at how coal is declared. It uses the name "Kohle" because it must have been declared when Simutrans was still using German as its main language.

obj=good

name=Kohle

MapColor=128

metric=tonnen

catg=2

value=210

speed_bonus=2

weight_per_unit=1000

This translates into the following in game in the goods list when shipped at speedbonus speed (0% setting).

Revenue: 0.70

% Bonus: = 2%

Weight: 1000kg

One can immediately notice something is strange with this. Although the percent bonus and weight translates directly in game, the "value" does not. This means there is some value scaling going on. Let us work this constant out just for piece of mind.

`(Revenue) * x = (value)`

0.70 * x = 210

x = 210 / 0.70

x = 300

So if we divide value by 300 we should be getting the in game value. A quick test with Passengers and Mail shows this to be the case.

The scaling is done with...

`waren[i]->value = (uint16)((long_base_value*multiplier)/1000l);`

Where multiplier is usually defined as 1000, with exception of if beginner mode is used. This means that the value is the same as provided in the pakset at this stage, which is 300 times bigger than the final value.

The calculation starts with...

` const sint32 kmh_base = (100 * speedkmh) / ref_kmh - 100;`

The multiply by 100 here is clearly some scaling factor. Without it the integer division will produce nonsense results. Why 100 was chosen instead of some binary value (which should be faster) is unclear and probably down to not knowing about fixed point numbers in computers.

Given a case of 0 speed, speedbonus speed and 2 * speedbonus speed we get the following out...

0 : -100 -> -1

1 : 0 -> 0

2 : 100 -> 1

Next the following is used...

`const sint32 grundwert_bonus = 1000+kmh_base*besch->get_speed_bonus(); // speed bonus factor`

We now multiply the previous value by speed bonus.

0 : -200 -> -2

1 : 0 -> 0

2 : 200 -> 2

It is then added to 1000. This clearly represents the logical value of 1 since we are adding a bonus to a multiplier. Since our previous ones used a scaling of 100, their logical values can be divided by

10 when viewed like this (where the magic 10 constant comes from).

0 : 800 -> 0.8

1 : 1000 -> 1.0

2 : 1200 -> 1.2

Next up...

`return besch->get_preis() * (grundwert128 > grundwert_bonus ? grundwert128 : grundwert_bonus);`

Firstly this clamps the previous result to a minimum. This minimum comes from game settings so can be largely ignored.

Here it is for people to see...

# lowest possible income with speedbonus (1000=1) default 125

bonus_basefactor = 125

So applying the clamp gives us...

0 : 800 -> 0.8

1 : 1000 -> 1.0

2 : 1200 -> 1.2

It only affects cargo with a % bonus larger than 10 it seems...

Ok now to multiply by coal to get the currency. I am writing the actual currency output for clarity.

0 : 168000 -> 0.56

1 : 210000 -> 0.70

2 : 252000 -> 0.84

This value is then used by convoys to work out revenue for all their cargo.

` // calculate freight revenue incl. speed-bonus`

if (ware.get_besch() != last_freight) {

freight_revenue = ware_t::calc_revenue(ware.get_besch(), get_besch()->get_waytype(), cnv_kmh);

last_freight = ware.get_besch();

}

const sint64 price = freight_revenue * (sint64)dist * (sint64)ware.menge;

// sum up new price

value += price;

Then finally it is transformed into something else...

` // Hajo: Rounded value, in cents`

return (value+1500ll)/3000ll;

Pushing our values through this

0 : 56 -> 0.56

1 : 70 -> 0.70

2 : 84 -> 0.84

Behold, the value out is simucents! So the value declared in files is in 1/3 simucent units. On top of this the revenue is computed with an extra 1000 scaling for computational accuracy.

Why something like Q.10 was not used and why cargo values are in 1/3 of a simucent I do not know.

As such speed bonus currently is defined as the % increase in revenue for a 10% increase in average maximum speed realitive to speedbonus speed.