Skip to content

devlog

Still following a finger that had gone

2026-09-11

The controls stopped working after five or ten minutes. Not on the first drag, which is exactly why it took so long to find.

Written while this is still in the working tree. It is being tested, not served.

The report was that the controls get stuck after five or ten minutes of playing. I had spent the previous day fixing controls that got stuck, so my first reaction was that I had not fixed them. That was wrong in a useful way: the earlier problem was a control that latched on a stray tap, which happens immediately or not at all. This one needed ten minutes. Same symptom, different animal.

A drag on a touch screen ends in one of two ways, as far as most code is concerned. The finger lifts, or the browser cancels the gesture and says so. There is a third way. The browser can simply take the gesture away, because it has decided the swipe belongs to it now: the back gesture at the edge of the screen, the notification shade coming down, a long press turning into a menu. When that happens the page is not always told. The finger is gone and nothing arrives to say so.

Our steering arc was then still following a finger that no longer existed. It holds one finger at a time, deliberately, so a second thumb landing on it mid-corner cannot snatch the wheel. Every touch after the theft looked exactly like that second thumb, so it ignored all of them, and sat at whatever angle it had last been handed. The car kept turning. Nothing on screen looked broken.

Ten minutes is roughly how long it takes to accidentally swipe the edge of a phone.

I did not want to guess at this one, so I built something that drives the real controls the way a phone does, including the endings a phone produces and a test never does: a cancel with no lift, a lift with no cancel, a second finger arriving mid-drag, the screen going away and coming back, and a gesture stolen outright. Forty rounds, and after every one it asks the only question that matters, which is whether the control still answers.

The first four endings were all handled. The deck was built carefully and it showed. The stolen gesture killed the steering on round five, and the arc never moved again, frozen at 0.31 of full lock.

The fix is two lines of intent. Losing the gesture is a release, so treat it as one. And when a new finger arrives while we believe we are already following one, check whether we really are before dismissing it. Both are the same admission: the thing we were trusting, that a drag we started is a drag we will be told the end of, is not true on a phone.

The buttons had it worse, and nobody had reported it, which I think is because it is harder to describe. Brake and boost are held rather than dragged, and a held button whose release goes missing is a car that brakes by itself with nothing on screen to let go of.

The part I want to keep is not the bug. It is that I had already written a fix for "the controls get stuck" that week, and it was a real fix for a real cause, and it was not this cause. A symptom is not a diagnosis, and the second report of the same sentence deserves the same suspicion as the first.