There is rule 39 stating that if the next signal in the same box is closed, then the train must come to a near halt before the signal is cleared.
And there is rule 5 (warning arrangement) stating that if the overlap beyond the home signal at the next box is not cleared, then the train must come to a full stop at the box in rear (or the starter there) and the driver be informed about the fact. For RW purposes, I left it at the full stop at the starter since you cannot trigger messages boxes in signal scripts.
Now if the overlap beyond the starter is not clear (which is a rare case) and a train approaches the home signal of that box, should we demand a full or a near stop? I opted for the full halt, but later forgot that I did.
Then during testing, I piped a bunch of AI trains through the station like I always do. And of course, these test layouts are always condensed to reduce travel time in order to reduce testing time. So a train ended up within the 400 m mark beyond a starter and another was brought to a near halt at the starter, but that one would not clear. I searched my scripts far and wide to find that bug, until I found it was a feature. My bad not to bring that train to a full stop.
Lesson learnt was to remove the feature and perform rule 39 even if the overlap beyond the next signal is occupied. If I don't read my own documentation often enough to remember all the tiny bits, who will?
Two fun facts about RW that are not exactly my fault but caused their share of wasted time nonetheless.
1) I knew that AI 'jerks' when passing signal links, that means that speed is reduced for split seconds in a insane way. I did not know that reverse movements occur as part of such episodes. Until I tested signals that clear automatically for unexpected trains (but not for trains in the reverse direction, like Kuju did). Only when you do that on a single line and on a dense layout, you will find single time slices (i.e., single calls to OnConstistPassed) where a train that is supposed to do 20 mph moves up to 35 mm into the opposite direction.
It resulted in randomly clearing signals for no apparent reason, which only happened if the insane jerking occurred in the monitoring zone of 200 m or so, near the signal. However, the jerking is nearly as fixed as all AI movements, so once it happens, it will happen in the majority of test runs, leaving you to wander what the hell of a bug you introduced into this specific signal that clears with absolutely no reason.
2) I knew that the AI dispatcher changes the switch for the next train as soon as the numbered link is cleared by the first train. I was not aware of the fact that the JUNCTION_STATE_CHANGE message is sometimes sent out to signals (by calling their OnSignalMessage function) before the OnConsistPass functions of all signals are called for the same time step.
So what happens is that for time step X, the dispatcher sees that the link is clear and starts changing the switch. This causes messages sent out to the signals concerned. After these messages are digested by these signals, the game calls OnConsistPass for all signals near, still at the same internal time X.
The naive view of the signal is first that the switches are changed while the train is still on them and then (some milliseconds later in real time, at the same time step in simulation time) that a disconnected link was cleared (which is more or less ignored in the normal case).
The funny thing is that this issue does not occur in many cases as the dispatcher waits five seconds before setting the path for another train, for the same direction. But for the return of the same train via the other track it did not wait in my case. Again I have seen it before that the dispatcher changes switches insanely early. But changing it before giving notice that the link is cleared was a first for me.
In both cases, yet another state variable to monitor what the game is about to do overcomes the problem.