While reviewing the crossed-row gameplay path, we found another place where the engine could use the right information at the wrong moment.

Some gameplay rules need to know whether a panel was being held when a chart row crossed the receptors. The older path could answer that by checking whether the panel was held when the engine processed the row.

Most of the time, those moments are close enough to appear identical, however, they are not always identical.

If a frame arrives late, the engine may need to process several rows together. By then, the player may have pressed or released the panel after one of those rows had already crossed.

Using the current controller state could therefore apply a later input state to an earlier gameplay decision.

We have started separating those two moments.

For normal forward gameplay, OutFox now keeps enough input history to check whether the panel was held at the time the row actually crossed, rather than relying only on its state during the later frame that processed it.

This is particularly important for held-over-mine behaviour and other crossed-row rules. Those decisions should be based on what the player was doing when the event occurred, not what the controller happens to report several milliseconds later.

The older behaviour remains available where the newer evidence is not yet safe to use. Warps, seeks, reverse movement, autoplay and some legacy rules still need separate handling, so this is not being applied blindly across every path.

The change is deliberately focused on ordinary human gameplay moving forwards through a chart.

If a panel was held when the row crossed, the engine should recognise that, if it was pressed or released afterwards, that later state should not be carried backwards into the judgement.

It is another small part of moving gameplay decisions away from frame timing and onto the actual song timeline.