Page 1 of 1

Cargo packet change suggestion

Posted: 23 Dec 2011 03:30
by Expresso
Something which has puzzled me for a while now, is that the game keeps track of how long a particular cargo packet is in transit in the number of days.

A better solution would be to keep track of the date a particular packet was created and the number of days spent at stations (this requires keeping track of the date the cargo packet is dropped off at a station). However, this does add 8 bytes to the cargopacket class.

If this gets implemented, only perishables need to be processed when in a vehicle, potentially increasing performance a bit. Days in transit then becomes a simple computation formulate:

(current date - generation date) - days at stations = days in transit.

As for the year cheat, a simple calculation could fix that (subtract/add x years and you are done).

EDIT: after posting this, it occurred that instead of storing the date, the game could instead store the tick information. That way you don't get all kinds of ugliness to deal with day length patches.

NOTE: I posted this here, because this isn't a suggestion for a new feature and purely deals with how stuff works internally, thus I felt the suggestions forum to be inappropriate for this post.

Re: Cargo packet change suggestion

Posted: 23 Dec 2011 08:11
by FooBar
Expresso wrote:(this requires keeping track of the date the cargo packet is dropped off at a station)
You would need way more than 8 bytes for that.

Imagine a cargo packet transferred a million times (unrealistic, but it's possible to do so). Then you'd need to store a million "arrived at station" timestamps.

Re: Cargo packet change suggestion

Posted: 23 Dec 2011 08:33
by Terkhen
Cargopackets are one of the intensive entities in both memory and CPU processing time. Things get worse with a destination/distribution implementation. Even 8 extra bytes per cargopacket is quite a lot already.

Re: Cargo packet change suggestion

Posted: 23 Dec 2011 09:32
by Arie-
If I understand this suggestion correctly it will reduce CPU requirements and increase the memory footprint of a game?

Re: Cargo packet change suggestion

Posted: 23 Dec 2011 09:36
by Expresso
FooBar wrote:
Expresso wrote:(this requires keeping track of the date the cargo packet is dropped off at a station)
You would need way more than 8 bytes for that.

Imagine a cargo packet transferred a million times (unrealistic, but it's possible to do so). Then you'd need to store a million "arrived at station" timestamps.
No, the "stored at station" time stamp is needed only once per station. If a vehicle comes to pick up the cargo packet, you can compute the number of days the cargo packet has been waiting at the station and simply add to the "waited at station" counter. That counter would need to be large enough in order to accommodate the result of a million transfers, though. :) This way you can recycle the "stored at station" counter.
Terkhen wrote:Cargopackets are one of the intensive entities in both memory and CPU processing time. Things get worse with a destination/distribution implementation. Even 8 extra bytes per cargopacket is quite a lot already.
Yes, well. In that case the space currently being used by the two tileindexes already stored in a cargopacket (they can be figured out) could be used for this instead. Loaded_at_xy could then become Loaded_at_station (making it 2 or 3 bytes (to accomodate FooBar's million transfers)). The increase at this point comes down to two or three bytes.

EDIT: The whole point of this suggestion is in order to reduce CPU consumption of cargo packets. What's the point of visiting a cargo packet just to increase a counter when that counter can be avoided in the first place?

Re: Cargo packet change suggestion

Posted: 23 Dec 2011 09:43
by Yexo
Arie- wrote:If I understand this suggestion correctly it will reduce CPU requirements and increase the memory footprint of a game?
It'll definitely increase memory usage. Whether it actually reduces CPU usage has to be measured.
Expresso wrote:
Terkhen wrote:Cargopackets are one of the intensive entities in both memory and CPU processing time. Things get worse with a destination/distribution implementation. Even 8 extra bytes per cargopacket is quite a lot already.
Yes, well. In that case the space currently being used by the two tileindexes already stored in a cargopacket (they can be figured out) could be used for this instead. Loaded_at_xy could then become Loaded_at_station (making it 2 or 3 bytes (to accomodate FooBar's million transfers)). The increase at this point comes down to two or three bytes.
The tile can't be figured out in case the original station gets removed, that's the reason we have that variable.
EDIT: The whole point of this suggestion is in order to reduce CPU consumption of cargo packets. What's the point of visiting a cargo packet just to increase a counter when that counter can be avoided in the first place?
And it might work, or it might not work. But it requires proper testing to show that is actually has a positive effect. More memory usage might result in more cache misses which might result in more slowdowns than you win by reducing the amount of work. Again, all speculation, it needs to be coded and tested.

Re: Cargo packet change suggestion

Posted: 23 Dec 2011 15:21
by Rubidium
Another caveat of storing the actual creation and arrival dates is that more packets are generated. At the moment packets are coalesced when their origin and days in transit is the same, so if you transport wood from an industry to a "feeder" station, then all wood cargo would be stored in a single packet at the feeder station since the days in transit is the same. This means that cargo can be moved around with less cargo packets.

Adding more data to cargo packets means that there is more difference, thus more cargo packets and less use for coalescing; possibly even to the point that coalescing makes no sense and you would have a single cargo packet for a single unit of cargo instead of one cargo packet for all cargo in the vehicle. That ofcourse means that you need to iterate over much more cargo packets when (un)loading.

So it isn't "simply" adding some extra bytes to the cargo packets to remove some other loop, you are also increasing the size of the loops that you aren't going to remove. Then ofcourse you should not break the NewGRF feature regarding cargo aging.

Re: Cargo packet change suggestion

Posted: 16 Jan 2012 05:49
by Creat
Also possibly problematic might be date cheats, most notably setting the time back a significant amount. Not a primary concern of course :)

Re: Cargo packet change suggestion

Posted: 16 Jan 2012 06:57
by fonso
Rubidium wrote:Another caveat of storing the actual creation and arrival dates is that more packets are generated. At the moment packets are coalesced when their origin and days in transit is the same, so if you transport wood from an industry to a "feeder" station, then all wood cargo would be stored in a single packet at the feeder station since the days in transit is the same. This means that cargo can be moved around with less cargo packets.

Adding more data to cargo packets means that there is more difference, thus more cargo packets and less use for coalescing; possibly even to the point that coalescing makes no sense and you would have a single cargo packet for a single unit of cargo instead of one cargo packet for all cargo in the vehicle. That ofcourse means that you need to iterate over much more cargo packets when (un)loading.

So it isn't "simply" adding some extra bytes to the cargo packets to remove some other loop, you are also increasing the size of the loops that you aren't going to remove. Then ofcourse you should not break the NewGRF feature regarding cargo aging.
If you store "date_created", "days_in_stations" and "date_current_station" instead of "days_in_transit" you can trivially determine the value for "days_in_transit" from the stored data and merge packets if they are equal in that. date_current_station would be set to current_date once a vehicle enters a station, days_in_stations would be incremented with "current_date - date_current_station" when the vehicle leaves a station. At that point date_current_station would have to be set to some INVALID_DATE value (or maybe we can figure out the "in station" state somehow else). The formula for days_in_transit would be (in pseudo code):

Code: Select all

days_in_transit = ((date_current_station == INVALID_DATE ? current_date : date_current_station) - date_created) - days_in_stations
Like this you can keep the coalescing behavior without incrementing a counter for each packet every day.

Re: Cargo packet change suggestion

Posted: 16 Jan 2012 07:15
by Eddi
you'll need to fiddle the cargo aging modificator in there, for each transfer leg

Re: Cargo packet change suggestion

Posted: 20 Jan 2012 13:17
by Tafidis
Having advocated a "timestamp" system before myself, I would like to add on this a bit.

I think it only makes sense if cargo actually does age at stations (this has also been suggested), in which case the formula is simplified significantly. You only need load and unload dates to calculate payments.

W.r.t to feeder systems:
fonso wrote: Code:
days_in_transit = ((date_current_station == INVALID_DATE ? current_date : date_current_station) - date_created) - days_in_stations
Eddi wrote: you'll need to fiddle the cargo aging modificator in there, for each transfer leg
This is the most difficult to do, days_in_transit counter is the easiest way to penalize/reward both the individual leg as well as the entire route without going into heavy calculations. Otherwise, you need to keep some info on each leg until the end or modify some of the variables (such as date_created and/or feeder_share) to reflect on different aging behaviour "so far".

w.r.t daylength patches:
Expresso wrote:after posting this, it occurred that instead of storing the date, the game could instead store the tick information. That way you don't get all kinds of ugliness to deal with day length patches.
I believe the contrary, a timestamp system would be paving the way for a consistent daylength patch, i.e. not having to consider "how many ticks in a day" and all that. [In fact i believe Pavel's daylength patch does not work like that at all. It just skips increasing the tick counter a set amount of times.]

So, a timestamp system has its pros and cons, which cannot be found out until such a system has been developed and tested. I would like to help in doing this, but do not have the time, unfortunately.

Re: Cargo packet change suggestion

Posted: 20 Jan 2012 13:27
by planetmaker
Tafidis wrote:I think it only makes sense if cargo actually does age at stations(...)
I have to disagree quite thoroughly. For once the cargo aging is a nice means to differenciate between slow and fast vehicles. And for second it's nice means to differenciate between comfort (slower aging) and economy class (normal or faster aging) vehicles. Removing these two elements from cargo income calculations would basically make sure that all cargo pays the same per tile, irrespective of the mode and duration of transport.

Re: Cargo packet change suggestion

Posted: 21 Jan 2012 10:19
by fonso
Well, alternately one could also save days_in_transit and a date_last_loaded (if that isn't even there already). Then you only have to update days_in_transit when unloading some cargo. At that point you know the vehicle you're unloading from, the date you loaded the cargo and the date when you're unloading the cargo so it's easy to calculate the increment for days_in_transit. Merging packets would be slightly more complicated. You'd have to "update" the date_last_loaded of the packet to be merged with to the current date and then compare days_in_transit. It's no rocket science, though.

Re: Cargo packet change suggestion

Posted: 22 Jan 2012 11:37
by Tafidis
@planetmaker:

Er, aging the cargo while waiting at stations does not remove the behaviour you describe. You still make more if you transfer the cargo faster and/or with containers in which cargo is aging slower. But it also adds complexity in that perhaps you can add facilities to the station (non-track tiles) that modify the aging factor at the station itself. Right now you can transfer from primary industries to intermediate stations in which cargo can wait very long before starting to decay in quantity and still get almost the same payment as you would for a direct transport. But all this is off-topic in this thread.

I think that, for the current game behaviour, the days_in_transit counter is the simplest implementation, or so my limited coding knowledge suggests.