News:

Want to praise Simutrans?
Your feedback is important for us ;D.

[Bug v3.4] Default Waiting Time and Zero Travelling Time

Started by knightly, May 05, 2009, 07:51:26 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

knightly

This has been reported before as well, but probably it has not been fixed yet.

(1) In the 1st attachment, 2 connexions show the default waiting time of 1min, which is obviously erroneous. The bus lines involved have been running for 2~3 years and it is impossible that the waiting times are as short as 1min.

(2) In the 1st attachment, 1 connexion has 0min travelling time. Although the travelling distance is relatively short (it is the next stop which is 10 tiles away), the travelling time involved should not be 0min or close to 0min. In the 2nd attachment, there is also a connexion with 0min travelling time -- that is ridiculous because when I manually checked the travelling time, it amounted to ~15days! And it was not updated even after 2 more round-trips. (This ship line travels between 2 cities only)

jamespetts

Knightly,

thank you very much for your reports. The zero travelling time is a bug that I have isolated, and will be fixed in the next release. The waiting times issue is far harder to isolate. In my testing, I cannot find anything particularly wrong with the code or the behaviour. I did discover, however, that the large number of instances of default waiting times were caused by the list of waiting times being empty: in other words, no waiting times for that destination from that origin had been recorded.

What might be causing it is this: waiting times are set when, and only when, cargo of the relevant type (passengers, mail, particular types of freight, etc.) board a form of transport at the stop, bound for the requisite destination. If no cargo has actually boarded there bound for that destination, then no waiting times will be set. What counts is the cargo's next transfer, not its ultimate destination. So, if an indirect route is faster than a direct route, the direct route will never be used, and cargo bound for that destination will not set the waiting time at that stop for the direct route. I have made one change, which will be in the next version, which might reduce the number of instances of default waiting times by preventing waiting times of zero being recorded at all, but this has not totally eliminated the problem. If you could see if you could find any issues in the code that might cause this, I should be most grateful - I am afraid that my search has drawn a blank so far!
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.

knightly

Thanks a lot for your efforts, James ;)

Quote from: jamespetts on May 07, 2009, 09:01:42 PM
If no cargo has actually boarded there bound for that destination, then no waiting times will be set. What counts is the cargo's next transfer, not its ultimate destination. So, if an indirect route is faster than a direct route, the direct route will never be used, and cargo bound for that destination will not set the waiting time at that stop for the direct route.

Regarding default waiting time issue, please kindly take a look at my save game again. In the Details Window of Lincoln City Hall Stop, there is an entry for Lincoln Cattle Yard Stop (which is located midway between Lincoln and Oxford) which shows that waiting time is 1min. The connection between these 2 stops is served by one single bus line only and the pax flow has been heavy. Given that this line has been running for years, it is really impossible that the waiting time is never updated with new records.

On the other hand, please also open the Details Window of Lincoln Cattle Yard Stop : the entry for Lincoln City Hall Stop shows a valid, non-default waiting time. If this entry is updated correctly, it's really strange that the corresponding entry at Lincoln City Hall Stop remains at its default value.

jamespetts

Hmm, this may well not be the issue in every case, then. However, I am really struggling to track down the cause, I am afraid...
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.

knightly

I have tried my best to track down the default waiting time problem but in vain.

The only thing I noticed is that, at least for the 2 cases which I investigated, the arrival time of ware_t object tmp (and hence neu) is exactly the same as welt->get_zeit_ms(), resulting in zero waiting time in hole_ab(). While it is not completely impossible that they are exactly the same, I suppose this is very unlikely to happen, right?

Probably you have already reviewed all the code related to arrival_time and waiting time calculation, and so have I. Thus, I am afraid that this problem is caused by some other code, and the bug may not be obvious to find.


knightly

James, I think I have finally found out why there is such default waiting time problem.

(1) Waiting times are calculated and recorded correctly in the appropriate place

I added some code in hole_ab(), vereinige_waren() and add_ware_to_halt() of haltestelle_t to output relevant data in calculating arrival_time and waiting_time. I sorted and filtered the output and checked for the suspicious cases, but found that they are actually correct.

Even for the cases where waiting time evaluates to zero, they are also correct -- they are just very rare cases where ware_t objects are unloaded/created and loaded in the same step. FYI, around 6.43% of those ~22000 entries generated from hole_ab fall in the range of 0 to 10 (in tenths of min of waiting time), so having waiting time < 10 does not signify any problem.

Since the data are correct, I would suggest removing the "waiting time unknown" message from halt details window to avoid confusion (since it is actually known), and display waiting time in XX.X format instead. As for setting waiting time to 10 when average waiting time is below 10, I would suggest you to try removing this adjustment first and see if you would like to add it back later, after applying the fixes below.


(2) Waiting time lists fail to be re-constructed correctly from save data during game loading

At first I thought that waiting times are not properly calculated and recorded, but as pointed above, this assumption was wrong.

The problem happens because, halts are reconstructed one by one during game loading. In your code related to saving waiting times, reachable halts are saved as coordinates (koord). When you load a halt koord from the save game (pls see below), you try to look up the halt in the map; if you fail to find a suitable halt at koord, you assume that the data is corrupted and discard all waiting time data -- no waiting time list will be constructed for that halt.



for(uint16 k = 0; k < halts_count; k ++)
{
koord halt_position;
halt_position.rdwr(file);
if(halt_position != koord::invalid)
{
halthandle_t current_halt = welt->lookup(halt_position)->get_halt();
if(!current_halt.is_bound())
{
// The halt was not properly saved,
// or was removed at some point.
uint8 waiting_time_count;
file->rdwr_byte(waiting_time_count, "");
for(uint8 j = 0; j < waiting_time_count; j ++)
{
uint16 current_time;
file->rdwr_short(current_time, "");
}
continue;
}
...



However, this creates a problem. Assuming that the map has 3 halts, A, B and C, which are served by a bus line. If A is the first one to be reconstructed from save data, A will not be able to rebuild the waiting time lists for B and C, simply because B and C do not exist on the map yet. After that, when B is reconstructed, it can only rebuild waiting time list for A, but not C, which again does not exist yet. And finally, C can rebuild waiting lists for both A and B upon reconstruction.


(3) base_pathing_counter is properly saved but never loaded from save game

Although waiting times are not loaded for some reachable halts, the lists should nevertheless be rebuilt over time. However, some waiting times are still shown as "unknown" after several months, which is perplexing.

I tried to output some data related to path and connexion staleness checks, and discovered that upon loading a save game, base_pathing_counter (which records the current game month counted from the 1st month at the start of a game) was only 5, while paths_timestamp[c] was 35 (which was correct given the game was tested for ~3 game years). Though seemingly trivial, this problem prevented connexions and paths from being rebuilt for many months (provided that the player didn't change halts or schedules and trigger welt->set_schedule_counter()).

The reason is that, in the following code from haltestelle::get_path_to(),


if(reschedule[category]
            || paths_timestamp[category] < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months()
            || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months()))
{
// If the paths hashtable is stale, clear it.
// This will mean that all the paths will need to be recalculated.
// Must always recalculate if the schedules change.
paths[category].clear();
search_complete = false;
}

destination_path = paths[category].get(goal);

if(!destination_path.next_transfer.is_bound() && !search_complete)
{
// The pathfinding is incomplete or stale - recalculate
// If the next transfer is not bound even though the search
// is complete, then there is no admissible path to the goal.
calculate_paths(goal, category);
destination_path = paths[category].get(goal);
}



If reschedule[c] is not set, the if condition above will remain false for many months and the stale paths will not be deleted. Even if connexions_timestamp < base_pathing_counter, since old paths are available, calculate_paths() will not be invoked, and connexions are thus not rebuilt, causing the same waiting time to be shown over months.

So what caused this problem? This variable is properly saved to the save game in karte_t::speichern(loadsave_t *file,bool silent). However, I found that this function is not invoked during game loading when I set a breakpoint inside it. Finally, I discovered that there is another function karte_t::laden(loadsave_t *file) which does the loading. Thus, karte_t is different from other classes, in that it has separate loading and saving functions, so adding the variable in the saving function alone is not enough -- you have to add counterpart code in the loading function.

jamespetts

#6
Goodness - that must have taken some effort! Thank you very much indeed - that is extremely helpful. I will have a look at this in detail to-night, and see if I can get these problems fixed by the next release. The solution to the loading issue might have to be to use a hashtable of "koord"s rather than halthandles for the waiting times.

Edit: I have now looked into this, and made the suggested changes. The waiting times are now far more populated on loading a saved game than they were, which is looking most promising! As ever, these suggestions are very helpful.

One thing that I have not done, however, is remove the "waiting time unknown", or remove the default minimum waiting time. The reason to have a default minimum waiting time of one minute is to simulate the fact that, however efficient that the transport network itself is, it still takes time and trouble to change from one transport to another: one minute was chosen as a reasonable approximation of this time. One minute being 10/10ths of a minute, the number 9 can then be used to show definitively when the waiting time is unknown: the number 9 will never be returned where the waiting time is known, since it has an automatic minimum of 10. "Waiting time unknown" is still a useful designation, as there will always be a time before the data are acquired, either shortly after adding a new stop or line, or amending an existing line or schedule, or after loading a game saved with Simutrans-Standard.
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.