DiRT Rally 1 & 2.0 — UDP Telemetry Protocol Specification

# DiRT Rally 1 & 2.0 — UDP Telemetry Protocol Specification

> **Games**: DiRT Rally (2015), DiRT Rally 2.0 (2019) by Codemasters
> **Engine**: EGO Engine (Codemasters proprietary)
> **Parser status**: ❌ Not implemented in rusty-telemetry
> **Platform**: Windows (DR1 also on Linux/Proton)
> **Importance**: HIGH — second rally sim in scope, key differentiator alongside AC Rally

---

## Overview

Both DiRT Rally games use the **Codemasters UDP telemetry format** — the same protocol family used by the F1 game series (F1 2016–2024). No handshake needed. The game broadcasts binary packets to a configured IP:port.

| Property | DiRT Rally 1 | DiRT Rally 2.0 |
|---|---|---|
| **Default Port** | 20777 | 20777 |
| **Format** | Binary, little-endian | Binary, little-endian |
| **Update Rate** | Configurable (up to 60 Hz) | Configurable (up to 60 Hz) |
| **Direction** | Game → Target IP:Port | Game → Target IP:Port |
| **Handshake** | None | None |
| **Packet Types** | 1 (all-in-one) | Multiple (physics, participants, lap data, etc.) |

---

## Cross-References

- **AC original protocol**: [Assetto Corsa — UDP Telemetry Protocol Specification](joplin://aed9f3be040943048273a16e05a8100f)
- **ACC protocol**: [ACC — UDP Telemetry Protocol Specification](joplin://6ae7005d9810437093d63470cff98b59)
- **AC EVO status**: [AC EVO — Telemetry Status & Research](joplin://2171d34ab9c1431ea3a979d30d206e23)
- **AC Rally status**: [AC Rally — Telemetry Status & Research](joplin://b7b331aa87544b6ebe5db5b8d7bcd2a0)
- **PCARS protocol**: [Project CARS 1 & 2 — UDP Telemetry Protocol Specification](joplin://c6bd2c45938246fa9d61776deae9874b)
- **Main project plan**: [Sim Racing Telemetry Analysis Platform — Project Plan](joplin://6c0dcb2a567348fd9796f50c790082e4)

---

## Configuration

### DiRT Rally 1
- File: `My Games\DiRT Rally\hardwaresettings\hardware_settings_config.xml`
- Or in-game: Options → Telemetry → Enable
- Settings:
  ```xml
  <motion>
    <udp enabled="true" ip="127.0.0.1" port="20777" delay="1" />
  </motion>
  ```

### DiRT Rally 2.0
- File: `My Games\DiRT Rally 2.0\hardwaresettings\hardware_settings_config.xml`
- Or in-game: Options → Telemetry → Enable
- Settings:
  ```xml
  <motion>
    <udp enabled="true" ip="127.0.0.1" port="20777" delay="1" />
  </motion>
  ```

### rusty-telemetry Bind Strategy
- Bind UDP socket to `0.0.0.0:20777`
- Game sends to `127.0.0.1:20777`
- No registration or handshake needed

---

## DiRT Rally 1 — Telemetry Packet

### Single Packet Format (All-in-One)

Total size: **~175 bytes**

| Offset | Size | Type | Field | Notes |
|---|---|---|---|---|
| 0 | 4 | float32_le | time | Session time (seconds) |
| 4 | 4 | float32_le | lap_time | Current lap time (seconds) |
| 8 | 4 | float32_le | lap_distance | Distance into current lap (meters) |
| 12 | 4 | float32_le | total_distance | Total distance (meters) |
| 16 | 4 | float32_le | x_position | World position X |
| 20 | 4 | float32_le | y_position | World position Y (up) |
| 24 | 4 | float32_le | z_position | World position Z |
| 28 | 4 | float32_le | speed | Speed (m/s) |
| 32 | 4 | float32_le | x_velocity | World velocity X |
| 36 | 4 | float32_le | y_velocity | World velocity Y |
| 40 | 4 | float32_le | z_velocity | World velocity Z |
| 44 | 4 | float32_le | x_roll | Roll vector X |
| 48 | 4 | float32_le | y_roll | Roll vector Y |
| 52 | 4 | float32_le | z_roll | Roll vector Z |
| 56 | 4 | float32_le | x_pitch | Pitch vector X |
| 60 | 4 | float32_le | y_pitch | Pitch vector Y |
| 64 | 4 | float32_le | z_pitch | Pitch vector Z |
| 68 | 4 | float32_le | x_suspension | Suspension position FL (meters) |
| 72 | 4 | float32_le | x_suspension | Suspension position FR |
| 76 | 4 | float32_le | x_suspension | Suspension position RL |
| 80 | 4 | float32_le | x_suspension | Suspension position RR |
| 84 | 4 | float32_le | x_velocity | Suspension velocity FL |
| 88 | 4 | float32_le | x_velocity | Suspension velocity FR |
| 92 | 4 | float32_le | x_velocity | Suspension velocity RL |
| 96 | 4 | float32_le | x_velocity | Suspension velocity RR |
| 100 | 4 | float32_le | x_wheel_speed | Wheel speed FL (m/s) |
| 104 | 4 | float32_le | x_wheel_speed | Wheel speed FR |
| 108 | 4 | float32_le | x_wheel_speed | Wheel speed RL |
| 112 | 4 | float32_le | x_wheel_speed | Wheel speed RR |
| 116 | 4 | float32_le | throttle | Throttle input 0.0–1.0 |
| 120 | 4 | float32_le | steer | Steering -1.0 to 1.0 |
| 124 | 4 | float32_le | brake | Brake input 0.0–1.0 |
| 128 | 4 | float32_le | clutch | Clutch input 0.0–1.0 |
| 132 | 4 | float32_le | handbrake | Handbrake 0.0–1.0 |
| 136 | 1 | uint8 | gear | Current gear (0=N, 1-6=forward, -1=reverse) |
| 137 | 4 | float32_le | g_force_lateral | Lateral G-force |
| 141 | 4 | float32_le | g_force_longitudinal | Longitudinal G-force |
| 145 | 4 | float32_le | lap | Current lap number |
| 149 | 4 | float32_le | rpm | Engine RPM |
| 153 | 4 | float32_le | slip_front | Front slip ratio |
| 157 | 4 | float32_le | slip_rear | Rear slip ratio |
| 161 | 4 | float32_le | x_angular_vel | Angular velocity X |
| 165 | 4 | float32_le | y_angular_vel | Angular velocity Y |
| 169 | 4 | float32_le | z_angular_vel | Angular velocity Z |

> **Note**: DR1 packet format has minor variations depending on game version. Some community implementations report slightly different sizes (150–175 bytes). Verify against live captures.

---

## DiRT Rally 2.0 — Multi-Packet Format

DR2 uses a **multi-packet model** similar to the F1 game series. The first byte of every packet is the **packet ID** that determines the structure.

### Packet Header (all packets)

| Offset | Size | Type | Field | Notes |
|---|---|---|---|---|
| 0 | 1 | uint8 | packet_id | Packet type identifier |
| 1 | 1 | uint8 | packet_format | Game format version |

### Packet Types

| Packet ID | Name | Description |
|---|---|---|
| 0 | Motion | Car physics, suspension, G-forces |
| 1 | Session | Session info, track, conditions |
| 2 | Lap Data | Lap times, splits, best laps |
| 3 | Event | Race events (start, finish, DNF) |
| 4 | Participants | Driver info |
| 5 | Car Setups | Setup data (tyres, suspension) |
| 6 | Car Telemetry | Speed, RPM, gear, inputs, temps |
| 7 | Car Status | Damage, fuel, tyre wear, DRS |

> **Note**: DR2 shares the same protocol family as Codemasters F1 games but may not include all packet types. Rally-specific data (surface type, stage progress) is mixed into the existing packet types.

### Packet 0: Motion Data

| Offset | Size | Type | Field | Notes |
|---|---|---|---|---|
| 0 | 1 | uint8 | packet_id = 0 | |
| 1 | 1 | uint8 | packet_format | |
| 2 | 4 | float32_le | x_position | World X |
| 6 | 4 | float32_le | y_position | World Y (up) |
| 10 | 4 | float32_le | z_position | World Z |
| 14 | 4 | float32_le | x_velocity | World velocity X |
| 18 | 4 | float32_le | y_velocity | World velocity Y |
| 22 | 4 | float32_le | z_velocity | World velocity Z |
| 26 | 4 | float32_le | x_pitch | Pitch vector X |
| 30 | 4 | float32_le | y_pitch | Pitch vector Y |
| 34 | 4 | float32_le | z_pitch | Pitch vector Z |
| 38 | 4 | float32_le | x_roll | Roll vector X |
| 42 | 4 | float32_le | y_roll | Roll vector Y |
| 46 | 4 | float32_le | z_roll | Roll vector Z |
| 50 | 4 | float32_le | x_yaw | Yaw vector X |
| 54 | 4 | float32_le | y_yaw | Yaw vector Y |
| 58 | 4 | float32_le | z_yaw | Yaw vector Z |
| 62 | 4 | float32_le | x_angular_vel | Angular velocity X |
| 66 | 4 | float32_le | y_angular_vel | Angular velocity Y |
| 70 | 4 | float32_le | z_angular_vel | Angular velocity Z |
| 74 | 4 | float32_le | g_force_lateral | Lateral G |
| 78 | 4 | float32_le | g_force_longitudinal | Longitudinal G |
| 82 | 4 | float32_le | g_force_vertical | Vertical G |
| 86 | 16 | float32_le × 4 | suspension_position | Per-wheel (FL, FR, RL, RR) |
| 102 | 16 | float32_le × 4 | suspension_velocity | Per-wheel |
| 118 | 16 | float32_le × 4 | suspension_acceleration | Per-wheel |
| 134 | 16 | float32_le × 4 | wheel_speed | Per-wheel (m/s) |
| 150 | 4 | float32_le | wheel_slip_ratio | Combined or front? (varies) |

### Packet 6: Car Telemetry

| Offset | Size | Type | Field | Notes |
|---|---|---|---|---|
| 0 | 1 | uint8 | packet_id = 6 | |
| 1 | 1 | uint8 | packet_format | |
| 2 | 4 | float32_le | speed | Speed (m/s) |
| 6 | 2 | uint16_le | rpm | Engine RPM |
| 8 | 2 | uint16_le | gear | Current gear |
| 10 | 2 | uint16_le | suggested_gear | AI suggested gear |
| 12 | 1 | uint8 | throttle | 0–255 |
| 13 | 1 | int8 | steer | -127 to 127 |
| 14 | 1 | uint8 | brake | 0–255 |
| 15 | 1 | uint8 | clutch | 0–255 |
| 16 | 1 | uint8 | handbrake | 0–255 |
| 17 | 1 | uint8 | fuel | Fuel remaining 0–255 |
| 18 | 4 | float32_le | engine_temp | Engine temperature (°C) |
| 22 | 8 | uint16_le × 4 | brake_temp | Brake temp per wheel (°C) |
| 30 | 8 | uint16_le × 4 | tyre_surface_temp | Tyre surface temp per wheel (°C) |
| 38 | 8 | uint16_le × 4 | tyre_inner_temp | Tyre inner temp per wheel (°C) |
| 46 | 8 | float32_le × 4 | tyre_pressure | Tyre pressure per wheel (PSI) |
| 54 | 8 | float32_le × 4 | surface_type | Per-wheel surface type |

### Surface Type Enumeration (DR2 Specific)

```
0 = Tarmac
1 = Gravel
2 = Mud
3 = Snow
4 = Ice
5 = Grass
6 = Sand/Dirt
7 = Cobblestone
```

This is **critical for rally coaching** — per-wheel surface type enables surface adaptation analysis.

---

## Rally-Specific Data in DiRT Rally

### What DR1/DR2 Provide for Rally Coaching

| Use Case | DR1 | DR2 | Data Source |
|---|---|---|---|
| **Surface detection** | ❌ | ✅ Per-wheel | surface_type in telemetry packet |
| **Suspension analysis** | ✅ Position + velocity | ✅ Position + velocity + acceleration | Motion packet |
| **Stage progress** | ✅ lap_distance | ✅ lap_distance | Treat stage as single lap |
| **G-forces** | ✅ 2-axis | ✅ 3-axis | Motion packet |
| **Wheel speeds** | ✅ Per-wheel | ✅ Per-wheel | Motion/telemetry |
| **Tyre temperatures** | ❌ | ✅ Surface + inner | Telemetry packet |
| **Tyre pressures** | ❌ | ✅ Per-wheel PSI | Telemetry packet |
| **Handbrake input** | ✅ | ✅ | Telemetry packet |
| **Car damage** | ❌ | ✅ (limited) | Status packet |
| **Fuel** | ❌ | ✅ | Telemetry packet |
| **World position** | ✅ | ✅ | Motion packet |
| **Full orientation** | ❌ | ✅ Pitch + Roll + Yaw | Motion packet |
| **Angular velocity** | ✅ 3-axis | ✅ 3-axis | Motion packet |
| **Brake temps** | ❌ | ✅ Per-wheel | Telemetry packet |
| **Multi-car** | ❌ | ❌ | Player car only |

### Advantages over AC Rally (for coaching)

1. **Available NOW** — both games are released and working
2. **Per-wheel surface type** — the single most important rally coaching field
3. **Suspension detail** — position + velocity + acceleration per wheel
4. **Tyre thermal data** — surface + inner temps per wheel
5. **Handbrake input** — critical for rally technique analysis
6. **3-axis G-forces** — including vertical (jumps!)
7. **Proven protocol** — same format as F1 series, well-documented by community

### Limitations

1. **No co-driver/pace note sync** — no way to correlate calls with data
2. **No stage metadata** — stage name, surface type overview, stage length not in packets
3. **No multi-car** — only player car data
4. **No slip ratio/angle** — no tyre slip physics detail (unlike AC Telemetry Tool)
5. **No spline position** — must calculate from world coordinates
6. **No tyre wear model** — no degradation tracking

---

## Data Depth Comparison

### vs AC Telemetry Tool (10101)

| Capability | AC Telemetry Tool | DR2 UDP |
|---|---|---|
| Rate | 60 Hz | Up to 60 Hz |
| G-forces | ✅ 3-axis | ✅ 3-axis |
| Tyre slip detail | ✅ Ratio + angle + nd_slip | ❌ |
| Tyre temps | ✅ Core temps | ✅ Surface + inner |
| Surface type | ❌ | ✅ **Per-wheel** |
| Handbrake | ❌ | ✅ |
| Suspension | ✅ Ride height F/R | ✅ Per-wheel pos + vel + acc |
| Tyre pressures | ❌ | ✅ Per-wheel PSI |
| World position | ✅ | ✅ |
| Velocity vectors | ✅ 3D world + local | ✅ 3D world |
| Full orientation | ❌ | ✅ Pitch + Roll + Yaw |
| Multi-car | ✅ | ❌ |
| Damage | ❌ | ✅ (limited) |

### vs AC Rally (Unknown Protocol)

| Capability | AC Rally (predicted) | DR2 UDP (proven) |
|---|---|---|
| **Status** | Unknown (EA) | ✅ Working |
| Surface type | Unknown | ✅ Per-wheel |
| Tyre temps | Unknown | ✅ Per-wheel |
| Suspension detail | Unknown | ✅ Per-wheel 3-axis |
| Co-driver sync | Unknown | ❌ |
| Pace note data | Unknown | ❌ |
| Stage metadata | Unknown | ❌ |
| Community tools | None | Multiple (SimHub, etc.) |

---

## Rust Implementation Plan

### Recommended Port

| Port | Use |
|---|---|
| 20777 | DiRT Rally 1 & 2 primary telemetry |

### Parser Architecture

```
src/
  parser_dirt_rally.rs    — Unified DR1 + DR2 parser
```

### Auto-Detection Strategy

1. If packet size ~175 bytes and starts with a float (time > 0) → **DR1 format**
2. If packet byte 0 is 0–7 (packet_id) and byte 1 is a known format version → **DR2 format**
3. DR2 packets are dispatched by packet_id to type-specific parsers

### Implementation Steps

1. **DR1 parser**: Single all-in-one packet, straightforward binary parsing
2. **DR2 packet dispatcher**: Read byte 0 for packet_id
3. **DR2 Motion parser** (packet 0): Position, velocity, orientation, suspension, G-forces
4. **DR2 Telemetry parser** (packet 6): Speed, RPM, gear, inputs, tyre temps, surface type
5. **DR2 Session parser** (packet 1): Track info, conditions
6. **DR2 Lap Data parser** (packet 2): Stage/lap times
7. **DR2 Status parser** (packet 7): Damage, fuel

### Estimated Effort

- **DR1**: ~2 days (single packet, ~175 bytes)
- **DR2**: ~5 days (multiple packet types, similar to F1 protocol)
- **Total**: ~7 days

### Priority

**HIGH** — DiRT Rally 2.0 is the only rally sim with proven, documented telemetry that includes **per-wheel surface type**. This is the rally coaching differentiator we can ship NOW, while AC Rally telemetry is still unknown.

---

## Live Verification Needed

**No DiRT Rally data has been captured yet.** Protocol structure is based on Codemasters community documentation and F1 series references (same protocol family). Verification requires:
1. DiRT Rally 1 or 2.0 installed
2. UDP telemetry enabled in `hardware_settings_config.xml`
3. rusty-telemetry listening on port 20777
4. Packet captures to verify byte offsets

DR1 is frequently on sale for ~€5 on Steam. DR2 is ~€15.

---

## References

- Codemasters community documentation (forum posts)
- F1 series UDP specs (same protocol family, well-documented)
- Community implementations: Python/C# DiRT Rally telemetry tools
- SimHub DR2 plugin (reference implementation)

---

*Created: 2026-06-06*
*Status: Research phase — no live verification yet*
*Next step: Purchase DR2, enable UDP, capture and verify packets*
*Strategic note: This is the fastest path to rally telemetry coaching — proven protocol, available now*

id: 877a753ad06a40e08059834d8c8fb438
parent_id: 94aa3283ead4477d8449e324a27eb3d0
created_time: 2026-06-06T08:17:21.418Z
updated_time: 2026-06-06T08:27:31.507Z
is_conflict: 0
latitude: 0.00000000
longitude: 0.00000000
altitude: 0.0000
author: 
source_url: 
is_todo: 0
todo_due: 0
todo_completed: 0
source: joplin-desktop
source_application: net.cozic.joplin-desktop
application_data: 
order: 1780733841418
user_created_time: 2026-06-06T08:17:21.418Z
user_updated_time: 2026-06-06T08:27:31.507Z
encryption_cipher_text: 
encryption_applied: 0
markup_language: 1
is_shared: 0
share_id: 
conflict_original_id: 
master_key_id: 
user_data: 
deleted_time: 0
type_: 1