News:

The Forum Rules and Guidelines
Our forum has Rules and Guidelines. Please, be kind and read them ;).

Mail revenue dropped to zero -- need to rewrite revenue code, advice requested

Started by neroden, June 13, 2013, 03:30:34 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

neroden

So, the mail base fare has rounded down after scale conversion (integer underflow) to a flat zero in the most recent version of pak128.britain.  (This is why mail is getting 0 revenue and also why it's not showing up in the goods list: the program thinks it's not a real good because it has zero revenue.)

I think the most clean way to fix this is to go through the revenue system from end to end and redo the math -- a lot of lurking problems can be cleaned up if we do this, anyway.

This requires some design decisions, however.  There are a couple of options:
(1) Internally record low-level revenues (per unit, per packet, per vehicle, with comfort &c modifications) in a smaller unit than the current storage unit, only rounding to cents on delivery (per-vehicle).  Perhaps 1/1000 of a cent, though for speed of computations I'd prefer 1/1024 of a cent.  There's already a multiplication and division by 3000 wandering around in the code, which we might then be able to clean up.
(2) Switch to using Bernd's portable floating-point type for the computations prior to "booking".  This eliminates the need to keep track of exactly what units we're using, as long as we're adding comparable units together (which we generally will be).  This could make the computations even cleaner.  But it could have subtle roundoff problems (though it does have 32 bits of precision, so it's unlikely to do so unless the alternative 32-bit computations would overflow, and even then the roundoffs will be in the final digit).  I favor this option because I believe it is more robust.

There's a third, less attractive option:
(3) Rescale all the values in pak128.britain, multiplying up by a factor of 10 or more.  However, the integer underflow may happen again with another pak if we do this.

(Edited for clarity)

jamespetts

Thank you for spotting this - this does indeed point to something somewhat fundamental (although no less in Standard than Experimental: it's just that in the Experimental version of the pakset that I changed the mail units/revenue).

I think that I provisionally favour no. 1, although it would be interesting to know how this would be done - presumably, no pakset alteration would be necessary? I favour this because, although Bernd's floating point class is portable, it is very slow when compared to native floating point types (let alone integers), and if it is worthwhile using 1024 instead of 1000 in native integers for a difference in speed, then it is definitely worth using native integers rather than a floating point class for the same reason (and it probably will be on large maps where lots of transactions are being booked every real time second).

May I ask for slightly more detail on what you had in mind for an implementation of no. 1?

Incidentally, as to the dividing by 3,000 thing that goes on - I am not sure that I follow it myself. It is very old from Standard (there was even a comment at some point, which might still be in the Standard codebase, from Prissi, I think, or one of the Standard developers at least, which inferred that he was not sure why it was like that either). As long as we can maintain the relative prices of Standard and existing Experimental paksets, this is probably the best way out of integer underflow issues.
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

neroden

Quote from: jamespetts on June 13, 2013, 09:36:44 PM
May I ask for slightly more detail on what you had in mind for an implementation of no. 1?
We pick a new unit, one much smaller than Sim-cents.  "Fares" adjusted for the scale_factor, and all revenue computations, are recorded in this new unit, right through the various computations related to comfort and speedbonus and so on, right up until the point where a convoy is unloaded (where the current division by 3000 is), at which point the numbers are converted into Sim-cents.  (The new unit could be anything but I would make it 2^x of this unit per Sim-cent, for some value of x, in order to make it easier for the chip to compute.)  This involves a lot of manual rewriting but should be pretty straightfoward.

jamespetts

I see - interesting. Do you mean to store all money values in this new type, or only base revenues? If the latter, there would have to be conversion at some point, which would involve division (or possibly bit shift). In a very large game, with many transactions per second, what sort of impact might this have on performance?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.

kierongreen

Bitshift conversions would have negligible performance impact (on some processor types they come free with other operations even).

neroden

Quote from: jamespetts on June 16, 2013, 11:12:39 AM
I see - interesting. Do you mean to store all money values in this new type, or only base revenues?
Revenues prior to booking.  The roundoff will be on unloading of vehicles. 


Payment per packet is usually very small -- meaning roundoff/underflow errors in the sppedbonus, comfort, etc. calculations --, while it adds up to something meaningful when a vehicle unloads.  When booking, it has to be registered with finance, which can end up with very very large numbers.

This is why unloading of convois is the correct point of conversion, probably.

jamespetts

Yes, I see. That seems to make sense - provided that the conversion is not too computationally expensive. Presumably you would convert the values of the goods on loading them from the pakset?
Download Simutrans-Extended.

Want to help with development? See here for things to do for coding, and here for information on how to make graphics/objects.

Follow Simutrans-Extended on Facebook.