Skip to content

The right guard, one phase too late

Topicscrash, physx, diagnosis, correction

Last week’s entry ended on a bet: the fix is deployed, nobody has played a game on it, and if the crash comes back the theory is dead. It came back on 1 September at five past ten at night, seven minutes into the session, at the same address in the physics engine as three crashes before it. So the theory is dead. This is what killed it.

The check itself was not wrong, and it stays in. Before touching a car we now ask the world whether that car is still attached to it, instead of asking the script whether its handle on the car still exists. Those are different questions, and only the first one tells you anything about the physical body you are about to read. What was wrong was where I put it. All six places I wired it into read the car during a pursuit. And the player’s own report said the crash hit the moment he entered the call radius, which is before there is any pursuit at all. I had fitted the guard downstream of the damage and then waited for it to catch something upstream.

That is the third time in two days the bug has had this exact shape, and it is worth naming, because it is never the shape I expect. It is never missing code. It is a correct guard wired into just one of the several places that needed it. One helper had five callers that needed the guard and one that had it. Another had two and one. This one had seven and one. Hunting for that pattern, a guard at one caller out of many, has paid better this week than looking for anything new.

So the new suspect is the arrival, and in particular the one call in that phase that moves a body by teleporting it: putting the suspect in the driver’s seat of a car that may still be loading in. That call ran six tenths of a second after the game signalled the spawn, on a car and a suspect looked up by tag and checked with the weaker of the two questions. Exactly the mistake above, one phase earlier. It now asks the real question: about the car, about the suspect, and about whether either of them is still in the middle of spawning.

It also retries instead of cancelling, which matters more than it sounds. Those six tenths of a second were a fixed wait, not a confirmation of anything. Simply refusing to seat him when the two are not ready would have swapped a crash for a callout that dies silently, and that is a worse bug, because nobody reports it. Now it tries four times across three seconds before giving up.

And I have to be honest about what the following night proved: nothing. The game did not crash, but the game’s own spawner accepted the car on the first attempt, so the path this fix lives on, the fallback for when that first attempt fails, never ran. Not crashing is no evidence that a guard works when the guard never ran. To test it I have to force that fallback path on purpose.

Two smaller things came out of the same session, both about the log rather than the game. The telemetry file writes nothing to disk until the game exits cleanly: zero bytes during play, forty-five kilobytes a few seconds after quitting through the menu. So every crash takes the end of its own record with it, and the only session you can read is one you ended yourself. And a sentence from last week has to go. I wrote that all ten calls I had wired with log lines closed cleanly, so none of them was the killer. True, and meaningless: of the eighteen breadcrumbs in the log, only one was on the arrival path. I had cleared a suspect I never questioned.