News:

SimuTranslator
Make Simutrans speak your language.

Schedule features: technical discussion

Started by jamespetts, January 22, 2018, 11:15:36 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

freddyhayward

I have spent a short time working on an alternative implementation design for layovers. I believe that this design is simpler than the current planned design, and I have attempted to ensure that it retains that design's core goals.

Staffing costs for ALL convoys are charged per unit of time as follows:
   * at the end of each month while driving, AND at arrival at ALL stops, the smallest of:
      - the time since the convoy's last departure OR
      - the time since the start of this month
   * at the end of each month at stops WITHOUT layover facilities AND at departure from stops WITHOUT layover facilities, the smallest of:
      - the time since the convoy's arrival at this stop OR
      - the time since the start of this month
   * at departure from stops WITH layover facilities, the smallest of:
      - the time since the convoy's arrival at this stop OR
      - the convoy's layover time threshold determined by any number of factors, potentially including game settings, pakset-specified values, default values, time spent loading, etc...

Design Implications:
   * There is no layover state for convoys
   * There is no layover setting for schedule entries
   * Staffing costs during layovers are zero

Potential issues and responses for this design:
   * Players would not have control over when the convoys enter and exit layover in this system:
      - Players would always receive the greatest possible cost savings for minimal effort in this system.
   * Staffing costs should be reduced or potentially reduced rather than zero, therefore this system saves players too much:
      - Players would still have to pay for the maintenance costs of layover facilities.
      - Additionally, this system could be modified to include reduced costs quite easily.
   * Players would not be able to check whether a convoy is in a layover state in this system:
      - Players should associate long waiting times with staffing cost savings in general, and therefore assume that any convoy waiting for long periods of time is probably in a layover state.
   * Layovers should not be in effect while vehicles have cargo onboard, therefore this system saves players more than they should and/or is unrealistic:
      - This system could be easily modified to apply regular non-layover charges while the convoy has cargo onboard. This could be coupled with 'unload all' and 'no load' schedule entry flags which would be very useful in their own right.
      - Additionally, a convoy's layover time threshold could be altered as part of its calculation when being charged to include the implicit costs of managing the cargo during the layover, generalising loading, unloading, storage, etc.

jamespetts

Quote from: freddyhayward on December 26, 2020, 12:43:22 AM
I have spent a short time working on an alternative implementation design for layovers. I believe that this design is simpler than the current planned design, and I have attempted to ensure that it retains that design's core goals.

Staffing costs for ALL convoys are charged per unit of time as follows:
   * at the end of each month while driving, AND at arrival at ALL stops, the smallest of:
      - the time since the convoy's last departure OR
      - the time since the start of this month
   * at the end of each month at stops WITHOUT layover facilities AND at departure from stops WITHOUT layover facilities, the smallest of:
      - the time since the convoy's arrival at this stop OR
      - the time since the start of this month
   * at departure from stops WITH layover facilities, the smallest of:
      - the time since the convoy's arrival at this stop OR
      - the convoy's layover time threshold determined by any number of factors, potentially including game settings, pakset-specified values, default values, time spent loading, etc...

Design Implications:
   * There is no layover state for convoys
   * There is no layover setting for schedule entries
   * Staffing costs during layovers are zero

Potential issues and responses for this design:
   * Players would not have control over when the convoys enter and exit layover in this system:
      - Players would always receive the greatest possible cost savings for minimal effort in this system.
   * Staffing costs should be reduced or potentially reduced rather than zero, therefore this system saves players too much:
      - Players would still have to pay for the maintenance costs of layover facilities.
      - Additionally, this system could be modified to include reduced costs quite easily.
   * Players would not be able to check whether a convoy is in a layover state in this system:
      - Players should associate long waiting times with staffing cost savings in general, and therefore assume that any convoy waiting for long periods of time is probably in a layover state.
   * Layovers should not be in effect while vehicles have cargo onboard, therefore this system saves players more than they should and/or is unrealistic:
      - This system could be easily modified to apply regular non-layover charges while the convoy has cargo onboard. This could be coupled with 'unload all' and 'no load' schedule entry flags which would be very useful in their own right.
      - Additionally, a convoy's layover time threshold could be altered as part of its calculation when being charged to include the implicit costs of managing the cargo during the layover, generalising loading, unloading, storage, etc.


Thank you for your detailed suggestions: this is very helpful. If I understand correctly, what you suggest is a sort of implicit layover. This is an interesting idea, but one possible problem relates to rounding errors for convoys that have low fixed costs and stop regularly.

Imagine, for example, a minibus that stops 10 times per game month and with a fixed cost of 1.29c. At each of its stops (assuming even spacing), it would charge a fixed cost of 1.29c / 10, which would, in integer arithmetic, produce 0.12c. 0.12c * 10 = 1.20c, reducing the fixed cost by 0.09c/month compared to an otherwise identical convoy with only 1 stop per game month. With 100 stops, the cost would potentially be truncated further to 1.00c.

We may also want to consider whether we need the concept of "layover facilities" and, if so, how to interpret it; do we need different facilities for different types of convoys (consider an airport with an associated 'bus stop, for example; layover facilities for the 'buses should not, if layover facilities are a thing at all, necessarily mean layover facilities for the aircraft, too). What exactly did you intend "layover facilities" to simulate?

Edit: One more significant issue occurs to me: the path explorer. One of the specifications for the layover feature is that the path explorer should not route passenger/mail/goods past a layover point. This is, I think, the reason that it was considered necessary explicitly to state the layover in the first place: the path explorer needs to know where layovers will occur at the time that it runs in order to determine whether to treat the stop in question as a terminating point or not.
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.

freddyhayward

#107
Quote from: jamespetts on December 26, 2020, 12:04:18 PMImagine, for example, a minibus that stops 10 times per game month and with a fixed cost of 1.29c. At each of its stops (assuming even spacing), it would charge a fixed cost of 1.29c / 10, which would, in integer arithmetic, produce 0.12c. 0.12c * 10 = 1.20c, reducing the fixed cost by 0.09c/month compared to an otherwise identical convoy with only 1 stop per game month. With 100 stops, the cost would potentially be truncated further to 1.00c.
Thanks, I had not considered this issue. The timing points I suggested could instead be used to accumulate time spent with an active staff (that is, not in layover), which could then be charged at the end of each month.

Quote from: jamespetts on December 26, 2020, 12:04:18 PM
We may also want to consider whether we need the concept of "layover facilities" and, if so, how to interpret it; do we need different facilities for different types of convoys (consider an airport with an associated 'bus stop, for example; layover facilities for the 'buses should not, if layover facilities are a thing at all, necessarily mean layover facilities for the aircraft, too). What exactly did you intend "layover facilities" to simulate?
I deliberately did not consider the actual implementation of layover facilities - I assumed that they were already planned because they were mentioned in prior discussion. As far as my suggestion is concerned, the actual presence or implementation of facilities is not very important as it would only require checking whether a given stop has appropriate facilities for a given convoy (or no check at all if it is decided not to implement them). As an independent discussion, I have not given much thought to the issue but would probably be in favour of generic facilities applicable to all convoy types since layovers as I understand them are primarily concerned with staffing costs.

EDIT:
Quote from: jamespetts on December 26, 2020, 12:04:18 PMEdit: One more significant issue occurs to me: the path explorer. One of the specifications for the layover feature is that the path explorer should not route passenger/mail/goods past a layover point. This is, I think, the reason that it was considered necessary explicitly to state the layover in the first place: the path explorer needs to know where layovers will occur at the time that it runs in order to determine whether to treat the stop in question as a terminating point or not.
If it is decided that all goods must be unloaded at layovers (which would be the only reason not to route past them), then convoys carrying goods would record non-layover time at those stops. Adding 'load only', 'unload only' and 'unload all' flags would give players more control over routing behaviour in many situations besides layovers. These were suggested and rejected earlier:
Quote from: jamespetts on February 08, 2018, 12:50:17 AMAs to W. Lindley's suggestion - thank you for suggesting that, but having to increase the size of the flags to 32-bit to accommodate the extra 3 flags for reversing would actually take more space than it would take as it stands; and the minimum loading has already been co-opted for some depot specific flags
I think that these are worthwhile features and it would be worth exploring to either find the space within the flagset by removing or consolidating other flags, expanding to 32 bits, or rearranging categories of flags into a few 8-bit sets.

jamespetts

Quote from: freddyhayward on December 26, 2020, 12:32:03 PM
Thanks, I had not considered this issue. The timing points I suggested could instead be used to accumulate time spent with an active staff (that is, not in layover), which could then be charged at the end of each month.

Yes, that would probably be the way to do it - any suggestions for a data structure for this? The implementation of the data structures is what needs to be done at the earliest stages of this project.

I should note that one important refinement to the semi-automatic implicit layovers that you suggest would be to require a substantial lead-in time for a layover, and only record any time without staffing costs if the stop duration is longer than a fixed time to represent the need for the lead-in time, a lead-out time and a reasonable amount of time between the two. One might have a minimum_layover_time= setting in simuconf.tab for this.

Another important anti-exploit mechanism is to ensure that a vehicle cannot load in a laid over state. This then requires considerable complexity to allow players to keep a vehicle in a laid over state for a time until it is ready to load (or else one would get either an exploit or a deadlock when using the wait for % load feature).

Quote
I deliberately did not consider the actual implementation of layover facilities - I assumed that they were already planned because they were mentioned in prior discussion. As far as my suggestion is concerned, the actual presence or implementation of facilities is not very important as it would only require checking whether a given stop has appropriate facilities for a given convoy (or no check at all if it is decided not to implement them). As an independent discussion, I have not given much thought to the issue but would probably be in favour of generic facilities applicable to all convoy types since layovers as I understand them are primarily concerned with staffing costs.

I cannot immediately recall whether layover specific facilities were mentioned (as distinct from refuelling facilities). Whether to require these and, if so, what to require, is a potentially complex question that needs careful consideration. However, it requires early consideration, since, as noted above, data structures come first in the implementation phase.

QuoteIf it is decided that all goods must be unloaded at layovers (which would be the only reason not to route past them), then convoys carrying goods would record non-layover time at those stops. Adding 'load only', 'unload only' and 'unload all' flags would give players more control over routing behaviour in many situations besides layovers.

With the semi-automated implicit layover system that you suggest, one could simply use the existing "layover" flag as an "unload all" flag, which would have very similar functionality to the layover flag as originally proposed, save that the actual entry to and exit of layover states would only arise when the relevant conditions have been fulfilled rather than whenever this flag has been set.

QuoteThese were suggested and rejected earlier: I think that these are worthwhile features and it would be worth exploring to either find the space within the flagset by removing or consolidating other flags, expanding to 32 bits, or rearranging categories of flags into a few 8-bit sets.

What was suggested was:

Quote
Also, why not change Reverse from an 8-bit field to a bit flag as well?

If there are bits left, "Receive only" and "Unload only" would be quite nice; used along with the conditional-skip, a stop would be skipped if the convoi were already full (receive only, conditional skip) or already empty (unload only, conditionally skip).

The original objection to this still holds; may I ask why these features justify increasing the per schedule memory consumption?
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.

Mariculous

Quote from: jamespetts on December 26, 2020, 02:14:17 PMYes, that would probably be the way to do it - any suggestions for a data structure for this? The implementation of the data structures is what needs to be done at the earliest stages of this project.
Did I misunderstand the suggestion?
The needed "datastructure" sounds like a simple int to me. Instead of paying the cost instantly, we add the time spent to the counter, at the end of each month, pay the costs according the accumulated time, done.

Quote from: jamespetts on December 26, 2020, 02:14:17 PMAnother important anti-exploit mechanism is to ensure that a vehicle cannot load in a laid over state.
When "wait for load" is used, do not load any goods in layover state, unless loading all the available goods will exceed the defined "wait for load" value.
Sounds like a rather simple implementational thing to me, not a big conceptual issue.

Quote from: jamespetts on December 26, 2020, 02:14:17 PMThe original objection to this still holds; may I ask why these features justify increasing the per schedule memory consumption?
How much additional memory consumption are we talking about?
I'd expect that memory to be rather negligible.

Assuming an impresively huge map with 10k vehicles and each route to contain 100 stops(which is much more than even on BB), we get an impressive 1 million affected entries, growing each of these by 16 bits (2 bytes) results in an impressive 2mb of additional data.
Do we really need to argue about the justication of 2mb?

freddyhayward

Quote from: jamespetts on December 26, 2020, 02:14:17 PM
The original objection to this still holds; may I ask why these features justify increasing the per schedule memory consumption?
The cost of doubling the flag size from 16 bits to 32 bits is extremely low. bridgewater-brunel currently has 5000 convoys. If  each convoy had its own unique schedule with 20 stops, that would add at most an additional 0.2MB of memory usage to the existing ~9-10GB. It would provide the space to trivially add another 13 flags in the future without needing to change the data structure again. Such flags could include orders for request stops, waiting for transferring cargo, and using the end of the platform.
Further, there are a number of situations where one or more of "no load", "no unload", and "unload all" would be use:
1. Forcing local passengers to use local services between nearby stops on a long-distance line by setting "no unload" on the down trip and "no load" on the up trip for those stops.
2. Preventing freight transfers from occurring at delivery destinations by setting "no load" at the destination stop.
3. Preventing freight from routing from one hub to another via a low-capacity delivery service (and instead use high-capacity services) that stops at both hubs to pick up cargo.
4. Preventing cargo from loading too early onto a delivery service that serves one hub multiple times per round trip and multiple destinations once per round trip by setting "unload all" either at all the destination stops or all the hub stops.

freddyhayward

Quote from: Freahk on December 27, 2020, 04:21:03 AMWhen "wait for load" is used, do not load any goods in layover state, unless loading all the available goods will exceed the defined "wait for load" value.
Sounds like a rather simple implementational thing to me, not a big conceptual issue.
This would be a slightly more difficult in my system that does not have an explicit layover state. Applying this to all situations (which would be necessary in my suggestion) might cause overcrowding at stops which could in turn cause deadlocks where goods will not appear in stops because the stop is overcrowded because the convoy won't pick up the goods. This is actually quite a significant problem with my suggestion...

Vladki

Speaking about the layovers and loading. The reality for goods trains is that the train loading is often  done by different people that the train crew. So the train crew can have a rest during loading, or even the engine detached and dispatched on another trip. Also goods trains are usually loaded sequentially (car by car), not in parallel like passengers who board themselves.

About the flags for conditional skips. What I had long time in mind is "skip the stop if no cargo for that stop is loaded". This is good for a truck supplying several small shops. Similar option "skip the stop if no cargo is waiting there to be loaded" would be nice for pickups from several farms. (however that assumes some sort of telecommunication is available - phone, telegraph, pigeons...)

jamespetts

#113
Thank you for your thoughts in relation to this, especially the memory calculations: that is helpful. As a reminder, the current design of the schedule boolean flags and associated data members is as follows:

Boolean flags:

(1) wait for time;
(2) lay over;
(3) ignore choose sign;
(4) force range stop;
(5) conditional depart before wait;
(6) conditional depart after wait;
(7) conditional skip;
(8) send trigger;
(9) conditional trigger is for line/convoy;
(10) clear stored triggers on departure;
(11) trigger one only;
(12) couple;
(13) uncouple;
(14) target for link couple is line/convoy;
(15) target for link uncouple is line/convoy; and
(16) target schedule direction (whether reversed) for link uncouple.

Data members:

(0) flags, as above (16-bit);
(1) unique entry ID (16-bit);
(2) condition bitfield (16-bit);
(3) target convoy/line ID (condition trigger) (16-bit);
(4) target convoy/line ID (link/uncouple) (16-bit);
(5) target convoy/line ID (link/uncouple) (16-bit);  and
(6) target unique entry ID for link uncouple (16-bit).

The suggested revised design, I believe, would be the following, (edit with changes shown in orange).

Boolean flags:

(1) wait for time;
(2) lay over;
(3) ignore choose sign;
(4) force range stop;
(5) conditional depart before wait;
(6) conditional depart after wait;
(7) conditional skip;
(8) send trigger;
(9) conditional trigger is for line/convoy;
(10) clear stored triggers on departure;
(11) trigger one only;
(12) couple;
(13) uncouple;
(14) target for link couple is line/convoy;
(15) target for link uncouple is line/convoy;
(16) target schedule direction (whether reversed) for link uncouple;
(17) discharge payload;
(18) set down only;
(19) pick up only;
(20) unused;
(21) unused;
(22) unused;
(23) unused;
(24) unused;
(25) unused;
(26) unused;
(27) unused;
(28) unused;
(29) unused;
(30) unused;
(31) unused; and
(32) unused.


Data members:

(0) flags, as above (32-bit);
(1) unique entry ID (16-bit);
(2) condition bitfield (16-bit);
(3) target convoy/line ID (condition trigger) (16-bit);
(4) target convoy/line ID (link/uncouple) (16-bit);
(5) target convoy/line ID (link/uncouple) (16-bit); 
(6) target unique entry ID for link uncouple (16-bit); and
(7) maximum speed (32-bit).

Note that I have used the term "discharge payload" in place of "unload all" used above and likewise "pick up only" in place of "no unload" and "set down only" in place of "no load", the latter two being standard terminology in the 'bus industry in the UK.

I can see that we do need an explicit layover given what Freddy has explained regarding deadlocks with wait for load. We may wonder whether we need to require the payload to be discharged for a layover for mail and goods, but we will need this to be done for passengers. However, this then gives rise to the complex question of how to deal with this in convoys with both passengers and other sorts of cargo. We probably cannot rely on the "discharge payload" flag for these purposes, as this would be set per schedule, so would have to make this implicit for passengers when the layover flag is set, and have logic in the path explorer specifically for this case.

As to the discussion of the computation of staff costs, Ranran has reminded me of this thread, which discusses the issue in considerably more depth and on which it is probably better to continue that aspect of the discussion.

Edit:  I have modified the above to show the changes in orange. I have also added a maximum speed parameter as discussed here. This is intended to have the effect of limiting the convoy to the set speed (which would be set by the player in km/h but converted to internal speed steps for storage) when its next schedule entry has the speed defined. Setting this to zero would disable the limit, and be the default value.
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.

jamespetts

Quote from: Ranran on December 28, 2020, 05:09:58 AM
Questions related to UI design work:
(1) Are wait_for_trigger and broadcast_trigger_on_arrival exclusive?
In other words, is it possible that [->1] [1->] are displayed at the same time?

No, these should not be exclusive: it should be possible for a convoy to broadcast one trigger on arrival and then await another.

Quote
(2) Can lay_over be considered like a superordinate of wait_for_time?
What triggers convoy to return from lay_over? If it's time, I think it's considered higher than wait_for_time.
Can we make it a lay_over even if the convoy is waiting for another convoy to join?
My intention is that if [LO] contains [*], it doesn't make sense to display both at the same time.

Not necessarily: a layover might work with a condition rather than a time, so the order might be for the convoy to go into layover until a condition has been fulfilled. A return from layover might be caused either by a time or a trigger.
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.

jamespetts

That looks very good!

As to a clear vision for the triggers - do you need more information from me in this regard?
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.

jamespetts

Thank you for this analysis. First of all, as to the graphic, this looks good, but it would help if you could explain the new symbols. Also, a question about the fuel indicator: does this denote a forced range stop or any range stop? It would probably be better if the symbol denoted any range stop, perhaps with a different colour for a forced range stop.

In relation to debugging - I will have to look into that when I get home; thank you for reporting this.
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.

freddyhayward

Quote from: Ranran on December 30, 2020, 12:34:59 AMtriggers match the increase / decrease colors that can be set in the theme. Therefore, in the above example, the separation is orange, which indicates a minus, and the addition is a turquoise color, which indicates an increase.
If send and receive  are already indicated by the triangle direction and color, the '+' and '-' indicators are probably redundant. They might also be confusing, since '+3' indicates trigger no. 3 rather than 3 triggers.

jamespetts

Quote from: Ranran on December 30, 2020, 12:34:59 AM
When is any range stop used? Or is it a plan? Is there such a parameter somewhere?

The logic for this is not written yet, but all the parameters are present. The logic will be that convoys will have to make a range stop every time that the distance to the next stop would exceed the distance specified in the last range parameter since the last range stop or last leaving the depot. For example, if a convoy had a range of 100km, and stops at 40km apart, the first stop after leaving the depot would be 40km from the last range stop or depot visit. The second stop would be 80km away, so the first stop would not need to be a range stop. The third stop, however, would be 140km away from the last depot visit or range stop, so the second stop would need to be a range stop. The third stop would then be 40km from the last range stop; the fourth stop would thus be 80km from the last range stop, so the third stop would not need to be a range stop, and so forth.

QuoteWhat color is desirable for force range stop?

I would suggest black for an automatic range stop and dark red for a forced range stop.

QuoteLayover symbol that imitates the sleep state

Is that the three quarters circle with the "zzz"? If so, that looks good.

QuoteHourglass symbol indicating that the waiting time is set at the station

This is a good symbol for this.

QuoteBrown pile indicating that loadind limit is set. The load limit percentage is displayed as a yellow bar.

This seems sensible.

QuoteThe color of the line indicates the color of the player

That looks good, although you might want to test all the colours to make sure that nothing clashes with e.g. the highlight colour.

Quote
Double line indicates round-trip route. round-trip will show a reverse mark at the end of the schedule. If not, a dashed line will be displayed to indicate that you will return to [1].
A dashed line is displayed for the route to the depot as well.

That is a nice idea. I wonder whether, instead of the green arrow symbol, it might be clearer to join the two lines in a loop after the first and last stops?

QuoteThe station number display is a player-colored square in the case of a depot.

I cannot see an example of this in the displays above; but I wonder whether there might be a clearer way of designating a depot than a square; perhaps a square with an oversized triangle on top of it representing a gabled roof to depict a depot building?

Quote
waypoint is an unnumbered circle.

The station has a white background with a square with rounded edges in the color of the station owner.

That looks good. One thing that might be even better - although not a high priority - is a graphical difference between stops at which only convoys of this line (or only this convoy, if it does not belong to a line) stop and stops at which other lines/lineless convoys stop. This is common on maps of metro networks around the world. One might use a circle with a number to represent a non-interchange stop and a square with a number to represent an interchange stop. The waypoint might either remain as a circle without a number, or switch to a thick perpendicular bisecting line.

Quote
ignore choose means that the arrival coordinates are fixed, the text color of the coordinates changes to blue, and the information symbol is displayed next to it.

I am not sure that this is the clearest way of representing this, as this looks as though it is giving general information - I wonder whether a set of diverging arrows with a red cross through it may be more suitable?

Quote
triggers match the increase / decrease colors that can be set in the theme. Therefore, in the above example, the separation is orange, which indicates a minus, and the addition is a turquoise color, which indicates an increase.

This looks sensible, and I agree with Freddy's suggestion for making this clearer, especially the latter part.
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.

freddyhayward

Quote from: Ranran on January 02, 2021, 01:15:18 PMI'm thinking about how to distinguish between symbol designs. So I have a question.
Is the discharge payload intended to make the convoy out of service until the next stop?
Does that mean it's exclusive with minimum load setting and pickup only? It seems pointless at first glance to unload all passengers and reload them. Is it possible?
Discharge payload does not need to make convoys out of service. If a convoy discharges payload and allows loading, it will first load the cargo already waiting at the stop.

freddyhayward

Quote from: Ranran on January 02, 2021, 01:46:49 PMWhat are the benefits of being able to do that?
So what makes it different from being able to set pickup only and setdown only at the same time?
Unloading something that does not need to be disembarked will add to the disembarkation time.
If you want to unload everything once during the layover, you only need to include it in the layover, eliminating the unnecessary operations and confusing things mentioned above.
You may not want there to be any cargo onboard, for example. Maybe you want the convoy empty before going over a weight restricted bridge. Maybe you don't capacity to be filled longer than is absolutely necessary. Goods and passengers will often make questionable decisions that harm operation. I will draw and link an example soon.

freddyhayward

Quote from: Ranran on January 04, 2021, 06:23:04 AMHowever, convoy spams "convoy has entered a depot" every time it returns to the depot on a schedule, which can be annoying. I think this should be changed.
I agree, same with "too long for next stop".

jamespetts

My apologies for not having replied to this for a while: this is a rather large topic, and I have been preoccupied with other things of late; since I am still working from home, I have been preferring to spend my evenings doing something other than working on a computer in order to have some variety, so have been focussing on my model railway of late. This is still a worthwhile project, however, so I hope that you will forgive the delayed response.

Quote from: Ranran on January 04, 2021, 03:15:20 PM
Thank you for your feeding.

Are there parameters as if the station had refueling equipment?

I do not think that any requirement for stations to have refuelling equipment has yet been encoded. I am not sure how significant that this would be in economic simulation; what would it have cost in reality to have a pile of coal at a station? Also, nearly every airport has refuelling facilities, so it would make little sense to have the ability to build an airport in game without this. It would require significant extra balancing and possibly significant extra work in producing graphics. However, if we decide that this is important in the future, it should in principle not be hard to add this.

Quote
I find it difficult to draw. Drawing beyond table cells is tedious. simutrans is difficult to draw beautiful and thick curves. It's easy to draw a rough straight line. Display area problems with station name display, etc.

That is understandable; do not worry if this is too hard to implement.

QuoteThe first design was at number one in the second image of reply # 126, but the design has changed as you suggested.

Excellent, thank you.

Quote
Anyway, due to the 2021 year, the schedule UI has transformed (hentai). (´・ω・`)
Feel the essence of Jarápagos.



A big suggestion for changing the seasoning is to split the layout left and right.
I think this is necessary due to previous visual changes. The schedule list tends to be longer than before, so it's more convenient to have a more comprehensive view.

And the option buttons were crowded due to the large number of options. Group this into a vertical list.

That does look good, and makes it nice and easy to understand. Excellent!

Quote
For example, I think it is difficult to write a number in a circle to display a three-digit number. If you try to put a number in a circle, the height of the line will increase. Therefore I propose a distinction as shown in the picture above.

The stop with a white background is the interchange station.

Yes, I can see the advantage of doing it that way. That does look good.

Quote
This can now be defined as:
Obj=symbol
name=IgnoreChoose

But I haven't made a symbol. If the pakset does not have a symbol, the information symbol will be displayed as above.

Thank you for clarifying - we should probably have a custom symbol at some point, since the "i" symbol is potentially confusing in this context, but it is a reasonable fallback where we do not have a symbol defined.

Quote
It was changed like this. It's good to save space.

Excellent, thank you.

Quote
I have added these parameters for testing the dialog.

But unfortunately this couldn't be implemented correctly so I didn't add it.
Therefore the speed limit input is currently dummy.

In my plan, if you set a number there, you will see a speed limit label in the space opposite the distance.

May I ask what problem that you had with implementing this?

QuoteAs a new feature,
(1) an electrical mark will be displayed if the line or convoy needs electrification.

This is very useful indeed!

Quote
(2) If the convoy or line has a convoy with a range limit, the range limit is displayed.
And if you stupidly set a schedule longer than that range limit, the distance display will turn red.
For example, in the image above, you are scolded by the schedule dialog because you are set to travel a distance of 31.1km even though you are using a horse with a 20km limit.
(At the moment it is checking the distance between two points, but this is expected to be improved to check between stations.)

This is also very useful and will make players' lives much easier - thank you.

Quote
EDIT:
The arrows for wait_for_trigger and broadcast_trigger were in opposite directions. It will be fixed.


EDIT2:
The schedule setting status is not reflected immediately except for the change of minimum load. I'm stuck on how to fix this.

Do you mean that the underlying data does not update until the dialogue box is closed?

Quote
memorandum:
- I thought about removing the entry by abolishing the remove button and putting a garbage button on each entry and clicking it, but it seems difficult to implement.
Placing the button there seemed complicated. The standard has a posbutton in the entry, but this was actually a fake image rather than a button.

This would be a nice feature to have, but do not worry if this is too much work.

Quote
- I noticed that there was an issue lying in the current travel distance logic. That is, there is a contradiction between the schedule display and the calculation.
The travel distance is calculated as a straight line distance, that is, the shortest distance. If you set a waypoint in the middle, the total value on the display will not be the shortest value, which is inconsistent with the value calculated by the player in his head.

Can I clarify - is this an error in your code or in the code already existing in Simutrans-Extended?

Quote
EDIT2:
It was brushed up.


Interesting! That looks splendid. May I ask what the orange highlighting on the line represents?

Quote

One problem with discharge is the combination with mirror schedule. For example, if you want to limit the speed to the next station, the mirror schedule will work correctly by referring to the speed limit of the previous station. But what about discharge?
This also makes it difficult to get the correct behavior that freddy said above. It is probably not recommended to use the mirror schedule in that case.

This is an interesting thought. I wonder whether mirror schedule ought to work in a special way in conjunction with discharge and do the opposite thing if the convoy is in its reverse direction?

Quote
Ambition, I wonder if we can make something like this. This will give you a more modern game look.


Interesting - is this intended for the display when adding items to a schedule or viewing a schedule? If so, that would be very useful indeed.
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.

Vladki

QuoteI do not think that any requirement for stations to have refuelling equipment has yet been encoded. I am not sure how significant that this would be in economic simulation; what would it have cost in reality to have a pile of coal at a station?

A pile of coal is indeed not a big deal. But a water tower is. Also a gas/petrol station is definitely not on every bus stop. Compare refueling facilities to the cheapest stop, not to a big station. Airports without refueling exist in remote places, where the only way to bring fuel is by plane.

Mariculous

#124
Quote from: jamespetts on April 02, 2021, 01:19:11 PMI do not think that any requirement for stations to have refuelling equipment has yet been encoded. I am not sure how significant that this would be in economic simulation; what would it have cost in reality to have a pile of coal at a station?

In the real-world it's not as simple as piling up some coal at the station.
You need special infrastructure to load the coal as swell as infrastructure to refuel water.
The same goes for Diesel, Hydrogen or any other kind of fuel. Even for electricity in case of battery vehicles.

I like the very last image. It really gives a more modern look at the map.
I'd really love to see the route itself to be painted on the map. I am aware that this route might depend on the actual vehicle on the line, so we could use the very first vehicle of the line to calculate the route and a dummy when there is no vehicle assigned yet.



As this thread is all about schedules, I'd like to throw in a consieration about timed schedules aka timetables:
In the real-world, routes are scheduled with a fixed waiting time in stations and a fixed journey time between these.
The scheduled time should usually be longer than the time it actually takes to wait at a station or to travel in between stations at full speed.
Once the scheduled time is shorter, we have a delay, in which case the train might exceed the scheduled speed or spend les time in a station time to catch up.
In simutrans, we cannot handle delays at all. Either we don't schedule a stop at all (depart when ready) or we schedule it to depart at a fixed time, in which case we will wait for the next time slot as soon as we are delayed by only a second.

I don't want to "request" a feature to handle delays here, but the above discussed scheduling concept should at least keep this in mind.
An "is delayed" condition to allow for exceeding the scheduled maximum speed, as well as an attribute to allow for delayed departures should be enough in most cases.
Optionally, a field to enter a maximum delay at which a train may still depart.
In that case, we'll also have to consider what to do when a train is much too late (more delay than the maximum delay).
Currently, maximum delay is 0 and trains exceeding that delay will simply wait for the next schedule slot.

Matthew

Quote from: Freahk on April 02, 2021, 04:52:30 PM
As this thread is all about schedules, I'd like to throw in a consieration about timed schedules aka timetables:
In the real-world, routes are scheduled with a fixed waiting time in stations and a fixed journey time between these.
The scheduled time should usually be longer than the time it actually takes to wait at a station or to travel in between stations at full speed.
Once the scheduled time is shorter, we have a delay, in which case the train might exceed the scheduled speed or spend les time in a station time to catch up.
In simutrans, we cannot handle delays at all. Either we don't schedule a stop at all (depart when ready) or we schedule it to depart at a fixed time, in which case we will wait for the next time slot as soon as we are delayed by only a second.

I don't want to "request" a feature to handle delays here, but the above discussed scheduling concept should at least keep this in mind.
An "is delayed" condition to allow for exceeding the scheduled maximum speed, as well as an attribute to allow for delayed departures should be enough in most cases.
Optionally, a field to enter a maximum delay at which a train may still depart.
In that case, we'll also have to consider what to do when a train is much too late (more delay than the maximum delay).
Currently, maximum delay is 0 and trains exceeding that delay will simply wait for the next schedule slot.

Perhaps worth mentioning that OTRP has already implemented this feature.
(Signature being tested) If you enjoy playing Simutrans, then you might also enjoy watching Japan Railway Journal
Available in English and simplified Chinese
如果您喜欢玩Simutrans的话,那么说不定就想看《日本铁路之旅》(英语也有简体中文字幕)。

PJMack

I am looking forward to this feature, however there are three things that have not been mentioned.  One is that a mechanism would need to be in place to ensure that a consist does not exceed the weight restrictions of bridges.  The method of doing that would have a setting of not only the maximum weight, but the maximum weight per tile, as short bridges sometimes only need to support part of a train.

The second issue is, at the risk of sounding like a feature request, is dead toeing of locomotives and cars.  What I mean by that is in some cases, have the locomotives part of the consist but not powered on or staffed, just along for the ride; or empty passenger or dining cars en-route to the depot since they would not need staffing, meal service, or even AC or lighting.  Although this has been mentioned before, there would also be live toeing where a vehicle would not be staffed, but operated by remote control (e.g. 2 DMUs).  For the technical side, it would require in addition to layover and running states, vehicles would also have a dead toe state, live toe state, and empty toe to/from depot state.  (An additional state may could an un-catered state to close the kitchen for some shorter trips, but that would involve a feature request).  Such states would need to be specified in the consist, and the packset would need a set of vehicle costs for each state.  (One possible addition would be allowing some relaxed coupling constraints in the empty toe to/from depot state to allow new passenger cars to hitch a ride with the freight trains, but again, that would be a feature request.)

A third issue is that comes to mind is with ships and planes where the "vehicles" are actually holds and interior configurations that could not be rearranged easily at port.  A simple "ishold" flag for the "vehicles" in the packset would need to be added to ensure that such holds can only be rearranged within an actual depot.  Alternatively, if various refueling and/or small repair facilities at stations/docks are incorporated, the packset would have a variable to limit which such facilities could rearrange holds.

Octavius

I recently returned to simutrans-extended. Nice to see some progress, but I also found out that I may need a new computer, as I can only run the game on fairly small maps.

The thing is, in a forgotten directory on my hard drive I found an almost forgotten file with some notes concerning a way to do scheduling in simutrans-extended, some of which pretty detailed. The ideas would support at least:
- splitting trains to operate on different branches of a line and recombining on the way back;
- changing locomotive for different portions of a line;
- parking wagons, trailers or unpowered barges at a stop waiting for cargo, only to call a locomotive/tractor/pushboat when full;
- lorries skipping stops where there's nothing to load or unload;
- a locomotive pool providing banking service for heavy goods trains of any owner on a mountain pass;
- putting lorries on RoRo-ferries, making services to small islands much easier (and more profitable);
- trains being rerouted or cancelled on excessive delay;
- setting waiting points for goods trains, where they are scheduled to be overtaken by passenger trains;
- as a bonus, loading and unloading cargo without stopping (or needing a platform at least as long as the train). This was actually done by some travelling post offices and is still done by bulk trains.

Of course, some work has already been done on this and it wouldn't be good to undo all of it to go some different direction, but would some of you like it if I translated some of these notes and put them here? (I ask first, because I don't want to sound too pushy and it's quite a long write.)

BTW, I'm actually a decent coder, in particular in C, but my use of C++ is more incidental and I'm completely unfamiliar with the simutrans code, so working on something big like this wouldn't be my first choice.

jamespetts

Octavius - thank you for your thoughts and apologies for the delay in responding. I would suggest that you post your notes on this topic in a different thread, as this thread is intended to be focussed on discussing the precise implementational details of the current 15 branch, and so discussion of a different system on this thread is likely to be disruptive. However, it would be interesting to see what you had envisaged in a separate thread.
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.

jamespetts

I am beginning work on trying to merge all the latest changes from Standard into the vehicle-management-new branch. So far, I have been able to get it to compile, but I get errors loading any saved game or generating any new game, both relating to inter-city roads (although probably in different parts of the code), so it is not currently usable.

It may take a considerable time to pick through the various issues with this, as merging diverged codebases is much harder than adding new code, so any assistance (especially from those who have added any of the code that conflicted with the original vehicle-management code) would be much appreciated.

I should note that I am not quite sure of the UI status of this branch at present, as, as indicated, I have not been able to get it running beyond the loading screen because I can neither load nor generate a game.

I think that the work in this branch needs to be prioritised at this time, as vehicles that never wear out are causing notable imbalances in the current game and distorting player incentives to do tedious and unrealistic things as opposed to interesting and realistic things.
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.

jamespetts

#130
I have noticed that Ranran has produced an ex-15-2022 branch, which has merged the latest changes up to about March this year from master. I have copied this branch and created my own ex-15 branch with this version of the code. This seems to work better than the vehicle-management-new branch, in that I can now load and save games with this.

Unfortunately, attempting to merge with the master branch produces irreconcilable conflicts in the schedule GUI code which are virtually impossible for me to resolve because I know very little about how the new GUI schedule works. I wonder whether Ranran might be able to look into the merging of this part of the code?

Edit: I see that Ranran had already implemented a sophisticated alternative GUI for the schedule in the ex-15-2022 branch. Unfortunatelly, trying to merge this by simply ignoring the changes on the master branch and overriding this with the changes from the ex-15-2022 branch produces a compile error as follows:

1>C:\Users\James E. Petts\Documents\Development\Simutrans\simutrans-extended-sources\gui\components\gui_aligned_container.h(120,47): error C2668: 'gui_colored_route_bar_t::gui_colored_route_bar_t': ambiguous call to overloaded function (compiling source file gui\schedule_gui.cc)
1>C:\Users\James E. Petts\Documents\Development\Simutrans\simutrans-extended-sources\gui\components\gui_schedule_item.h(35,2): message : could be 'gui_colored_route_bar_t::gui_colored_route_bar_t(PIXVAL,uint8)' (compiling source file gui\schedule_gui.cc)
1>C:\Users\James E. Petts\Documents\Development\Simutrans\simutrans-extended-sources\gui\components\gui_schedule_item.h(34,2): message : or       'gui_colored_route_bar_t::gui_colored_route_bar_t(uint8,uint8)' (compiling source file gui\schedule_gui.cc)
1>C:\Users\James E. Petts\Documents\Development\Simutrans\simutrans-extended-sources\gui\components\gui_aligned_container.h(120,47): message : while trying to match the argument list '(const A1, const A2)'

This message is somewhat inexplicable in the circumstances.
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.

jamespetts

Excellent, thank you! This does work. It is excellent to see your improved schedule UI in operation.

This is quite a long-term and large project, and I have not done major work on this since 2018, so it will take some time for me to set myself up with the work in this and see how far that I had got and what other things may need to be changed based on feedback since. It may well be that I will have to split out certain parts for a future update.

Your assistance with this is much appreciated. For new features that require new user interactions, assistance with the UI, especially of this quality, is highly valuable.
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.

jamespetts

I have been doing some implementation work on this in the last few days. All the work on this project is now in the ex-15 branch on my Github repository.

In particular, I have been adding the vehicle type data (i.e., the data specified in .dat files for vehicles and stored in game in vehicle_desc_t objects).

Here is an extract from the code, including some brief documentation by way of comments, to give an overview of what has been added:

uint32 base_initial_overhaul_cost = 0; // Overhaul cost (without scale factor and increase for multiple overhauls)
uint32 initial_overhaul_cost = 0; // Overhaul cost (before increse for multiple overhauls)
uint32 base_max_overhaul_cost = 0; // Overhaul cost (without scale factor after full increase for multiple overhauls)
uint32 max_overhaul_cost = 0; // Overhaul cost (after full increase for multiple overhauls)
uint16 overhauls_before_max_cost = 0; // The number of overhauls before the maximum overhaul cost is reached. 0: no change
uint32 max_distance_between_overhauls = 0; // The maximum distnace in km between overhauls. 0: no overhauls required
uint32 max_takeoffs = 0; // The maximum number of takeoffs (flight cycles) between overhauls for an aircraft. 0: unlimited
uint32 availability_decay_start_km = 0; // The number of km since the last overhaul when the availability begins to decay. 0: no decay
uint8 starting_availability = 100; // The percentage availablility of this vehicle when new. 100: needs no maintenance
uint8 minimum_availability = 100; // The percentage availability of this vehicle when at max_distance_between_overhauls since the last overhaul 100: needs no maintenance

uint32 calibration_speed = 0; // Used for calibrating the fuel consumption (km/h). 0 = fuel consumption does not vary with speed.
// A non-zero value represents the speed (assuming accelerating or physics limited to this speed)
// against which the fuel consumption per unit of distance is calibrated.
uint32 cut_off_speed = 0; // The minimum speed below which fuel consumption per km does not reduce (km/h)

uint32 fuel_per_km = 0; // Fuel cost calibrated according to the above. Not all powered vehicles (e.g. sailing ships) use fuel. The traction type records the fuel type.

bool self_contained_catering = false; // Whether any catering provided by this vehicle is available to the whole consist or only this vehicle.

/**
* Staff data.
* Hashtable: key: staff cost type; value: number of staff for this vehicle.
* Introduced for version 15
*/
typedef inthashtable_tpl<uint8, sint32, N_BAGS_SMALL> staff_map;
staff_map drivers; // Staff who need to be present if the vehicle needs to be driven.
staff_map conductors; // Staff who need to be present if the vehicle is at the rear.
staff_map staff; // Staff who need to be present at all times.

uint8 multiple_working_type = 0; // This determines whether multiple powered vehicles need drivers only in the first of them. If the numbers match (and are non-zero), then yes; otherwise, no.

Note that the above code extract has been abridged to show only new data.

Once the data members are fully in place, work can start on both the logic and UI (indeed, that work can go on in parallel once the data members are in place). Ranran - if you have any questions about the intention of any of these data members for the purposes of UI implementation, please let me know.

A few notes for reference for the UI design:

* availability is a percentage;
* the intention is that only the current availability percentage should be displayed to the player (this will be calculated in vehicle_t not vehicle_desc_t);
* the intention is that only the cost for the next overhaul should be displayed to the player (this will be calculated in vehicle_t not vehicle_desc_t);
* I am not sure how best to represent the fuel economy data in the UI;
* the intention is for the fuel specified in the code to be unit agnostic, so long as the pakset authors consistently use the same units; and
* I have yet to implement the global data (the .tab files and the new simuconf.tab settings).
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.

jamespetts

Ranran - thank you for your work on this, and apologies for the delay in replying. I realised that I had not fully worked out the answers to some of the questions and that some things that I had implemented needed to be modified to deal with some of the points raised. I will deal with the questions under headings below.

Staff

Thank you for that very useful explanation of the system that you had proposed. This is actually a very good idea and significantly reduces the complexity of the logic needed to implement the system.

Indeed, with this system, there is no need to distinguish between conductors and other staff. What I have implemented, therefore, are two datasets: (1) drivers; and (2) staff_hundredths. Each of the two types can be of any of the 255 possible enumerated types wages of which will be able to be set in a staff.tab when I implement that. Drivers will work as previously discussed. Staff hundredths will work as you suggested.

The reason that there is no need to distinguish between staff and conductors is that players who want to specify a vehicle that always has a fixed number of staff (e.g. a buffet car which always has somebody behind the counter, or a passenger brake carriage before continuously braked trains that always has a guard in it) can just specify a multiple of 100. This will not interfere with any lower number set to represent any other staff as multiples of 100 will always increment staff by exactly 1.

To facilitate this, I have altered the interface in the .dat files to allow pakset authors to specify either staff[0]= or staff_hundredths[0]= (or substituting any other number for 0 for different wage groups for staff).

Note that the ability to specify staff of different pay grades in this way should address the issue raised by Matthew in this post.


Fuel consumption

The calculation for fuel consumption has been discussed at some length elsewhere – I do not believe that anyone has come up with a more workable formula than I have specified here. However, there may be some misunderstanding of what is proposed. The calibration speed assumes that the vehicle in question is taxed so heavily (e.g. with a heavy load) that that is its maximum possible speed. A more lightly taxed vehicle would consume proportionately less fuel.


I would suggest not trying to compute the in-service fuel economy in advance, but giving a catalogue like figure, being the economy at the calibration speed assuming that the vehicle be fully taxed at that speed (and perhaps even giving the load on the level at which it would be so taxed). Where the calibration speed is zero, disabling the dynamic fuel calculation for the vehicle in question, what will have to be given instead is the basic static per km fuel consumption.


Overhauls and replacements

I am not sure how, in detail, best to handle replacement yet. However, I have added, as you will see, an auto upgrade index datum to the vehicles' .dat files. The intended algorithm for this is that, whenever the vehicle to which the index specified in the .dat file refers becomes available, the vehicle is upgraded automatically to this type when it is overhauled. With upgrades, as opposed to replacements, the intention is for the vehicle's existing maintenance data (especially the number of overhauls) to be preserved. Obviously, with a replacement to a new vehicle, this number will start at zero. In general terms apropos replacements, the idea is that these will occur on the next depot visit rather than forthwith, unless the player specifically commands an immediate replacement. It should be possible to replace only certain vehicles rather than all vehicles.

As to deferring overhauls, there will need to be a limit on how far that overhauls can be deferred. That limit is intended to be set at max_distance_between_overhauls or max_takeoffs for aircraft. However, the default overhaul should happen well before this point, and players should be able to defer up to this point. What I have not worked out yet is how best to calibrate the default overhaul point. The decay in availability and increase in maintenance cost after the last overhaul is intended to work on a sigmoid function (I have not yet worked out how best to implement that function using only integers; if you have any idea, I should be most interested; my current implementation is very crude). Quite at what point it is best to default to an overhaul I am not sure. If you have any ideas, I should be interested. The most straightforward option is probably a percentage of the difference between the base and maximum running costs specified in simuconf.tab, with the option to override this in the UI and have the vehicles overhauled when they fall below a certain availability % or above a certain running cost.

***

I hope that this clarifies matters. For reference, the latest set of data  in vehicles' .dat files is as follows:

uint32 base_initial_overhaul_cost = 0; // Overhaul cost (without scale factor and increase for multiple overhauls)
uint32 initial_overhaul_cost = 0; // Overhaul cost (before increse for multiple overhauls)
uint32 base_max_overhaul_cost = 0; // Overhaul cost (without scale factor after full increase for multiple overhauls)
uint32 max_overhaul_cost = 0; // Overhaul cost (after full increase for multiple overhauls)
uint16 overhauls_before_max_cost = 0; // The number of overhauls before the maximum overhaul cost is reached. 0: no change
uint32 max_distance_between_overhauls = 0; // The maximum distance in km between overhauls. 0: no overhauls required
uint32 maintenance_interval_km = 0; // The distance between maintenance depot visits (when the next depot visit will be triggered). 1.5x this will trigger an emergency depot visit wherever the convoy is on its schedule.
uint16 max_running_cost = UINT32_MAX_VALUE; // The maximum running cost of vehicles at max_distance_between_overhauls. Sigmoid interpolation between running_cost and this after availabiliuty_decay_start_km
uint32 max_takeoffs = 0; // The maximum number of takeoffs (flight cycles) between overhauls for an aircraft. 0: unlimited
uint32 availability_decay_start_km = 0; // The number of km since the last overhaul when the availability begins to decay and running costs increase. 0: no decay
uint8  starting_availability = 100; // The percentage availablility of this vehicle when new. 100: needs no maintenance
uint8  minimum_availability = 100; // The percentage availability of this vehicle when at max_distance_between_overhauls since the last overhaul 100: needs no maintenance
uint32 replenishment_seconds = 60; // The number of seconds required for this vehicle to replenish (refuel) at a replenishment stop.

uint32 calibration_speed = 0; // Used for calibrating the fuel consumption (km/h). 0 = fuel consumption does not vary with speed.
// A non-zero value represents the speed (assuming accelerating or physics limited to this speed)
// against which the fuel consumption per unit of distance is calibrated.
uint32 cut_off_speed = 0; // The minimum speed below which fuel consumption per km does not reduce (km/h)

uint32 fuel_per_km = 0; // Fuel cost calibrated according to the above. Not all powered vehicles (e.g. sailing ships) use fuel. The traction type records the fuel type.

...

uint8 auto_upgrade_index = 255; // The index of the vehicle upgrade to which this vehicle upgrades automatically during the first overhaul in which the upgrade is available. Default: 255: no auto upgrade


bool self_contained_catering = false; // Whether any catering provided by this vehicle is available to the whole consist or only this vehicle.



/**
* Staff data.
* Hashtable: key: staff cost type; value: number of staff for this vehicle.
* Introduced for version 15
*/
typedef inthashtable_tpl<uint8, sint32, N_BAGS_SMALL> staff_map;
staff_map drivers; // Staff who need to be present if the vehicle needs to be driven.
staff_map staff_hundredths; // Other staff, expressed as a fraction of 100, but always rounded up to the nearest 100 to allow staff to be added incrementally if necessary.

uint8 multiple_working_type = 0; // This determines whether multiple powered vehicles need drivers only in the first of them. If the numbers match (and are non-zero), then yes; otherwise, no.

As before, only new data are shown.
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.

jamespetts

Quote from: RanranI think it is necessary to consider the high salary depending on the type of staff. However, I don't think I understand the issue correctly. It may be helpful if someone just elaborate on this point.
Inflation needs to be implemented together with fares, fuel costs, etc., so I think it can be considered separately. 

The idea is that there will be different staff types defined with different salaries. So, for example, one might have in staff.tab:

# Train driver
0=1750,10,1800,15,1850,20,1900,50,1930,65,1950,75,1975,150,1990,200,2020,250
# Fireman
1=1750,5,1800,10,1850,15,1900,30,1930,45,1950,55,1975,100,1990,170,2020,200
# Guard
2=(etc.)
# Buffet car attendant
3=(etc.)

Then, in a locomotive, one might have something like this:

driver[0]=1 # 1* staff type 0 (train driver)
staff[1]=1 # 1 * staff type 1 (fireman)

And in a carriage something like this:

staff[3]=2 # 2 * staff type 3 (buffet car attendant)
staff_hundredths[2]=1 # 1/100th of a guard (staff type 2).

The actual cost per month of each type of staff would depend on the numbers in staff.tab. So, for example, for our locomotive, in 1950, it would cost the following per month:

1 * staff type 0 in 1950: 75c + 1 * staff type 1 in 1950: 55 = 130

whereas in 1900 it would be:

1 * staff type 0 in 1900: 50c + 1 * staff type 1 in 1900: 30 = 70

Between the specified points, there would be simple linear interpolation.

I hope that this makes it clear?


Incidentally, I am having some difficulty with the implementation of this system in respect of drivers. For some reason that I have been unable to understand despite extensive testing, the driver data are not written to the .pak files even when these data are present in the .dat files. The same does not happen for the staff data. I cannot see any material differences between the code for staff and drivers in the makeobj sources, and I have not been able to run a debugger on makeobj despite spending a great amount of time attempting to do so because, for some reason that I cannot understand, passing an address for a .dat file to be read and turned into a .pak file as a command line argument in the Visual Studio debugger results in Makeobj being unable to find the file even when executing the identical command on the command line gives rise to no trouble at all in finding the file. Any assistance in resolving this issue woudl be much appreciated.



Thank you for your thoughts in relation to overhauls. Can I clarify what the intention is with the "auto" setting? The idea is for convoys always to have a depot stop somewhere in their schedules , albeit this will be skipped if no maintenance should be required. I think only in emergencies (i.e., where the player has let the distance to overhaul or maintenance exceed the maximum possible threshold) should convoys be sent to a depot immediately no matter where they are in their schedule. One possibility would be to allow players to choose between overhauling when the next maintenance would otherwise be due rather than at the next time that the convoy passes the depot, although I am not sure how useful that this would be.

As to early overhauls, I am not sure that this entirely works for overhauls (as opposed to maintenance), as there is a fixed capital cost for overhauls where there is not for maintenance, and overhaul timings are calculate differently to maintenance timings (I have yet to add the overhaul timing code: I intend to make this fixed per waytype in fractions of a game month from simuconf.tab settings).

In terms of the table, the "distance between overhauls" is potentially ambiguous, as there are in principle many different things that this could be measuring:

(1) the maximum possible distance between overhauls before the vehicle will immediately go to the depot for an overhaul no matter what the player does (but a player would be well advised to overhaul before this point, as availability will have reduced and running costs increased significantly by this point);
(2) the minimum distance after the last overhaul at which availability starts to drop and maintenance costs start to increase (but these will initially increase only slightly, so it is rarely likely to be optimal for the player to overhaul the vehicle at this point);
(3) the optimum distance for the player to overhaul the vehicle (which is likely to be highly complex to calculate with an in-game algorithm); and
(4) the distance that the player has actually set since the last overhaul for the next overhaul.

The same therefore applies by reference to the "distance to next overhaul" setting.

In terms of "upgrade instead of overhaul", one would probably want to think about offering the player a further alternative: "replace instead of overhaul".

I hope that this assists.


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.

jamespetts

A brief update. I have added logic for the following features:

  • overhaul timing;
  • availability based maintenance timing;
  • limits on the maximum number of vehicles that can be undergoing maintenance or overhaul in a depot at any given time (a queue based system);
  • reading values from fuel.tab and presenting fuel costs to other parts of game logic (not yet written);
  • reading values from staff.tab and deducting correctly computed staff salaries in respect of vehicles*;
  • the self-contained catering feature;
  • auto upgrades on overhaul (albeit the logic for sending vehicles for overhaul has not been implemented yet); and
  • per km maintenance cost increase based on distance since last overhaul.

* I have still not managed to fix the bug when reading data relating to drivers for reasons that I still do not understand. Any help with this would be much appreciated.

The next things on my list are implementing the fuel consumption logic and hopefully writing a better sigmoid function based on Prissi's advice. I will also need to think about the implementation of inflation more generally.

A few questions for Ranran (and anyone else following this) at this stage about the interface between the game logic and UI code.

  • How best to deal with the vehicle replacer and its interaction with auto upgrades? My current thought is to have any replace data override an automatic upgrade and to add replace data specifying when the replacement should take place (immediately (the current behaviour), on next possible depot visit, on next maintenance, on next overhaul). We also need to think of a sensible default for these; I would think that on next maintenance would be a good default, but on next overhaul might also be a candidate. Note that if the vehicle is replaced with a non-upgrade type, there will be no overhaul, whereas if the vehicle is simply upgraded, an overhaul will still be performed (but the only cost will be the upgrade cost).
  • Do we need to store any other maintenance or overhaul based options for player control in the vehicle_t objects? I imagine that we should at least need to store the overhaul interval setting - but how to calibrate that by default is not an easy question and and will need some careful thought.
  • Do we need any logic to allow the player to control the depot maintenance queue, for example, by bumping individual vehicles/convoys to the top/bottom of the queue?
  • How is it best to deal with multi-vehicle convoys (e.g. trains) on maintenance overhaul? For technical reasons, it is very difficult to do other than have a convoi_t object that is undergoing maintenance or overhaul, and this is what I have implemented. However, players may not want to maintain/overhaul all vehicles at once, and this may be inefficient. The only way around that I can think of is to allow the players to split the convoys at the point of maintenance/overhaul using the consist orders system, but I am not sure that the current system allows for this. Quite how to handle this will need careful thought and any input on this question (most especially any input that does not require vast amounts of coding effort and entire new abstractions and systems) would be much appreciated.

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.

jamespetts

I have now completed the work for adding fuel consumption mechanics and fixed the bug stopping the drivers system from working, as well as having fixed another bug relating to the accounting for the cost of staff in vehicles.
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.

jamespetts

Quote from: Ranran on June 26, 2022, 08:56:35 AMCurrently I'm testing the updated one, but convoy may make a strange eternal stop.
For example, demo save's (97) LNER Tyneside EMU's staffs will start an eternal strike around 1:00:00.  ::'(
Thank you for this. I have merged your UI work so far into the ex-15 branch for testing.

I have carried out some initial investigation into this, and the problem appears to be that the spacing is not set in the convoys' schedules but the go_on_ticks value is set to WAIT_INFINITE. Looking at the current schedule UI, I cannot see where the spacing setting is; it seems to be missing from the dialogue. If you could restore this, it would be much easier for me to test what the problem is with a view to fixing it.
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.

jamespetts

Quote from: Ranran on June 26, 2022, 02:35:45 PMI've added a maintenance display to the convoy detail, but strangely many vehicles show a running cost increase of 200%.
This conflicts with the depot display and the current master branch value.
Does get_running_cost(welt) also include different factors such as fuel and staff costs?


I think that I have fixed the bug causing this; the problem was that, where the vehicle had 0 (the default) specified for maximum distance between overhauls and the actual distance since the last overhaul was a non-zero value, the maintenance cost was given as the maximum, whereas in fact it ought to have been given as the base cost.
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.

jamespetts

Excellent, thank you for that. First of all, I think that I have fixed the problem with the schedules not working - I should be grateful if you could re-test in respect of that. I realised that the reason that I could not find the wait for time datum previously was that I was looking at the vehicle's schedule rather than the line's schedule; my apologies for any confusion.

In respect of the new schedule window, this is generally very good. One or two small points. First of all, we seem to have lost the timing display for "departures". In the current master branch, we can see in hours, minutes and seconds the frequency of departures, and this is importance for ease of use. This is currently missing from this window. Secondly, I think that we need a little more sophistication with respect to the speed limit. Internally, the code recognises a limit of 65,535 km/h (i.e., the highest number that can be stored in an unsigned 16-bit integer) as unlimited speed. The current UI represents this by showing 65535 in the "speed limit" data entry field. What would be better is for there to be a checkbox for "speed limit". The box being unchecked would be equivalent to the speed limit being 65535. When the box is unchecked, the "speed limit [xxx] km/h" entry should be greyed out. Unchecking the box should automatically set the speed limit to the maximum speed of the convoy and enabling the "speed limit" data entry field. Unchecking it again should override the speed limit with 65535.

The "modify_convoy" button does not work, but I infer that this is because this interface has not been designed yet - I presume that this is for consist orders? I cannot comment on the completeness of what you have implemented here without seeing the implementation of the modify_convoy dialogue.

As to the convoy detail dialogue, I have not had the chance to recompile the themes yet, so I cannot fully test the graphical implementation, but what I have seen looks very good. I agree with Matthew that having the maintenance tab having a higher prominence, being the first tab now opened, is a good design choice. One issue in the maintenance tab is that we seem to have the livery scheme name repeated 6 times underneath the vehicle name; presumably, this name was only intended to appear once? The "last overhauled" display currently shows "Last overhauled: -, (0)" when the vehicle has never been overhauled. If it were instead to say "Last overhauled: never" in such a situation, I think that this would be much clearer. The "since_last_overhaul" display is useful - but equally useful would be a display showing how many km (or flight cycles/takeoffs for aircraft) left before the next overhaul, shown in orange or red if the next overhaul is due within the last 10% of the range or is due now, respectively. One small thing: the "do_not_overhaul" and "do_not_auto_upgrade" buttons would be easier to use if they were in the same vertical alignment as one another.

We do have one possible bug in the change prices dialogue, in that the accommodation name is not translated in the "By accommodation" tab. Also in that tab, I am not sure what "Compartments" is intended to mean here; the word "compartments" has a specific meaning in the context of railway rolling stock (especially older types), and using this word for something else is likely to cause confusion. Can I clarify what was intended here?

I do like the table under the "spec" tab: this is very nice and shows very clearly the vehicles in a train. The "convoy_value" of "initial_overhaul_cost" seems to be broken in that this shows zero even when the individual values are non-zero. The payload_spec option probably needs to show whether any catering is self-contained. I notice that the accommodation strings (e.g. p_accommodation[1], etc.) are not translated here, either.

As to conveying staff costs, I think that the simplest thing to do is simply to communicate the total staff cost per game month to players per convoy. Perhaps this could also be shown as a per hour cost by extrapolation, although this may not be worth it if it is extremely difficult. The more complex thing to communicate is the staff cost per vehicle where this is in fragments that are always rounded up. I suggest here some kind of symbol on each vehicle with a staff cost which does not divide exactly by 100, the first in the convoy being in full colour and showing the staff cost next to it, and the next ones being in light grey with no number next to it, until we get to the next vehicle that takes the number over 100, in which case, the symbol shall be shown on that vehicle with the number, etc..

In terms of fuel economy, I recommend showing it as "x¢/km at y km/h at full power", where y is the calibration speed and x is the base fuel consumption figure multiplied by the current inflation adjusted cost of that type of fuel. The units specified are not money - these are arbitrary units (litres, gallons, tons, tonnes, kilogrammes, BTUs, logs, sacks, etc.) determined by the pakset author. The algorithm does not care what the units are so long as the same units be used for each reference to units in respect of each traction type, which is why I suggest converting these into money when showing these in the UI.

In terms of replacing, you are probably right that the only way of specifying in UI terms how a convoy should be replaced is in the replace dialogue. We can still have a "replace instead of overhaul" option, however: but this can be set in the replace dialogue, so that the replacement is triggered at the point of overhaul. Implicitly, any vehicles that are the same before and after replacement would be overhauled as normal if they require overhaul.

As to automatic upgrades, the purpose of having an automatic (rather than a standard) upgrade is precisely that it is done by default. If it were not on by default, it would work identically to any other type of upgrade. This feature is intended for relatively minor upgrades typically performed at the same time as an overhaul, for example, the replacement of the Paxman Valenta engine of the BR class 43 "HST" power car with MTU engines: the new engines altered the power characteristics, weight, reliability and sound of these locomotives, so would need to be represented in game by a different vehicle with its own .dat file, but these were installed (together with an electrical upgrade) universally at the point of overhaul in 2007-2008. The purpose of automatic upgrades is to take away routine busy-work from players of manually having to specify upgrades the choosing of which is likely to be such an obviously sensible thing to do that no player is likely, save in exceptional circumstances, to want to overhaul the vehicle without performing this sort of upgrade. An upgrade that does not fit into this category is one that is best not specified by the pakset author as an automatic upgrade. Normal (i.e., non-automatic) upgrades do allow multiple upgrade candidates for vehicles at any given time, and these can be chosen by the player; the default would be no upgrade. The combination box that you suggest for this should work well with this as it stands.

We do want to think about what happens in the case of trains to prevent the whole train having to go in for an overhaul lots of times because each carriage has a slightly different overhaul timing. Perhaps we could specify something like "overhaul if other vehicles in this convoy are being overhauled and the distance to the next overhaul is less than Xkm".

In any event, this is very helpful - thank you for your work on this.
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.