Sheet 1 of 6 · Lights Out · Exploded assembly
Lights Out
F1 guide for newcomers
Specification
- Role
- Solo developer
- Stack
- TanStack Start, React 19, three.js, Blender, Effect, Cloudflare Workers, GitHub Actions
- Repos
- public · work in progress
- Drawn by
- Praffi Ramadhani
- Date
- 2026-11-07
- Status
- active
- Sheet
- 1 / 6
Overview
Lights Out is a fan-made web app that introduces Formula 1 to people who know nothing about it. It is not official and does not try to look official. It is a personal project, built for fun.
I fell in love with F1 watching Abu Dhabi 2021: two rivals level on points, everything riding on one last lap, fast and loud and impossible to call. The site tries to give a newcomer that feeling, then teach them enough to keep watching.
The problem
“Success means a newcomer leaves hooked and able to follow a race.”
A newcomer starts with zero knowledge, so no jargon can go unexplained, and a page that reads like Wikipedia loses them. Lights Out teaches through visuals, motion and interaction, with short captions, and follows the current season as it happens.
It also has to cost nothing to run: hosting, data, fonts and the domain.
A1 · Part 1 of 6
the pole lap
The weekend page’s circuit band replays the real pole lap at that circuit, in real time. It is the pole-sitter’s Q3 lap from Grand Prix qualifying, never sprint qualifying, with speed, gear, throttle and brake from OpenF1 telemetry. A lap clock runs, each sector box fills with its real split, and a wet pole is shown as it happened.
It updates itself. Within about an hour of a qualifying session ending, the new pole lap replaces the old one, so during a race weekend the band shows that weekend’s pole from Saturday night.
Lining the lap up
- OpenF1’s x/y positions are fitted onto the model’s lap line with a 2D similarity transform, mirror allowed, and each sample is projected onto the line.
- The lap is then warped in time through the sector cuts, so the car reaches each sector colour the moment its split shows.
- If the raw fit misses a cut by more than 3% of a lap, that lap is skipped and the stored one stays.
Pole lap · Lando Norris · 2026 São Paulo GP · Wet: 1:27.470, sectors 22.480, 45.874, 19.116.
A2 – A3 · Parts 2 to 3
the lap explorer
Each circuit with a model has its own full-screen page at /lap/<circuit>. There is no play button: a second after it opens, the camera swoops into a chase view and a light cruises the lap in about 48 seconds, slowing for corners. Any scroll, swipe or arrow key makes it yours, and it never takes control back.
Scroll is position, not push. About 14,000 px of scroll is one lap, and the light stops when your hand stops, with no momentum, settling onto a turn it stops near.
This season, at /season, is drawn from the live season snapshot: the title fight, a calendar of 23 Blender circuit tiles, the drivers’ and constructors’ championships, who led and when, and the next session’s countdown.
- A2 the lap explorer /lap/<circuit> · scroll is position
- A3 this season title fight · 23 circuit tiles · standings
A4 – A6 · Parts 4 to 6
the Worker
The site is TanStack Start on Cloudflare Workers, on the free workers.dev subdomain. It reads two things from Cloudflare KV: the season snapshot and each circuit’s pole lap, served at /api/season and /api/pole/<circuit>.
An hourly GitHub Actions job fetches the season from Jolpica and OpenF1, decodes every response with Effect schemas, and writes the snapshot. It writes a pole lap only when its session changed, so most hours write nothing. A failed lap is logged and keeps the stored one. It never fails the run or touches the season snapshot.
- A4 the Worker TanStack Start · Cloudflare Workers
- A6 the hourly job GitHub Actions · Jolpica + OpenF1 → KV
A5 · Part 5 of 6
the circuits
Everything that can be 3D is made in Blender. Each circuit is a bpy script that builds it from the bacinger/f1-circuits layout and NASA SRTM elevation, then exports a .glb that three.js renders through React Three Fiber.
The road is a raised ribbon in its three sector colours over the circuit’s real OpenStreetMap surroundings, baked once into a texture, with large buildings near the track standing up as low blocks. The glow is drawn without a bloom pass, so phones render no extra targets. Blender also renders a poster of each circuit from the same camera; it shows first, and it is what reduced motion and no-WebGL visitors get.
Five circuits are built: Interlagos, Las Vegas, Lusail, Albert Park and Yas Marina.
Key technical decisions
-
The pole lap, not the race's fastest lap.
The first spike replayed the race’s fastest lap with a hand-tuned alignment. The pole lap is more entertaining, and the alignment is now fitted from real positions, because the hand-tuned one was off by 2.8% of a lap on Las Vegas.
-
No live timing.
The only real source, OpenF1’s live tier, costs €9.90 a month and is licensed for personal use. The site has to cost nothing, so live timing is dropped for good, and the season updates within the hour after each session instead.
-
Built once, then data.
Nothing is modelled or rendered per race or per season. Each circuit’s model is built once and rebuilt only when its layout changes; what the scenes show comes from the data.
-
No copyrighted media.
No race footage, official photography, team logos or liveries, and no official typeface. Photos come from Wikimedia Commons with their credits, the map is credited to OpenStreetMap, and driver names are text only.
Current status
In progress.
Live at lights-out.prafficoding.workers.dev. Built so far: Home, This season, the race weekend page with the pole lap, and the lap explorer. Still to come: How F1 works, the car, the engine, the tracks, the people and the glossary.