In part one my GTR2 replays got their 1990s TV graphics. Part two added a TV director, part three a modern look and my old league nights, and part four took the graphics live, onto a race while I drive it.
All of that still needed me. I had to start the replay, press record, stop the recording, find the file, upload it, write a title and link the video to the race on this site. Over the last two weeks FDTV learned to do every one of those steps by itself. It now takes a folder of old replays, plays them one after another with the director at work, streams each race to YouTube, writes the titles, sets the thumbnails and chapters, and links every video to its results page here. Nobody has to be in the booth.
Interlagos, 6 November. I raced it live at 20:43, streamed as I drove; at 21:28 FDTV was directing and streaming the replay, and by the end of the evening both videos were on YouTube and on the race's page here.
Moving into the game PC
Until now, FDTV lived on my home server and reached into the game PC from outside. That made sense while it was an experiment, but everything on air depended on a second machine being up, and every fix I tested went straight to the copy on air.
So FDTV moved into the game PC itself, in a small container that starts with Windows. The home server became the test bench: I change things there and try them on old races, and when a change is approved it ships with a single command, which also restarts everything that needs restarting: the companion, the director's page, the see-through window over the game and the OBS sources. Testing and broadcasting no longer share a copy, and a bug on the bench stays on the bench.
The game presses record
Part four found where GTR2 keeps the race. This time we looked for where it keeps itself: whether a track is loaded, whether I am driving, sitting in the garage menu or back in the main menu, and whether a replay is playing and which one. With those few values, the companion that runs next to the game knows what I am doing without being told.
When I first drive out in a session, OBS starts recording, and the file is named after the track and the time instead of OBS's own date and number. When I go into the garage, the recording pauses; when I drive out again, it carries on. When I quit to the main menu, it stops. When I open a replay, FDTV picks that race on every screen by itself, and if it has never seen that replay, it imports it first and then picks it. Replays I save while playing are filed away afterwards into "to record", "archive" or "failed", once the game is closed.
One lesson from that week: OBS answers "recording started" before the recording has actually started. Swapping in my file name and putting OBS's own setting back straight after the answer silently undid the rename. The fix was to wait for OBS's own event that the recording is running, and only then tidy up.
From OBS to YouTube, without me
Thirty seconds after FDTV stops a recording, the companion hands it over to n8n, the automation tool that already writes the race reports on this site. Everything after that happens in n8n, where I can watch every step and see exactly where something failed:
- The race's log goes to this site and is imported, unless the site already has that race. A video never re-imports a race.
- The site writes the title and the description from its own data: the championship and round, the track, the full results and a link back to the championship here.
- The video goes up to YouTube. Replays are public; live sessions go up unlisted.
- The thumbnail is a screenshot OBS took five seconds after the start. The chapters (pre-race, start, every lead change, the biggest pit stops, the chequered flag) come from FDTV's own data, on the video's clock.
- The video joins its championship's playlist, created the first time it is needed.
- The video's id is saved on this site, so it appears on the race's results page.
The whole chain. The companion only hands over the file; every decision after that is visible in n8n.
A two-hour race recorded in 2560 by 1080 is a big file, so the first test was whether n8n could carry one at all: a 6.5 GB recording went up in a single piece while n8n used about 0.6 GB of memory. YouTube's daily upload allowance is the real limit. When it runs out, n8n waits for the reset and carries on, and my phone gets a message. In two weeks the workflow has finished 327 jobs.
Going live, and the broadcast that was always one late
Recording and then uploading means waiting for the race to end. Streaming means the race is on YouTube while it runs, so FDTV can now do either, with streaming as the default. At Go live, n8n prepares a YouTube broadcast on my channel's stream key, OBS starts streaming, and when the stream ends n8n gives that broadcast its title, description and chapters, the same as an upload.
YouTube made us earn it. One crashed test left a broadcast "ready" but never used, and YouTube feeds a stream to the oldest ready broadcast on a key. From then on every stream landed one broadcast late, with the previous race's title on it and the wrong video linked on this site. Now every Go live clears out leftover broadcasts first.
A week later OBS refused to start a stream, and the companion asked for a new broadcast on every tick: about 80 broadcasts in eight minutes, until YouTube stopped answering for the day. Now there is one broadcast per session, three tries to start, and a backup recording that runs from the first second. As soon as YouTube confirms the stream is live, the backup stops and its file is deleted; if YouTube never confirms, the backup keeps going and goes up as a normal video at the end. A race never goes missing because a stream did not start on time.
The cars that sank
Replays recorded on a dedicated server, where my league races were held, had always looked a little wrong: the cars sat in the tarmac, wheels half buried, and bounced as they drove. The server only sends each car's position a few times a second, and in between the replay lets gravity pull the car down, a little further on every frame.
The fix reads the track itself. GTR2's track files mark which surfaces you can drive on, so for every car we know where the ground is under it. The car's first record, on its grid slot, says how high that model rides above the ground. From then on, any reading below that height is lifted back onto it, and any reading above it, a kerb hop or a jump, is kept. GTR2 plays the edited replays without complaint, and all 73 server replays in my archive now have their cars on the road.
Nobody in the booth
With record, upload and stream automatic, the last manual step was starting the replay. The replay queue is now just a folder. The companion takes the first replay, copies it where GTR2 looks, starts GTR2, brings it to the front (it never does that by itself), clicks through the menus with the same invisible buttons the director uses, opens the replay and presses Go live. The director takes the cameras, OBS streams, and when the closing graphics end, the companion stops everything, closes GTR2, files the replay as recorded and starts on the next one. GTR2 is restarted for every race: twenty-year-old games do not enjoy running for twelve hours.
The first full day of the queue, 30 October: 16 of the 17 races it started on its own between 07:49 and 20:17, each a thumbnail taken five seconds after the start.
An unattended station has to fail gracefully, and the first days showed how. A race with a car file the game could not load crashed GTR2: after two crashes a replay now goes to a "failed" folder, and the queue moves on. Once, an error in the director's page stopped it mid-race while its heartbeat still said "alive", and GTR2 looped the same replay on stream for three hours. Another time, Docker's virtual machine died under the container, the page that tells OBS to stop was gone, and a Daytona replay streamed for three hours too. Now the page catches its own errors and reports them, and a watchdog in the companion stops a stream when FDTV's server has been unreachable for three minutes or GTR2's replay clock has stood still for five. The queue reports to my phone, and a failure comes with a screenshot of the whole screen.
Hot laps
Hot laps go through the same queue: a single lap, its own lap card and timer, recorded or streamed and uploaded to a "Hot Laps" playlist. The first hot-lap run streamed 14 of them back to back; FDTV now holds 135. Each one compares itself to the lap it has to beat, sector by sector, so the reference had to come from somewhere: the live session I drove, if FDTV saw it, else the full session replay, else the race log or this site's lap times.
A hot lap at Interlagos in Grip Racing number 84: 1:25.385, 0.682 seconds under the reference.
The sector times taught us something about GTR2. For replays, FDTV places the sector lines where the track's AI path says the sectors change. The game itself times sectors at separate markers in the track file, and at Interlagos those sit 20 and 35 metres earlier: enough to make a replay's first sector 0.27 seconds slow and the second 0.63. When FDTV has the live session, it now uses the game's own split times.
Smaller things on screen
Not everything was automation. The graphics kept growing too:
- Multiclass. Races with GT1 and GT2 cars together show each car's place in its class, class leader cards, and standings and predictions per class.
- A preview and a championship for live races. At the first session of a weekend, FDTV shows the event preview with the race distance, and picks the championship the race belongs to, so the live prediction and the provisional standings at the flag are right.
- The running order ticker. The classic display got a ticker along the top: every car's place, number, name and gap to the leader, scrolling at the pace of a real broadcast, 10.25 seconds a crossing.
- Race chapters on every replay video, from the start to the flag.
- Numbers that stand still. The broadcast font had no fixed-width digits, so times shifted every time a 1 went past. A variable version of the same font fixed every number on every graphic at once.
The ticker at the A1-Ring (today's Red Bull Ring), a 2012 league race replayed by the queue on 3 November.
And one for the driver: a delta bar. Under the mirror, a bar grows left or right with how far I am behind or ahead of my best lap of the session, green while I am gaining time and red while I am losing it, with the number underneath. It works like the one iRacing drivers know. GTR2 keeps no such number, so the reader traces every lap I drive, a hundred times a second, and compares me with my best lap at the same point on the track.
Curitiba, today, live: leading on lap 3 and 1.13 seconds up on my best lap. XD's own delta in the top-left corner says 1.136.
Here is a whole race from the queue, as it went out: a league round from 2012, replayed, directed, streamed and titled with nobody at the controls.
Everything else is on my channel's playlists, one per championship, plus the Hot Laps.
Next
FDTV was built for one game PC, one home server and one person's habits. The next step is a version other GTR2 players can run: the graphics, the director and the live timing, without my network, my n8n and my site behind them. More on that when it is ready.
Results and learnings
- FDTV now runs a whole broadcast by itself: a folder of replays in, directed races and hot laps out, on YouTube and on this site, with my phone told when something goes wrong.
- Live sessions record or stream themselves from the moment I drive out, and stop when I leave.
- Every external system answers before it acts. OBS says "started" before it starts, and YouTube says "ready" for a broadcast that will swallow the next stream. Wait for the event that proves it happened.
- Automation multiplies mistakes as well as work: one retry loop made 80 broadcasts in eight minutes. Every automatic action needs a limit, and every stream a backup.
- A heartbeat must come from the thing it vouches for. The director's page looked alive for three hours while the part that does the work had stopped.
- Keep the decisions where you can see them. With every step after the recording in n8n, a failure is a red box with its reason, not a guess.
- Read the game's own files before guessing: the ground under the cars and the real sector lines were both in the track files all along.
As in every part, this was built with Claude as my pair programmer. I decided what the station should do and how it should behave when things go wrong, and drove the test sessions; Claude found the game's states in memory, built the queue, the n8n workflows and the fixes, and read the logs of every night that went wrong.
For fifteen years my old league races sat on a hard drive as replays nobody would ever watch again. Now a machine in the corner wakes them up one by one, puts them on air, and files them away, like a TV station working through its archive overnight.





