DRIFTIT

Devlog

Building a drift game in the browser

DRIFTIT is a top-down drift game in the spirit of Absolute Drift that runs in any desktop browser. Here is how it works under the hood: a car model written from scratch, twenty tracks made of arcs and straights, worlds with no texture files, and a trailer that was never screen-recorded.

The trailer: every frame is rendered by the game's own renderer from recorded runs of its real physics.

The stack

Plain JavaScript, three.js for rendering, Vite for the build. No game engine and no physics engine. The whole game (physics, rendering, menus, audio, leaderboard client) is a few thousand lines of code, and it loads as a single page. The leaderboard is a small Node server with SQLite.

A car that wants to slide

Rigid-body engines are built for realism, and realistic cars are hard to drift with a keyboard. So the car in DRIFTIT is a pure, deterministic 2D model: no Math.random, no clock, the same inputs always give the same run. That one property ended up paying for itself many times over (more below).

The model has two virtual contact patches, one per axle. Each step, the velocity is split into forward and sideways parts in the car's frame, and each axle answers with a sideways force that grows with slip and then saturates at a grip cap. The trick is the rear axle: its cap is multiplied by a smooth traction state that goes from "hooked up" to "sliding" and back with some hysteresis. That makes a drift a state rather than a moment: once the rear lets go it stays loose until you straighten up, which is exactly the feel you want.

On top of that:

  • Power oversteer: throttle steals rear grip, so the gas pedal holds and grows the angle.
  • A "sliding puck" handbrake: the locked rear gets simple kinetic friction and almost no sideways grip, so a flick at any speed rotates the car instantly.
  • A counter-steer assist that only fades in while sliding: the front wheels lean towards the direction the car is actually moving, so your steering input works relative to the slide. That is what makes it drivable on digital keys.
  • Sub-stepping at 240 Hz, so a 60 Hz and a 144 Hz screen drive identically.

We did not get there in one go. Several candidate models were written and put through the same numeric "feel" tests (how fast does a handbrake flick rotate, does releasing the steering straighten the car, can you hold a steady angle at part throttle), and the final model took the best parts of each. Those tests still run on every change to the car.

Tracks from arcs and straights

Every track is a chain of segments: a straight of some length, an arc with a radius and an angle. One or two straights are marked "solve", and their lengths are computed so the loop closes on itself. From that chain the game builds the centreline, the walls, the checkpoints and the start line. A new track is about ten lines of data.

The target times were not guessed. A pure-pursuit bot drives every track with the real car physics, and the target is its lap time × three laps × 1.25. Because the physics is deterministic the bot gives the same answer every time, so a track change shows up immediately as a number.

You can see every track's corner list on its guide page, like the Spiral, whose radii shrink from 28 m to 13 m corner by corner.

Worlds without textures

There are six worlds: a meadow circuit, a red-rock desert, an autumn valley at golden hour, a snowy pass and a neon harbour at night, plus an airfield playground. None of it uses a texture file. Grass, sand, snow and concrete are procedural; the kerbs, barriers, grandstands, trees, cacti, containers and cranes are built from the track data at load time. At night, lamp posts and floodlights are baked into a light map that the ground, barriers and props sample, and the car switches on projected headlight beams.

The only model is the car itself, from Kenney's CC0 car kit, split by colour into paint, glass, chrome, tyres and lights. Everything then goes through a small HDR pipeline: bloom, AgX tone mapping, a colour grade per world and a vignette. When frames run long, the pixel ratio steps down first, then bloom, then the post chain.

Smooth on a 60, 144 or 240 Hz screen

Physics runs at a fixed 120 Hz, but screens do not. Drawing the latest physics state means the car moves 0, 1 or 2 steps per frame and visibly trembles. The fix is classic: the car is drawn between its last two physics steps, interpolated by how far the clock is into the next one. Races are drawn on every refresh up to about 165 Hz; menus are capped around 60 fps to keep laptops quiet.

A ghost in 20 KB

Your best run on each track is saved as a ghost: the car's pose sampled 20 times a second, about 11 to 25 KB per track, kept in the browser. The next run replays it as a translucent car, and at every checkpoint the HUD shows your split against it. It is the single best feature for getting faster, because you can see exactly which corner cost the time.

A trailer rendered from code

The trailer at the top of this page was never screen-recorded. A "stunt driver" script drives the real physics: every 0.05 s it tries about fifty short plans (hold a drift left, flick in with the handbrake, grip along the edge) on snapshots of the car and keeps the best. The takes are saved, and a renderer replays them through the game's own graphics in headless Chrome, frame by frame at 60 fps with motion blur from eight sub-frames each. The music is one of the game's songs, and the lap chimes are synthesised in the song's key, just like in the game.

What's next

More tracks, more worlds and better tools for chasing times. If you want to see how it drives, it takes ten seconds to start:

Play DRIFTIT free

And if you are new to drifting, start with how to drift with a keyboard.

Ready to slide?

Free, in your browser, no download. Keyboard or gamepad. Also on Steam for Windows, Mac and Linux, $4.99.