Skip to content
All work
Vantage app icon

VANTAGE·A 3D FORMULA 1 REPLAY

A replay should be a place, not a recording.

Vantage replays the 2024 Japanese Grand Prix as a 3D miniature: the whole Suzuka field on a tabletop, seventeen cars moving, and three cameras — drawn with Expo GL and Three.js, not played back from a video and not a WebView.

Role

Sole author

Stack

React Native · Expo GL · Three.js

Data

OpenF1 recorded sessions

Verified

Android release APK, on a Note 20

Race — the whole field at 01:33. Seventeen moving streams, recorded lap and timing, and ×N badges where projected cars overlap.
Race — the whole field at 01:33. Seventeen moving streams, recorded lap and timing, and ×N badges where projected cars overlap.
Follow — NOR through the hairpin. Drag to orbit, pinch to zoom; the selected car keeps its label and ground ring.
Follow — NOR through the hairpin. Drag to orbit, pinch to zoom; the selected car keeps its label and ground ring.
Battle — NOR and HAM in one frame. Group counts disclose overlapping projections rather than inventing lanes.
Battle — NOR and HAM in one frame. Group counts disclose overlapping projections rather than inventing lanes.
Timing — recorded order with gap or interval, last lap and source age. Sparse events are not inferred from the miniature.
Timing — recorded order with gap or interval, last lap and source age. Sparse events are not inferred from the miniature.
Lab — time-aligned speed traces plus speed, throttle, brake, gear and RPM at the shared cursor.
Lab — time-aligned speed traces plus speed, throttle, brake, gear and RPM at the shared cursor.
Return — returning from the background leaves the replay paused at the last cursor. Timing and telemetry stay available.
Return — returning from the background leaves the replay paused at the last cursor. Timing and telemetry stay available.

Screens

01 / 06

Architecture

How the system fits together

OpenF1 recordings → replay engine (one clock) → Expo GL scene (licensed circuit + 17 car projections) → three cameras; timing and telemetry read the same clock

The problem

A replay is a recording

Almost every replay app plays a video. A video is a picture of a broadcast: the camera is where the director put it, the field is a photograph, and nothing on screen can be checked against the timing. Scrub back and the picture changes; the race does not.

The data behind a race is not like that. Position, lap, gap and telemetry for every car are recorded, and they are all on one clock. So the question was whether the same data could be drawn as a place — a circuit you can look at, with the cars on it moving at the times they actually moved, and the numbers beside them.

The drawing is the easy half. The hard half is what the app is allowed to show when the data is thin. A 3D view is persuasive, and a persuasive view that guesses is worse than a table that admits a gap.

Competitive gap

What replay apps get wrong

Three habits run through the category, and each one gives up the same thing: the ability to check a claim.

Vantage is deliberately narrow. It replays one recorded race, on one circuit, and it is honest about the limits of what that recording contains.

ApproachWhere it fails
Video playbackThe camera is fixed, the field is a picture, and nothing on screen can be checked against the timing.
Charts of telemetryA speed trace knows the speed. It does not know where the car was when it happened.
Simulated racesA grid of cars on a made-up circuit can look convincing and mean nothing.
VantageRecorded positions on a licensed circuit plan, drawn live, with the timing on the same clock.

The views

Three cameras, one clock

The three cameras answer three different questions. **Overview** shows the whole field, so the shape of the race is visible: where the pack is, where the gaps opened. **Follow** stays with one car and can be orbited and pinched; the selected car keeps its label and its ground ring. **Battle** frames two cars together, and a group-count badge discloses when projected cars overlap rather than inventing lanes for them.

All three read the same clock. The scrubber is the replay; the cameras are views onto it.

CameraWhat it answersWhat it gives up
OverviewWhere is the race right now?Detail on any one car
FollowWhat is this car doing?The shape of the race
BattleWhat is happening between these two?Everything else

The data

Recorded, with the gaps left visible

The app replays documented OpenF1 recordings from the 2024 Japanese Grand Prix — position, lap, timing and telemetry for a 120-second excerpt.

The timing screen shows the recorded order with a gap or an interval, the last lap, and the age of the source. Sparse events are not inferred from the miniature: a timing screen that quietly invents a missing event is worse than one that admits the data is thin.

The lab screen puts the telemetry on the same clock as the cars — speed traces for two drivers, time-aligned, with speed, throttle, brake, gear and RPM read out at the shared cursor. The miniature and the numbers are the same moment, so a claim can be checked.

Returning from the background leaves the replay paused at the last cursor rather than jumping forward, and timing and telemetry stay available while it is paused.

The renderer

Drawn, not played

The native client draws the circuit, the field and the cameras with Expo GL and Three.js. There is no WebView and no video playback: the circuit is a miniature on an olive tabletop, built from editable Blender sources, with the cars as moving projections.

The renderer does 2× supersampling in the native target — an sRGB target, with a linear path and a direct fallback. On the test handset that cut the hard-step fraction from 0.640 to 0.298, so the visible stair-stepping on the track edges roughly halved. It also roughly doubles the measured GPU frame cost, and a hundred seconds of playback is 3.99% janky against 1.72% without it, so **60 fps is not claimed**. A 1.5× experiment traded sharpness for GPU headroom without a consistent jank win, and no adaptive mode is shipped.

Results

What is verified, and what is not

Everything claimed here was measured on a physical Samsung Note 20 5G running a release APK — not a simulator and not a mockup. Startup, camera-change and moving-field pixel gates pass as real GL-region comparisons rather than UI-only checks. The pacing figures, the overview framing fix and the supersampling are recorded in the repository's own validation notes, and `npm run check` runs the typechecker, the linter and 39 pure tests.

The honest part: the gaps are specific, and the repository lists them.

39

Pure tests

TYPECHECK · LINT · TESTS

0.298

Hard-step fraction

DOWN FROM 0.640

3.99%

Janky frames

OVER 100 SECONDS

Source · Samsung Note 20 5G, Android 13, release APK, 2× supersampling

Lessons

The pixels are the easy half

Drawing seventeen cars on a circuit in a GL context turned out to be the straightforward part. The part that took the work was deciding what the app was allowed to show when the data was thin.

A car crossing the line is a fact. A car in second place is a judgement the data has to support. So the group-count badge discloses overlapping projections instead of drawing lanes that were never there, the timing screen shows the age of its source instead of inferring sparse events from the miniature, and the miniature is never allowed to be the source of a number.

The second lesson was that a measurement you do not publish is a measurement you did not make. The render notes carry the hard-step fraction, the jank percentage, the changed-pixel counts from the camera sweep, and the 1.5× experiment that did not help — including the costs that were accepted rather than hidden.

A 3D view is persuasive. A number has to be true.

Still open

What is not established yet

No physical iPhone has run it

Simulator moving-replay presentation is a known Expo GL limitation. The iOS build exists, but no physical iPhone has run the app, so iOS device behaviour is not established.

60 fps is not claimed

2× supersampling roughly doubles the measured GPU frame cost. Sustained performance and thermals beyond the hundred-second aggregate run are not established, and no adaptive mode is shipped.

One handset, one race

The evidence is a single Note 20 and a single 120-second excerpt. A GPU-trace-level profile, p99 hitches, intermittent blackouts, ghosting, and any device beyond the one test handset are all open.

No store submission

The local APK is debug-key signed, not a Play Store artifact. There is no live-data integration, and commercial rights for a live feed are not cleared.

The circuit is illustrative

The plan geometry is MIT-licensed and the licence is preserved, but elevation, structures and scale are not surveyed. The replay uses documented OpenF1 recordings; it is not a live feed.

In short

What Vantage came down to

01

Drawn, not played

The replay is a live rendering of recorded positions, not a video. That is the whole difference between watching a race and being able to check it.

02

The view cannot invent

Where the data is thin the view says so: badges that count overlaps, timing that shows its source age, and never a lane the data does not have.

03

Publish the measurements

The jank, the hard steps and the failed experiment are in the repository. A claim about smoothness whose cost you cannot see is a claim you have not checked.

More work