A real-time telemetry heads-up display for Forza Horizon 6, rendered as a transparent overlay on top of the game. Receives live data via the game's UDP "Car Dash" stream and displays it through 30+ independently positionable and fully customisable elements.
- 30+ overlay elements across 8 categories - RPM, inputs, gears, speed, engine metrics, tyres, dynamics, race session, identity
- Per-element style selection - each element has between 2 and 7 visual display styles (bar, arc gauge, numeric, radial, etc.)
- Full colour customisation - bar fill colour and text colour independently configurable per element
- Drag-and-drop layout editor - resize and reposition any element live, snapped to an 8 px grid
- Intelligent shift assistant - three-tier algorithm (power peak → torque crossover → raw ratio) learns per-car shift points from live telemetry and stores them in
car_data.json; cache is keyed by a five-field fingerprint (class, PI, engine idle RPM, engine max RPM, drivetrain) so PI-neutral modifications (e.g. engine swap + suspension downgrade) are correctly detected; a gearbox-only swap is caught by a runtime ratio sanity check on the first observed upshift - Pedal telemetry from UDP - throttle, brake, and clutch read directly from the game packet, accurate regardless of input device
- Tyre telemetry - temperature (°F), combined slip ratio, wheel speed, and suspension travel per corner in 4-wheel grid or 2-wheel row layouts
- G-force, yaw, slip angle, roll/pitch - dynamics elements with live physics data
- Race session info - current/last/best lap time, lap number, race position, elapsed race time
- Car identity - car class, PI, drivetrain type, per-gear ratio display
- Single-instance guard - prevents duplicate overlays
- System tray - quick access to settings and layout editor without task switching
| Category | Elements |
|---|---|
| RPM | RPM bar |
| Inputs | Throttle, Brake, Clutch |
| Gear | Gear indicator, Shift Up signal, Shift Down signal |
| Engine | Speed, Boost, Fuel, Power (kW), Torque (Nm) |
| Tyres | Tyre Temp, Tyre Slip, Wheel Speed, Suspension Travel |
| Dynamics | G-Force, Yaw Rate, Slip Angle, Oversteer, Roll/Pitch, Axle Delta |
| Race Session | Current Lap, Last Lap, Best Lap, Race Time, Lap Number, Race Position |
| Car Identity | Car Class, Car PI, Drivetrain, Gear Ratio |
| Network | UDP Status |
- Windows 10/11
- Python 3.11+
- PyQt6
- pygame (for gamepad input capture)
Install dependencies:
pip install PyQt6 pygame
python src/overlay.py
On first run a setup wizard appears. A 3-second splash screen is shown, then the wizard asks for your transmission type. No button bindings are collected - all signals are automatic from UDP. Bindings can be set later in the settings panel.
| Component | Role |
|---|---|
src/overlay.py |
Main window, element host, edit layout engine, tray icon, single-instance guard |
src/telemetry.py |
UDP listener thread, packet parser, shift detection, CarCache, TelemetryState |
src/config.py |
Config dataclass, INI load/save |
src/controller.py |
XInput listener thread, ControllerState |
src/input_listener.py |
Cross-device input capture (keyboard + gamepad) via pygame |
src/setup_wizard.py |
First-run wizard (collects transmission type) |
src/settings_panel.py |
Runtime settings panel (colours, styles, transmission, port) |
elements/ |
One file per element or element group; all extend BaseElement |
car_data.json |
Per-car learned gear ratios and optimal shift RPM (auto-created) |
config.ini |
User configuration (auto-created by wizard) |
Forza Horizon 6
│ UDP port (default 20777)
▼
start_udp_listener() ← background thread
│ parse_packet() - 320-byte Car Dash packet
▼
TelemetryState ← shared data store (thread-safe reads)
│
▼
OverlayWindow._tick() ← 60 Hz QTimer
│ updates every BaseElement
▼
Element._paint_element() ← QPainter render per element
Set environment variable FH6_DIAG=1 before launch to write shift logic diagnostics to shift_diag.log in the project directory.
src/
overlay.py main entry point
config.py configuration
telemetry.py UDP + shift logic
controller.py XInput gamepad
input_listener.py cross-device input
setup_wizard.py first-run wizard
settings_panel.py settings panel
elements/
base.py BaseElement (shared edit-mode logic)
bar_item.py Brake / Throttle / Clutch bars
rpm_item.py RPM bar
gear_item.py Gear display
shift_item.py Shift signals
speed_item.py Speed
boost_item.py Boost
fuel_item.py Fuel
power_item.py Power (kW)
torque_item.py Torque (Nm)
tyre_items.py Tyre Temp / Slip / Wheel Speed / Suspension
dynamics_items.py G-Force / Yaw Rate
lap_time_items.py Lap times
race_session_items.py Race time / Lap number / Race position
car_identity_items.py Car Class / PI / Drivetrain
engineering_items.py Gear Ratio / Slip Angle / Oversteer / Roll-Pitch / Axle Delta
network_item.py UDP status
logo/
logo.png application icon
car_data.json per-car learned data (auto-generated)
config.ini user configuration (auto-generated)