33Visual ReasoningAI Research

Vision-only TORCS Racing Bot

#ModelScoreStepsIn tokOut tokAvg costAvg time
1Claude Fable 5.1
0.2829
±0.075
457144.5M316k$78.8114.2h
2Qwen3.8-Max
0.0348
±0.043
48882.9M779k$34.0119.6h
3GLM-5.3
0.0343
±0.012
443182.6M353k$82.2219.0h
4Grok 4.6
0.0341
±0.050
544125.0M942k$151.4315.9h
5DeepSeek V4 Flash Exp
0.0277
±0.027
579216.4M447k$3.7417.4h
6Kimi K3
0.0270
±0.024
483146.1M383k$54.8819.8h
7GPT-5.6
0.0241
±0.054
29980.1M123k$76.2010.8h
8Inkling
0.0186
±0.022
24826.2M75k$25.151.8h
9Gemini 3.7 Flash
0.0128
±0.007
24647.9M237k$9.884.0h
10Muse Spark 1.2
0.0063
±0.007
32486.0M371k$41.4811.1h

Background

Driving a race car from pixels alone is a classic hard problem in embodied AI: the policy must infer speed, track position, and upcoming curvature from a single forward camera (no speedometer, no track sensors, no HUD) and turn that into steering, throttle, and brake commands fast enough to hold a racing line. Doing it on tracks the policy has never seen rules out memorizing any one circuit; the solution has to generalize.

The task builds on a patched, headless build of the TORCS racing simulator with a lock-step control loop: the engine blocks for the bot's action each step and runs faster than real time, so the agent can roll out thousands of episodes to hand-tune a controller, collect data, or train a model; the approach is entirely open.

Task

The agent must implement act(obs) in /app/bot.py: a policy that takes the camera observation and returns driving controls, completing laps as fast as it can, including on tracks it has not seen.

  • The only input is obs["frame"], a 480×640 RGB forward road camera image; speed, track position, and lap progress must be inferred from the pixels.
  • The bot returns steer in [-1, 1] plus accel and brake in [0, 1]; gear and clutch are automatic.
  • The camera publishes a new image every second control step (and the first frames are black), so motion estimation from pixels must account for the frame cadence.
  • An episode runs up to 21,000 control steps (~430 s of sim time); a crawling car reaches the step limit before finishing a lap. Each control step must return within ~30 seconds, including the first (model loading counts).
  • Module-level state and one-time setup (e.g. loading a trained model) are allowed; the policy may be hand-written, learned, or anything in between.

What The Agent Gets

A workspace at /app with the bot.py stub, a Gymnasium-style harness (game_harness) that runs the sim headless with reset/step/restart, a runner (python3 /app/run_bot.py), a minimal demo (harness_demo.py), a sample camera frame, and /app/README.md documenting the observation/control interface and episode rules. Five practice tracks are available in the sandbox (g-track-1, eroad, ruudskogen, aalborg, alpine-1); the evaluation tracks are not among them. The image preinstalls numpy, scipy, scikit-image, Pillow, OpenCV, and torch with torchvision, and the box has an A10G GPU for training. The machine is offline.

Verification

A clean-room verifier in a separate container restores the harness from a root-only pristine copy (keeping the agent's own files), unlocks two held-out tracks that never appear in the agent workspace (corkscrew and street-1) and races the bot 3 times on each, de-rooted as the non-root agent user with pixels-only observations. Scoring reads only root-written telemetry from the verifier's own harness, never anything the agent wrote.

  • A completed lap maps to a reward by piecewise-linear interpolation over five per-track lap-time anchors: 1.0 for superhuman pace, 0.8 for a skilled human, 0.6 for a published imitation-learning bot, 0.4 for this build's reference sensor-based bot, and 0.2 for barely finishing within the step budget. Street-1's human and imitation anchors come from published TORCS results; corkscrew has no published record, so its rungs are set from an internal reference lap. The 0.4 rung is measured on this exact build.
  • A DNF scores at most 0.2 times the fraction of the track covered, always below the completion floor. The final reward is the mean over runs, then over the two tracks.
  • A bot that fails to answer within the 30-second per-step cap is declared dead; the engine and all agent processes are killed before scoring. Harness faults mark the trial invalid rather than scoring the agent zero.

Environment

Base imageubuntu:22.04
Tools availableCUDA, PyTorch, C/C++ toolchain, Python 3
Compute8 CPUs · 16 GB RAM
GPU1× A10G
Time limit20h

References

  • TORCS (The Open Racing Car Simulator) (GPL-2.0-or-later (content: GPL-2.0 / Free Art License)): A trimmed TORCS 1.3.7 engine tree is vendored and built into the image. Non-free NFS3-derived car artwork, GIMP texture sources, and background music were pruned, so the image ships only GPL-2 and Free-Art-License content; the full license text is retained in the vendored tree.
  • SCR championship server (scr_server driver) (GPL-2.0): The Simulated Car Racing championship server patch for TORCS 1.3.7 (originally by Loiacono, Cardamone, and Lanzi), exposing the sensor/actuator interface the task's bot drives through.
  • pyTORCS-docker (No license published (only GPL-derivative patches retained)): Origin of the trimmed torcs/ subtree and three engine patches (main-menu skip, countdown removal, a shared-memory frame channel) plus pre-configured race XML. Because the repository publishes no license, none of its original authored material is redistributed: its README and Dockerfiles were removed; what remains is derivative work of GPL-2.0 TORCS, redistributed under GPL-2.0-or-later.