bergerhealer / TrainCarts

Minecarts redefined
MIT License
205 stars 63 forks source link

After waiting at waiter sign, trains aren't launched to full speed again #488

Closed amalon closed 10 months ago

amalon commented 11 months ago

Info

Please provide the following information:


Bug

Description

After waiting at a waiter sign, for example:

[+train]
waiter100
2

due to a stopped train in the next 100 blocks, if I destroy the train ahead (or it moves on out of the wait zone), the waiting train doesn't launch back to full speed. /train status reports that it only launches to around 0.2b/s, so it crawls along around the track causing a massive queue of trains behind it.

Expected behaviour

I suppose it should launch to launchForce like stations do.

Actual behaviour

The launch speed is sometimes much smaller

Steps to reproduce

Additional Information

Screenshot_20231118_153623

bergerkiller commented 11 months ago

In general I recommend to stop using the waiter sign and use the wait distance property, instead. This is because the waiter sign mechanic has problems like this, especially at server restarts.

Ill give this a look to see if theres anything I can do though*

Also, you should probably put a space between name and arg. So 'waiter 100' not 'waiter100'. Idk why people do the latter

bergerkiller commented 11 months ago

Keep in mind that the waiter re-launches the train to the speed it had upon reaching the waiter sign. If you have a launch action going on at the same time, that launch is aborted, and the current speed at launching is used to resume it. The launch isnt resumed.

Stating this in case it applies

amalon commented 11 months ago

that'll be because the wiki explicitly says without a space: https://wiki.traincarts.net/p/TrainCarts/Signs/Waiter

Its pretty soon after a station where I'm particularly seeing the problem, so yeh its possibly its mid way through a launch, or else just queued up due some complex routing near a junction.

I've started using waiter signs for a few things, not so much for spacing trains, but:

bergerkiller commented 11 months ago

Oh wow, its indeed wrong on the wiki. Let me correct that then. Judging by code either method should work but there is definitely no requirement that there be no space between wait/waiter and the distance.

bergerkiller commented 11 months ago

If youre on discord weve been talking about this there as well. Ill repeat kind of my current suggestion, see if it works for you.

I want to add a new sign, "pathingmutex" or "pmutex". What it does is that, similar to the waiter sign, when a train approaches it (wait deceleration) or nears it, it will look for tracks ahead and turn that into a new temporary mutex zone. If no other trains are occupying the track at this time, then the train is allowed to continue moving and locks the track. Other trains cannot cross the path it takes either.

When the train exits its covered path, the mutex zone is released.

This behaves similar to the smart mutex, except that it isnt in a cuboid zone but instead a distance from the start. https://wiki.traincarts.net/p/TrainCarts/Signs/Mutex#Smart_Mutex

Would this mechanic work for your situation?

amalon commented 11 months ago

I don't use discord, but I can see pmutex being useful (I've contemplated a similar thing myself), though I'm not sure it'd cover this case (though to be honest the waiter sign is a workaround for this case)...

It was a bit of an experiment to play with routes that kinda worked so I left it: junction

The trains on the orange line start at the top, go onto the bottom-right track, reverse into the platform to the left, then leave to the bottom right. Other trains enter the same platform from the bottom-right. The blue mutex region is needed to prevent the trains being blocked in the platform by other orange or red line trains. I don't think smart mutexes worked in this case since the trains change direction within the mutex, otherwise I'd just extend the mutex region to all the tracks. I had a waiter at the top left so that trains wouldn't enter the green mutex region unless the blue mutex region was clear at the time, but as it was configured it affected red line trains going to the top right, which ended up causing congestion due to the trains going really slow after the waiter.

pmutex would be useful there if it locked all mutexes along the track before entering the mutex region, as it could wait for the blue region, and lock it, and always get all the way into the platform without being stuck across the green region waiting for it to clear. It'd also have to be sure to release the pmutex once it goes into that platform and is off the track originally locked by the pmutex, even though still in blue mutex.

The other case I mentioned where a waiter prevents trains entering a terminus platform until it is clear, wouldn't work so well, as it'd lock the tracks that it crosses into the platform, preventing other trains passing while its in the platform.

I can see it being useful on lines before a junction, rather than having mutex regions for every fork when trains can come from multiple forks. (Could that be automatic? mutex signs under TCC tracks are a faff compared with signs on TCC nodes)

bergerkiller commented 11 months ago

If you name the 'pathingmutex' the same as the blue, they effectively become the same mutex zone, expanding it once the train is active inside. I think the current solution I have in mind will work for your situation. Station "forks" is exactly the use case I had in mind. Every fork can have a pathing mutex, and trains departing from the station will trigger the temporary mutex to become active once they get near enough, and are stopped if another train is currently intersecting with that path.

amalon commented 11 months ago

So something like this would work? junction2 red and orange = train routes green = switcher blue = mutex zone + pathingmutex with same name pink = pathing mutexes (could be same name i suppose, probably doesn't make much difference except making trains stop a little before fork)

blue pathing mutex gets trains into platform if its already clear, then allows pathing mutex to expire, so pink pathing mutex can be used by red line while its in platform.

Could the blue mutex for the platform be another pathing mutex? The other blue pathing mutex would probably have to see further pathing mutexes (i.e. the platform) on the route and lock them too.

Would the pink pathing mutexes be necessary?

bergerkiller commented 11 months ago

its something Ill have to test, its a little complicated because the pathing mutex only comes into existence once the train gets near enough to it. So im not sure whether or not it exists while riding on the square blue mutex zone.

The pink pathing mutex probably isnt needed. The blue pathing mutex locks the tracks, and that includes blocking other trains trying to cross it. If a train is already crossing the blue pathing mutex the train is stopped before entering it.

bergerkiller commented 11 months ago

https://github.com/bergerhealer/TrainCarts/assets/957601/220e20be-4aa0-47d4-bc2b-9810cf4d0c03

bergerkiller commented 11 months ago

Still working on:

amalon commented 11 months ago

Cool, do let me know when you're ready for testers! I'll just workaround waiter for now using launch after it.

bergerkiller commented 11 months ago

I've implemented a first version of the pathing mutex. Syntax is pretty similar to the normal mutex:

Args:

Third and fourth lines are the same name/statement as the other mutex signs.

Debug mutex command shows the path taken when a train is waiting/on it.

There is probably still some performance issues to work out, so it might be helpful to make a spark report for it too.

You can combine other mutex types with a pathing one (or have two pathing ones that intersect) by naming them the same.

Example signs:

[+train]
spmutex 64.0 3.0
acrossing

[+train]
pathmutex 32

image

https://ci.mg-dev.eu/job/TrainCarts/1485/

https://ci.mg-dev.eu/job/TrainCarts/1486/ Fixes non-working activation direction rules

amalon commented 11 months ago

Thanks, I've been giving this a try. I have a pathmutex that goes into a normal set of mutex signs (non-smart), all with the same name, but the train stops with the center on the pathmutex (unfortunately right across a crossing) instead of before entering that stretch of track. /train status says its approaching the mutex zone at the pathmutex sign. This is only a few blocks after a switcher sign. If I put the pathmutex before the switcher the train stop before the pathmutex sign, so I'm guessing the switcher is messing with it.

Is that an easy thing to fix?

bergerkiller commented 11 months ago

Can you make a screenshot of how this looks? The path finding should take switchers into account, but maybe its something else

amalon commented 11 months ago

2023-11-23_10 07 28

Train comes from the right, stops right over the "pathmutex 91 4\nHoganXP3"

bergerkiller commented 11 months ago

oh, youre using tcc signs. They dont really have a direction so theyre always active, no matter the direction trains come from. Since they trigger from a distance, that might be a problem. Try putting a specific direction, like [+train:north] pathmutex

You can see with /train debug mutex what paths are active

There might be other issues as Ive primarily tested with vanilla track

amalon commented 11 months ago

I tried [+train:sw] on the pathmutex, but it still stops right across the pathmutex sign (confirmed by /train status showing Waiting for mutex at that position)

bergerkiller commented 11 months ago

The mutex stuff is tightly connected to the rail block, so that entire stretch of track with that one node is seen as one. Try adding additional nodes inbetween to create a divider

amalon commented 11 months ago

Like this? 2023-11-23_10 29 13

That didn't seem to help.

bergerkiller commented 11 months ago

Can you show how it looks when a train is stopped? Then I have a clearer idea where trains are coming from / what the problem is

amalon commented 11 months ago

Here's the train stopped on it. The node with the pathmutex is selected. The train in the foreground is waiting for the train in the background which is in a similarly named mutex. 2023-11-23_10 34 09

bergerkiller commented 11 months ago

Im a bit at a loss, would it be okay if I join your server in, say, 5 hours from now to see if I can make sense of it? Theres some deep debugging I can do but thats difficult to do over github exchanges

amalon commented 11 months ago

sure, should be doable, feel free to email me when you're ready.

bergerkiller commented 11 months ago

I've added path prediction capabilities for the station route sign, as discussed on the server https://ci.mg-dev.eu/job/TrainCarts/1491/

Then you wont need that extra switcher sign anymore to have the train reversing work

amalon commented 11 months ago

cool, thanks. seems to work I think for me. Is it only stations marked "route" rather than an explicit direction that it'll work for? (not a problem, just curious)

bergerkiller commented 11 months ago

Yes, only routing stations. Didnt want to accidentally break people's existing layouts

bbayu123 commented 10 months ago

Closing - new feature added to provide workaround.