Games › Dev log

APEX: rain, reflections and thirty-three circuits in a browser

· 5 min read

APEX is the biggest racing game on PLAYPILE: a low-poly Formula 1 game with thirty-three circuits, tyres that wear, pit stops, damage and weather. The full version reached the site on 22 September, and a handling fix followed on the 23rd. This post covers the circuits, the rain, and keeping the car from spinning.

Circuits: describing them did not work

Our first approach to the tracks was the one that sounds sensible. Every real circuit has a published corner sequence: a straight of this length, a right-hander of that radius, and so on. We wrote each circuit as a list of straights and arcs and solved the list until the lap closed.

The laps did close. But Spa and Monaco each ran through themselves twice, and Suzuka crossed itself twice where the real circuit crosses once, on a bridge. Before solving, hand-written laps missed closing by one to four kilometres, and Spa ran anticlockwise because La Source had been written down as a left.

So the circuits are now surveyed rather than described. The centre lines come from the open f1-circuits map data, projected into metres. Each survey is a few hundred points, which we run through a smooth curve, resample, smooth again and scale to the circuit's published length. Smoothing mattered: the raw curve measured Monza's tightest corner at 10.7 metres, tighter than the Monaco hairpin.

What a survey does not know is still written by hand: the track width, the start line, the corner names and the grandstands.

Check a lap by its corners, not its shape

A lap drawn backwards looks exactly like the right one from above. Two files in the data ran against the race direction. Marina Bay's first sector read right, right, right, when it should be left, right, left hairpin, and Paul Ricard turned left twice after Signes, where the Beausset is a double right. Both are reversed in code, and every circuit was checked by its first corner, its hairpins and its longest straight.

One bridge

Suzuka is the only circuit where the road crosses itself. The build finds the crossing and raises one road 7.5 metres on 180-metre ramps, a 4 per cent grade, with a deck, girders and piers placed clear of the road beneath. Our first version of "which part of the road is the car on" used distance alone, so a car passing under the bridge got placed up on it, 2.4 kilometres round the lap, inside the walls. Height is now checked first, then continuity with the previous frame.

Rain is two numbers

The weather can be dry, changeable, light rain or heavy rain. Underneath, the game tracks two separate values. One is how hard it is raining. The other is how much water is on the road, and that one lags behind the rain in both directions. A shower does not soak the track instantly, and the track does not dry the moment the rain stops. The tyres only feel the water on the road.

That shows up in the tyre choice. Slicks start losing grip to aquaplaning once the water passes 0.35 on a 0-to-1 scale. Each of the five compounds has its own grip curve: soft 1.035, medium 1.0, hard 0.97, intermediate 0.90 and full wet 0.82. In the dry the wet tyre is far slower. In standing water the slicks are the ones in trouble. A medium lasts about six laps of Monza.

Reflections that are actually reflections

The wet road reflects the world, and it is a real mirror rather than a painted shine. A second camera, mirrored under the road surface, renders the scene at half resolution. Only the road materials look at that image. In puddles they read it sharply, at a roughness of 0.04, and the reflection wobbles with rain ripples. On merely wet tarmac they read a blurred version, at a roughness of 0.32, which gives a sheen rather than a mirror.

Puddles come from two scales of noise, with a water level that rises through them as the road gets wetter, so small puddles appear first and join up. Spray appears once there is real water down and a car passes 12 metres a second, thrown up from the rear wheels out of a pool of 1,400 particles.

A mirror means drawing the scene a second time, so it is kept cheap. On a dry road it is switched off completely. The twenty thousand or so grass tufts are hidden from the reflection, and shadows are not recalculated during that pass.

The car that kept going round

A racing game lives or dies on how the car feels at the limit. Our test bench passed throughout, and the car still spun. The bench only measured slip flat out in fourth gear, and the spins happened elsewhere. A probe that tried other situations found two: 169 degrees of slide when putting the power down out of a slow corner, and 92 degrees when lifting off mid-corner.

The first round of fixes softened the shape of the tyre's grip curve, and added traction control, a taper on engine braking and stability control. The worst case fell to 8 degrees. That was not the end of it, so the car now also has a hard limit. A racing car at the limit runs six to ten degrees of slip. APEX now lets the car get up to 22 degrees sideways, which leaves room to feel it move and to catch a slide, and takes away the part where it keeps going round. Above 8 metres a second, if the car passes that angle it is pulled back to it, and the rotation that was taking it there is cut to 35 per cent.

Bugs that threw no errors

Some of APEX's worst bugs produced no error message at all, only a wrong picture. For a while the whole racing surface was culled from view, and the car drove on grass with the tarmac invisible beneath it. The car was buried to its axles. The steering wheel turned the wrong way. Tyre wear was taken once per physics step instead of being scaled by time, so tyres went bald in under a lap and every computer car crashed on every circuit. A lap-by-lap test caught that one. The bench, which only ran short tests, did not.

That is the lesson we keep relearning with APEX: a test only answers the question it asks. The useful tests were the ones that drove a whole lap, or a whole race, and counted what went wrong.

More from the dev log