News:

Simutrans.com Portal
Our Simutrans site. You can find everything about Simutrans from here.

Industry consumption query

Started by jamespetts, January 18, 2014, 08:57:24 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jamespetts

Probably a silly question, but it is not immediately obvious from reading the code: where can one find a variable/getter in the fabrik_t class representing the monthly maximum consumption of one particular type of input goods in any given industry?

Edit: My investigations into this have dug up some very weird behaviour, and I am not sure whether this is confined to Experimental or not: a market consumes fruit, vegetables, meat and fish in proportions 100%, 100%, 33%, 200%. It is connected to a single arable farm in a test game, which produces vegetables far faster than the market can consume them (I set up the test game to test the max_intransit_percentage adjustment feature that I am writing).

Production is nominally 16 units per month. The industry is not connected to electricity. When I run the game fast forwarded and it is connected to the arable farm, consumption of vegetables is 41/month (as shown on the "goods needed" graph). When run for a month without fast forwarding, consumption is only 20/month. A diary, meanwhile, with a nominal consumption of 800/month consumed exactly that in a very similar test when connected to two cattle farms with sufficient transport to meet its need more than sufficiently.

Also, I examined the code and deduced that this was the relevant code determining industry consumption rates:


if(  ausgang.empty()  ) {
            // consumer only ...
            if(  besch->is_electricity_producer()  ) {
                // power station => start with no production
                power = 0;
            }

            // finally consume stock
            for(  uint32 index = 0;  index < eingang.get_count();  index++  ) {
                if(!besch->get_lieferant(index))
                {
                    continue;
                }
                const uint32 vb = besch->get_lieferant(index)->get_verbrauch();
                const uint32 v = max(1,(menge*vb) >>;

                if(  (uint32)eingang[index].menge > v + 1  ) {
                    eingang[index].menge -= v;
                    eingang[index].book_stat(v, FAB_GOODS_CONSUMED);
                    currently_producing = true;
                    if(  besch->is_electricity_producer()  ) {
                        // power station => produce power
                        power += (uint32)( ((sint64)scaled_electric_amount * (sint64)(DEFAULT_PRODUCTION_FACTOR + prodfactor_pax + prodfactor_mail)) >> DEFAULT_PRODUCTION_FACTOR_BITS );
                    }
                    // to find out, if storage changed
                    delta_menge += v;
                }


In theory, therefore, the following code should produce the correct number:


const uint64 max_prod = (uint64)prodbase * (uint64)(get_prodfactor());
    const uint64 menge_prod = (max_prod >> (18-10+DEFAULT_PRODUCTION_FACTOR_BITS-fabrik_t::precision_bits)) * welt->ticks_per_world_month + (uint64)menge_remainder;
    const uint32 menge = (uint32)(menge_prod / (uint64)PRODUCTION_DELTA_T);
    const uint32 vb = besch->get_lieferant(index)->get_verbrauch();
    const uint32 v = max(1,(menge*vb) >>;
    const uint32 TEST = convert_goods(v);


("TEST" should be the same as shown in the "goods needed" graph). However, this produces the figure of 16, which is the same as would be produced by the much simpler:


(get_current_production() * besch->get_lieferant(index)->get_verbrauch()) >> 8;


This looks to me like a rounding error somewhere. Would changing "fabrik_t::precision_bits" to a higher number assist, or would doing so cause overflows somewhere?
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.

prissi

Part of the problem is how often step() is called. When bits per month were introduced, I set this so the pa128 open pit mine did not overflow until setting of 23 (if memory serves me right, that was a little ago already).

jamespetts

Interesting - thank you. Does that mean that industries whose monthly production is less than 23 are likely to see this problem?
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.

prissi

No, this would be an underflow. For this I tested until bit per month 16. But I only tested the standard paks, so a risk of underflow might still exist. Best to add some debug logging and see for yourself.

Although with bits per month = 20, you should only get productions which are divideable by four.