News:

Simutrans Tools
Know our tools that can help you to create add-ons, install and customize Simutrans.

More realistic convoy loading & passenger behavior

Started by Borgoth, July 23, 2009, 08:32:40 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Borgoth

New poster, old player (well, couple years). I've been spending my holiday with Simutrans (102, pak64 and pak128) and while my preference may be different to others, I wish for more realism on some things where it can be achieved with little effort. I'm coder myself so I should have reasonably good idea on the amount or work needed, and gotta admit I'm slightly tempted at coding them myself. But let's see what people think first.


#1 More realistic convoy loading. I'm well aware that this has popped up before on forums and I chose to write a clarified new thread rather than necroing an old one.

Current behavior: Load nearest first. In route A->B->C->D, at A we first load everything that's heading for B, then if there's more room, everything for C and so on. Works fine on most cases and thread http://forum.simutrans.com/index.php?topic=886.0 has had lengthy discussion about it, including the suggestion of what is in my opinion both by far most realistic and also best for gameplay point of view. That thread was about a different suggestion (bad one imo) so here's the correct one in its very own thread hoping for a response.

Preferred behavior: Load even portion to each destination. In route A->B->C->D, at A we load some for B, C and D. How much? Put into a formula: amount heading to B loaded = B / (B+C+D) * convoy capacity.

Example: Train fits 350 passengers. Station A has 1100 passengers waiting, 400 to B, 200 to C and 500 to D.
B / (B+C+D) * convoy capacity = 400 / 1100 * 350 = 127
C / (B+C+D) * convoy capacity = 64
D / (B+C+D) * convoy capacity = 159
Total loaded: 127 passengers heading to B, 64 passengers heading to C and 159 passengers heading to D.
As a comparison, current loading system would pick up 350 passengers to B, 0 to C and 0 to D.

Since I did mention realism, how does this fit into that? In reality, you'd either sell seats to your train beforehand and thus load train with FIFO, or people would just rush into the arriving train randomly. FIFO takes too much resources to keep up in the game so it's obviously out, but assuming even speed of passenger generation between given B, C and D, the first 350 people in that FIFO list would be very close 127 to B, 64 to C and 159 to D, just like the suggested method produces. Considering the case of 1100 people rushing into the train and lucky 350 getting in, we'd still end up with 127 to B, 64 to C and 159 to D.

Now, implementation for even balance is easy and couple multiplications & divisions isn't too heavy. Certainly nothing like FIFO would be, and since people have already agreed FIFO would give best results but it's out of the question because of memory usage, I don't really see any reason not to use the suggested method that creates same end result as FIFO without the massive memory cost.

Problems: Express train A->D. With current implementation passengers heading to D are ignored by the A->B->C->D train most of the time so express train straight to D has plenty to pick. With even load such express train wouldn't work as well (it still would to some extent since likely A->D has lots of passengers to pick from). Now, people going for slower local train instead of the faster express train can be explained with two things: 1) they might still get to D earlier with local train than express, if express isn't due for a while, or 2) they're just too stupid to choose what's better for them (this IS a problem and should be fixed). Either way, loading to all destinations equally isn't breaking express trains: they're already broken, current 'nearest first' loading system just happens to band-aid express trains to being somewhat viable. But as I said, problem is elsewhere and belongs to another thread.

Possible problems with implementation: Considering division is used, the shares for each destination aren't integers but need to be rounded. As a result, in given example it's not guaranteed that shares of B, C and D end up with total of 350 due to rounding errors. Flooring the values and filling the possible last empty spot in convoy with whatever passengers would probably work fine, but it'd be annoyingly messy code. Instead, I'd consider this:

Example: convoy with room for 130 passengers, divided among 3 destinations with previous formula gives values
rB = 33.333, rC = 43.333, rD = 53.333
Flooring or rounding will both end up with 129 passengers, roofing would go to 132. Both bad. So, instead:

B = round(rB) = 33
C = round(rB+rC) - B = round(76.666) - 33 = 44
D = round(rB+rC+rD) - B - C = round(129.999) - 33 - 44 = 53

End result 130 sharp. In pseudo,
double rsum=0.0; 
int isum=0;
foreach (next, destinations) {
    rsum += next.rval;
    next.ival = round(rsum) - isum;
    isum += next.ival;
}

jamespetts

Very interesting thinking! Have you looked at Simutrans-Experimental? It does not (yet) have any new system for determining the order in which passengers and goods are loaded, but it does have a system for determining which line/convoy that passengers should board based on a reasonable estimate of what is likely to get them to their destination more quickly.

If you are into coding, have a look at the Simutrans-Experimental Github repository here. Some of the code is in German, I am afraid, but the newer code is in English. I find Google translator (or Babelfish or any of the others) useful for deciphering the German portions.

Welcome to the forum, incidentally!
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.

Borgoth

I haven't had time to actually play ST-Exp yet, just read through your fine description of all the changes you have made. The passenger routing system you've come up with sounds complex and realistic so I'm definitely looking forward to have a go at it (just can't let go of my new cities just yet (pak128, 192x192, 15 towns, 16000->64000 in 11 years and growing fast, experiencing the nasty factory spamming). On topic of passenger routing, take a look at the other 2 threads I posted. I think they still have some stuff that might enhance the system you've already done.

I might actually have a look at the code sometime. Would want to confirm my long-living suspicion that city AI can't build anything next to my bus/mail stops, and my fear that this might extend to tram rails as well...

Fabio

Hi Borgoth, your proposed system looks VERY interesting!

gerw

Imho, as long as goods are routed via number of transfers, we shouldn't change the behaviour of loading nearest first. Otherwise the express trains become even more broken (as you mentioned in your first post)...

What could be changed: What goods to the next halts are loaded. Currently some random goods are taken, but they aren't evenly distributed.

Severous

I like this idea. 

Its not unusual for a train to be loaded with passengers all going to the same place..and when it gets there not enough new passengers to fill it.  Had it previously loaded more variety of passengers it would be more likely to find enough new passengers as it proceeded along the stops of its line.
Regards
Sev.

Borgoth

Makes me wonder if goods getting routed based on number of stations/stops would just be better. That'd fix express trains and shouldn't be more heavy to calculate. Bit too big change to request for. I'll try it one day if I have time to dig up the code. Or has someone tried it already and failed miserably?

prissi

I would appreciate such system. I started this a long time ago, but there are lots of routines to change andmy try was much slower. I think gerw did this also, or at least he implemented A* route search (which was unfourtunately 50% of the current speed, and this is the most time-consuming routine in well developed games).