Arcade Quick Start

End-user guide for running the F1 StratLab arcade replay with the live strategy surfaces. Aimed at someone who has cloned the repository and wants everything on screen inside ten minutes.

One command launches everything. The arcade process owns the simulation loop and broadcasts merged state on a local TCP port; the follower surfaces subscribe and render.

One follower stack. PITWALL (two pywebview windows rendering React) is the whole strategy surface. The original PySide6 pair ran beside it through the migration so every PITWALL panel could be compared against the window it replaced while that window still existed; it has now been retired, along with the PySide6 and pyqtgraph dependencies. The comparison baseline is not lost with it: the Qt windows' rendered output is committed as screenshots under documents/dev_docs/migration/pitwall/. The pyglet replay is unchanged either way.


The arcade: 2D replay, strategy dashboard and live telemetry, all in sync. Recorded before PITWALL joined; the pyglet replay on the left is unchanged.

Prerequisites

One-command launch

From the repository root:

python -m src.arcade.main --viewer --year 2025 --round 3 --driver VER --team "Red Bull Racing" --driver2 LEC --strategy

What happens:

  1. src.arcade.main parses the CLI and opens the arcade Window.
  2. The --viewer flag skips the menu and goes straight to F1ArcadeView.
  3. The view loads the 2025 Round 3 (Suzuka) parquet for Verstappen.
  4. With --strategy set, the view starts a TelemetryStreamServer on 127.0.0.1:9998, owns a StrategyState, and spawns python -m src.pitwall.
  5. PITWALL opens PITWALL · DATA and PITWALL · AGENTS, two pywebview windows rendering React against the same broadcast, through a single shared TCP client.

The arcade window drives playback; every other window reacts to broadcasts. PITWALL additionally serves the same two pages over loopback, and prints the URL on startup, so they can be opened in a browser (and get devtools) instead of, or as well as, the windows.

What each window shows

Arcade replay (pyglet)

Track outline with the DRS zones drawn in green, two driver icons (our driver in team colour, rival in rival-team colour), a leaderboard on the right with compound pills and gaps, a weather panel, a driver-info strip, and a progress bar with the current lap.

PITWALL · AGENTS

Four strata, top to bottom: header, decision band, agent grid, status bar. The band runs left to right in the order a reader asks the questions, which is what the orchestrator is doing, why, on what evidence, and what happens next: the orchestrator card with its action badge and confidence bar, the reasoning panel, the scenario bars (STAY_OUT / PIT_NOW / UNDERCUT / OVERCUT, scored by the Monte Carlo over the agents' own distributions) and the plan strip.

Under it a grid places its cards by name rather than in reading order, because three of them want a shape reading order does not give them:

pace   tire   side
radio  exit   rag

side stacks Situation (N27) and Pit (N28); exit is the PIT EXIT card, which answers what position a stop taken on this lap rejoins in and which cars land either side. Pace (N25) and Tire (N26) carry embedded ECharts plots, and Radio (N29) and RAG (N30) dim when inactive.

PITWALL · DATA

A full-width status strip over two columns. Left: the twenty-row timing tower and the session bests. Right: a tab strip over TRACES (the own-car 2x2 telemetry grid, the track ring and the radio / RCM feed), RACE PACE (a lap-by-lap grid coloured by each lap's own ranking) and RACE TRACE (accumulated time against the leader, the field average or our own car).

Menu mode vs --viewer

Drop the --viewer flag and the arcade opens MenuView first:

python -m src.arcade.main --strategy

MenuView is a pure-keyboard navigator (Arrow keys + Enter, Escape to go back). It lists years (2023-2025), rounds per year, drivers, and teams. The --viewer shortcut exists for regression testing and for the "I know what I want" path.

Single-driver vs two-driver mode

Omit --driver2 and only the main driver renders on track and in the telemetry charts. The Delta trace in the telemetry window stays empty (no rival to compare against) and the Situation card focuses solely on safety-car probability.

Pass --driver2 LEC and:

Playback controls

Hotkeys handled by F1ArcadeView.on_key_press:

Key What it does
Space pause / resume
Left / Right hold to scrub backwards or forwards. Holding pauses playback; releasing restores whatever state was active before. Not a one-lap step
Up / Down next / previous playback speed
1 2 3 4 jump straight to 0.5x, 1x, 2x, 4x
R restart: back to frame zero, default speed, playing
D show / hide the DRS zones on the track
B show / hide the progress bar
A show / hide the eighteen non-featured cars
C show / hide the controls list itself
Escape close the window

Escape quits rather than returning to the menu, and it does so whether or not --viewer was used at launch.

The controls list collapses to a single C Controls line when the column above it has no room. The list needs 158 px, and the left column leaves 263 at the default 1280x720 whether one driver is followed or two, so the collapse fires only on a window dragged below 615 px tall. C opens the list anyway where it does not fit, on the grounds that a list you asked for is one you can dismiss with the same key.

The telemetry under the weather card is one table with a column per driver. It used to be a card each, which repeated the same six labels under two headers and took 354 px of the column for twelve values; at the default height that left 146 px against a list needing 158, and the list drew over the second card.

The window has no minimum size, and below about 475 px tall the table reaches the collapsed hint line. Nothing collapses further at that point. Before the table replaced the two cards the same crossing happened at about 652.

Known limitations

Troubleshooting

Symptom Likely cause Fix
FileNotFoundError: data/raw/.../laps.parquet the race is not in the local cache uv run python -c "from src.f1_strat_manager.data_cache import ensure_race; ensure_race(2025, 'Melbourne')", or just pick the race from the f1-strat menu, which calls the same function
"Backend offline" / "Connection refused" Arcade did not start the stream server Restart the arcade with --strategy
"OpenAI api_key missing" .env missing or OPENAI_API_KEY unset Add the key to .env, or F1_LLM_PROVIDER=lmstudio
PITWALL renders but charts stay empty First broadcast carries only the arcade frame Per-agent outputs arrive on the second broadcast
PITWALL needs its UI bundle on startup the React bundle was never built npm ci && npm run build in src/pitwall/ui

Related reading