Skip to content

beamuu/f1-telemetry

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

F1 Telemetry Logger

A simple Rust application that captures F1 25 game telemetry data via UDP and outputs it as JSON logs in real-time.

Features

  • 🏎️ Captures F1 25 UDP telemetry packets
  • 📊 Parses common telemetry header fields
  • 📝 Outputs structured JSON logs
  • ⚡ Async UDP handling with Tokio
  • 🛠️ Configurable interface and port
  • 🎨 Pretty or compact JSON output
  • 🛑 Graceful shutdown with Ctrl+C
  • 🧪 Optional raw hex packet dump (--raw)
  • 🎯 Packet filtering by ID (--filter 6,14)
  • 🗂️ Per-lap directory logging (--laps-out telemetry_laps/)
  • 🔍 Structured body parsing (CarTelemetry + TimeTrial so far; others fallback to unsupported)

Quick Start

Prerequisites

  • Rust 1.75+ installed
  • F1 25 game with telemetry enabled

Build and Run

# Build the project
cd f1logger
cargo build --release

# Run with default settings (listens on 0.0.0.0:20777)
cargo run

# Run with custom settings
cargo run -- --iface 127.0.0.1 --port 20777 --pretty

Command Line Options

  • --iface <IP>: Interface to bind to (default: 0.0.0.0)
  • --port <PORT>: Port to listen on (default: 20777)
  • --pretty: Enable pretty-printed JSON output
  • --filter <list>: Comma-separated packet IDs to keep (e.g. --filter 6,14)
  • --raw: Log raw packets (header parsing skipped) with rawHex field
  • --laps-out <dir>: Enable per-lap logging; writes one folder per lap with per-packet files

F1 25 Game Setup

  1. Open F1 25 game
  2. Go to SettingsTelemetry
  3. Enable UDP Telemetry Output
  4. Set:
    • IP Address: 127.0.0.1 (for local capture)
    • Port: 20777
    • Send Rate: 60Hz (recommended)

Example Output

Compact JSON (default)

{"ts":"2025-09-02T10:30:45.123456789Z","src":"127.0.0.1:54321","bytes":1464,"parsedHeader":true,"packetFormat":2025,"gameVersion":"1.25","packetVersion":1,"packetId":6,"packetName":"CarTelemetry","sessionUID":12345678901234567890,"sessionTime":123.456,"frame":7890,"playerCarIndex":0}

Pretty JSON (with --pretty flag)

{
  "ts": "2025-09-02T10:30:45.123456789Z",
  "src": "127.0.0.1:54321", 
  "bytes": 1464,
  "parsedHeader": true,
  "packetFormat": 2025,
  "gameVersion": "1.25",
  "packetVersion": 1,
  "packetId": 6,
  "packetName": "CarTelemetry",
  "sessionUID": 12345678901234567890,
  "sessionTime": 123.456,
  "frame": 7890,
  "playerCarIndex": 0
}

Packet Types

The logger recognizes these F1 telemetry packet types:

ID Name Description
0 Motion Car motion data (position, velocity, acceleration)
1 Session Session and track information
2 LapData Lap times and sector data
3 Event Race events (penalties, retirements, etc.)
4 Participants Driver and team information
5 CarSetups Car setup configurations
6 CarTelemetry Car telemetry (speed, throttle, brake, RPM, etc.)
7 CarStatus Car status (fuel, ERS, damage, penalties)
8 FinalClassification Final race classification
9 LobbyInfo Multiplayer lobby information
10 CarDamage Car damage information
11 SessionHistory Session history data
12 TyreSets Tyre compound and usage data
13 MotionEx Extended motion data
14 TimeTrial Time Trial ghost / delta data sets

Currently implemented body decoders: CarTelemetry (6) and TimeTrial (14). Other packet IDs are emitted with packetName but body content is not yet expanded (appears as unsupported in per-lap body logs). Raw mode (--raw) bypasses all decoding.

Lap-Based Logging

When --laps-out <dir> is provided the logger creates a hierarchy like:

telemetry_laps/
  silverstone-2025-09-02T10-30-45Z-lap-1/
    CarTelemetry.log          # JSON line records (one per packet) with headers + summary
    CarTelemetryBody.log      # Detailed parsed multi-car body (if implemented)
    TimeTrialBody.log         # Time Trial data (if present)
    Session.log               # Header-only until body implemented
  silverstone-2025-09-02T10-32-05Z-lap-2/
    ...

Lap rotation is driven by the player's current lap number (LapData packet) and track slug derives from the Session packet trackId. If either packet hasn't arrived yet the logger buffers in the current (first) lap folder.

Tips:

  • Use --filter 6 to record only CarTelemetry for lighter storage.
  • Combine --filter 6,14 --laps-out telemetry_laps to study pace vs. time trial deltas.
  • Add --pretty only for human inspection; compact mode is smaller & faster.

Troubleshooting

No packets received

  • Check that F1 25 telemetry is enabled in game settings
  • Verify IP address and port match between game and logger
  • Check firewall settings (allow UDP traffic on port 20777)
  • Try running as administrator/sudo if needed

Parse errors

  • The logger will continue running even if header parsing fails
  • Parse errors are logged with a note explaining the issue
  • Common causes: game version mismatch, corrupted packets

Performance

  • Default buffer size is 2048 bytes (suitable for F1 25 packets)
  • High packet rates (60Hz) may generate significant output
  • Consider redirecting output to a file for analysis: cargo run > telemetry.jsonl

Development

Project Structure

f1logger/
├── Cargo.toml          # Dependencies and metadata
├── src/
│   └── main.rs         # Main application code
└── README.md           # This file

Adding Features

  • Packet body parsing for specific packet types
  • Database storage (SQLite, PostgreSQL)
  • Real-time dashboard with web interface
  • Data export to CSV/Excel formats

License

This project is open source. Feel free to modify and distribute.

About

An open source F1® 25 game telemetry receiver

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages