So I've modified the cost function a bit:
1. Occupied track is weighed against the distance from the train:
This allows a train to look at how crowded a route is, and consider less crowded alternatives. The distance from the train is taken from the cost to reach a node. A weight is calculated upon that:
With x being the cost to reach this node, and high_limit, low_limit and max_weight as added 'npf_rail_occupied_*' variables.
Code: Select all
for x <= high_limit: w = max_weight
for x >= low_limit: w = 1.0
for high_limit < x < low_limit: linear interpolation between max_weight and 1.0
The initial values chosen for the variables are:
max_weight = 3
high_limit = 1000
low_limit = 5000
This means that till a distance of roughly 10 tiles the weight of 3 applies (i.e. triple the length of the occupied track may be chosen as alternative), and that after roughly 50 tiles no extra weight is given.
Note that these are very rough guesses, based on what seemed to work for me. The values may be heavily dependent on train speed (maybe the limits should be scaled with it?) and network layout, so feel free to play around.
2. Red presignal entries which are not the first encountered also get a penalty:
In general this allows custom tweaking of weights. An example may be crossovers on a double track, which should be very strongly discouraged if the destination track is occupied. The more red presignal entries, the more likely a suboptimal alternative is chosen, which in the example may be an alternative approach with tunnels/bridges.
The penalty can be changed with the 'npf_rail_red_entry_penalty' variable.
3. The higher firstred penalty now also applies to presignal entries:
In line with the 2nd change, so the direct choice for a red presignal entry is even more strongly discouraged.
Attached is a patch upon r4341 (I hope I did it right

Edit: updated attachments to use integer math and fixed the interpolation. Making the technical note useless

Technical note:
In the weight implementation I use a floating point variable, for which no unified type was available. While floats should be supported on pretty much every platform, their behaviour may not be the same and therefore may cause very rare desyncs in network games.
Also the config file doesn't support input of floats (as far as I could see), so the max_weight variable is limited to rounded numbers only.
Should floats be a major objection I guess the weight can be given in 1/10'ths or something.
Any thoughts?