Rails-18xx / Rails

Rails 18xx Java Application Main Repository
GNU General Public License v2.0
36 stars 22 forks source link

18VA: a 'minor' stop is not always minor #547

Open erik-vos opened 6 months ago

erik-vos commented 6 months ago

For quite some time I have been working on an issue with 18VA, that basically is caused by the overloading of the stop type 'minor' for giving certain train stops different properties than others.

It is currently used for at least three purposes:

  1. to create two different stop types to enable the use of n+m trains (e.g. 1835, 1837, 18Scan);
  2. to exclude certain stops from being counted against the train length (e.g. 18EU, 1841, SOH);
  3. to have certain trains (optionally or mandatory) ignore certain stop types (e.g. 1826 TGV, 1861).

In most games that overloading does not generate problems, but in 18VA it does. In 18VA, neither of the following two 'minor' stop types is counted, but

In the code, the variable ignoreMinors is used for both purposes 2 and 3. I could fix this in a dynamic modifier, but that isn't neat, and I decided to try a new approach in which that 'minor' overloading will be reduced or even eliminated.

In any case, the contents of the <Score> tag per train type will change. So far we have <Score towns="yes"|"no" cities="single"|"double" />. This will be replaced by defining score factors per stop and train type. For 18VA this would give:

The value "0" implies ignoring a stop, as is currently the case with towns="no". As "1" will be the default, attributes with that value may be omitted.

In addition I may need a new tag <Count> with a similar structure (and a default "yes" for all):

This all is still in the works. Success isn't guaranteed, as the infamous ignoreMinors permeates much of the route finding and revenue calculating algorithms, which I still do not completely understand.

erik-vos commented 5 months ago

The new <Score> and <Count> tags have been implemented in 18VA and now work fine. Until all games have been adapted, the old style configuration will keep working; there is a new (and temporary) game parameter HasNewStyleReachAndScoreAttributes that controls which style is used.

For future game development, the following aspects should be taken into account:

  1. The revenue calculation now gets all info about stop values, counting and ignoring via a new class StopValueCalculator. This class delivers the final stop values, except certain bonuses, when initialising NetworkVertex instances, after applying all factors that determine these values. Game-specific details should be added in a subclass (see StopValueCalculator_18VA). The values can depend on all three of stop type, count type (major/minor/no) and train type.
  2. Bonuses acquired via Special Properties are not (yet) included in these calculated stop values, these are still processed seprarately.
  3. The 'prediction' step in revenue calculation has for now been disabled; in my opinion it is no longer needed, as the NetworkVertex instances now get there final values per train type already at instantiation time. The reason for this change was, that in some cases route finding was terminated prematurely, delivering a sub-optimal income. However, it may prove necessary to reconsider this change, as I have already seen a case in an end game with two trains, where optimal route finding was rather slow.
  4. The "minor" count type value is now strictly reserved for handling n+m ("plus") trains, and should not be used in games that have no such trains. In games that have plus trains, the count type may vary per train type. For instance, in 18Scan towns are now "minor" for plus trains, but "major" for normal trains. So there is no longer such a thing as a fixed stop (or station) count type. Trains for which certain stops do not count against the train length should specify the new count type value "no".
  5. Ignoring stop types (i.e. neither counting nor taking revenue) is now defined by having a score factor value 0. Score factors should not be confused with city values. For instance, 1841 passes would be defined having a score factor 1 (so these will be counted), but a city value of 0 (gaining no revenue).

So far, only 18VA has been converted. I'm currently testing other games for correct processing of the old style configuration details. The regression test now runs perfectly.