Logs / Route 009
The bugs that didn't make a sound
A rescue helicopter that fell 135 km, force feedback sent into the void, and a test suite that passed because it gave up halfway. The worst bugs in this project never crashed anything.
Crashes are the easy ones. The game stops, there’s an error, it gets fixed and everyone moves on. The bugs that cost the most time in this project never crashed anything. The game kept running and looked fine, and somewhere underneath, something had stopped doing its job. These are the best ones so far.
The rescue helicopter that fell 135 km
Every time the game boots, even for an automated test, it restores parked vehicles and saves their positions every five seconds. The grass tests boot a small test world with no ground in the spot where the developer’s rescue helicopter was parked. So the helicopter fell, and the fall got saved.
The first time, it ended up 24 m below sea level. A day and a lot of test runs later, it was 135,572 m under the island, still falling at terminal velocity in five-second instalments.
The grass tests now get their own data folder. Giving every test the same treatment is still on the list.
Force feedback into the void
In September the steering was split into two parts: the angle the wheels point at, and the “feel” that comes through a steering wheel. The new feel code ran every frame and computed exactly the right force. Then it wrote that force into a field that nothing reads. The wheel reads a neighbouring field with a very similar name.
It only came to light because the old steering code, which was still quietly feeding the right field, was about to be deleted. Deleting it would have switched force feedback off completely, with no error and no failing test. The test that existed was checking that the feel was computed, which it was. It just never checked that anything was listening.
The physics rate that vanished
On 8 June, a commit that removed some debug logging also carried, unnoticed, an automatic rewrite of the project settings file by the editor. That rewrite dropped one line: the physics rate. The game quietly fell back from 90 steps a second to 60.
Nobody noticed for two months, because the cars still drove. What finally gave it away was an off-roader in low range on mud. At 60 steps a second its drivetrain oscillated so badly that it slowed down under full throttle, covering 9 m in a test where it should have done 29.
The game runs at 60 again now, but on purpose this time. And the value that gets checked is the one the game actually runs with, not the file that’s supposed to set it.
The steering that snapped
The new steering has a maximum turning speed for each car. For the first few commits after it went in, that value was never actually handed over, so it sat at “unlimited”, and every car’s carefully set steering speed did nothing. The wheels went from straight to full lock in a single frame. There’s now a test that checks it turns exactly one degree per frame at 60 degrees a second.
Inside-out walls
A triangle in 3D has a front and a back, and which is which depends only on the order of its three corners. Get it backwards and the triangle faces inwards. On most materials it simply vanishes. On double-sided materials it’s worse, because it stays visible but is lit from the inside, so it looks nearly right and nobody can work out why.
A stone parapet cost weeks this way. At one point an entire road deck didn’t render because every triangle was wound backwards. And the rule written down in the project’s own notes to prevent exactly this had the formula the wrong way round. It’s been corrected, and generated geometry is supposed to go through a single helper that works out the winding instead of trusting a fixed order.
The shock absorber that added energy
A damper is supposed to take energy out of a system. But simulate a stiff one in small time steps the obvious way and the maths can overshoot. The wheel’s damping step came out at a factor of −0.43, which means the wheel’s vertical speed flipped sign every sub-step. It rang like a bell instead of settling. The driveline’s damper had done the same thing a few months earlier. Both are now solved implicitly, which can’t overshoot however stiff the damper gets.
The test that passed because it gave up
This one hid the others, which makes it the favourite.
In GDScript, a runtime error doesn’t fail a test. It aborts the function it happened in and carries on. So a test suite whose subject broke halfway through reported only the checks that had run, all passing, all green. The proof: a single broken character in the lane-markings code took that suite from 79 checks to 75, and it still said PASS.
Since the end of August, a suite that runs fewer checks than it did last time fails.
The six weeks nobody could hear
Other players’ cars were completely silent for six weeks, because the values that drive tyre squeal weren’t being sent over the network. That one has a proper write-up in The car runs on the driver’s computer.
Looking back at this list, most of how the project tests things now exists because one of these got away first.
Filed under behind-the-scenes, bugs