English | 简体中文
This project is maintained for the Forza Mods Discord community by Insightful.
An external adaptive transmission controller for Forza Horizon 6. It reads real-time UDP telemetry from the game, decides when to shift based on driving style, throttle, RPM, speed, and brake input, and injects keyboard keys (E = upshift, Q = downshift).
After launch, open http://127.0.0.1:8765 in your browser for the live dashboard and settings (English / 简体中文 UI).
| I want to… | Use |
|---|---|
| Play — no Python / Node install | Download & use (Release) |
| Develop or run from this repo | Run from source |
| Change the Vue UI | web-ui/README.md |
Platform: Windows 10 / 11 only. Run as Administrator (required for global key injection).
Open GitHub Releases and download the latest VirtualTCU-*-win64.zip.
Extract the entire zip to any folder (e.g. C:\Games\VirtualTCU\). Do not run the exe from inside the zip preview.
VirtualTCU-12.0.x-win64/
├── Launch VirtualTCU.bat ← optional launcher (recommended)
└── VirtualTCU/
├── VirtualTCU.exe
└── _internal/ ← required; do not delete or move exe alone
Right-click Launch VirtualTCU.bat or VirtualTCU\VirtualTCU.exe → Run as administrator.
A console window opens. The browser may auto-open http://127.0.0.1:8765; if not, open it manually.
Configure FH6 once (in-game setup), start a race, and the dashboard should go live when telemetry arrives.
Focus the console window and press Ctrl + C, then close the window.
(Do not use Q — that is the in-game downshift key.)
Release builds save config, profiles, and logs in the same folder as VirtualTCU.exe (portable-style):
VirtualTCU/
├── VirtualTCU.exe
├── _internal/
├── tcu_config.json
├── tcu_profiles.json
├── logs/
│ └── tcu_replay_*.bin.gz
└── .tcu_last_run
If the install folder is not writable (e.g. C:\Program Files\), data falls back to %APPDATA%\VirtualTCU\ (the console shows which path is used on startup).
| Item | Default (Release) |
|---|---|
| Settings | VirtualTCU\tcu_config.json |
| Per-car profiles | VirtualTCU\tcu_profiles.json |
| Telemetry replay logs | VirtualTCU\logs\ |
| Crash log (if startup fails) | same folder as above / crash.log |
- In the Web UI sidebar, click Start logging (events) or Start logging (all).
- Drive in FH6 (must be in a race with Data Out enabled).
- Click Stop when done — the file is finalized on stop.
| Mode | What it records |
|---|---|
| Events | Shift moments + short buffer (~0.5 MB typical) |
| All | Every telemetry packet while recording (up to 10 MB auto-stop) |
Files are named tcu_replay_YYYYMMDD_HHMMSS.bin.gz (gzip binary replay, not plain .log).
For developers or anyone running from a git clone.
| Tool | Version | Notes |
|---|---|---|
| Python | 3.10+ | Download — check Add Python to PATH |
| Node.js | 18+ | Only for building / editing the Web UI |
Open Administrator Command Prompt or PowerShell:
cd path\to\virtualTCU
pip install -r requirements.txtcd web-ui
npm install
npm run build
cd ..npm run build writes the dashboard to virtual_tcu/web/dist/. Without it, the backend returns HTTP 503 instead of the UI.
cd path\to\virtualTCU
python -m virtual_tcu(python virtual_tcu.py also works.)
Open http://127.0.0.1:8765, launch FH6, enter a race. Quit with Ctrl + C in the terminal.
When running from source, config / profiles / logs use the project directory (current working directory):
virtualTCU/
├── tcu_config.json
├── tcu_profiles.json
└── logs/
└── tcu_replay_*.bin.gz
Terminal 1 — backend:
python -m virtual_tcuTerminal 2 — Vite hot reload:
cd web-ui
npm run devOpen http://127.0.0.1:5173 (proxies WebSocket to port 8765). See web-ui/README.md.
cd web-ui && npm run build && cd ..
pip install pyinstaller
pyinstaller virtual_tcu.spec --noconfirmOutput: dist/VirtualTCU/ — same layout as the GitHub Release. Push a v* tag to trigger CI.
| Mode | Behavior |
|---|---|
| COMFORT | Eco-friendly shifts, early upshifts, cruise efficiency at stable speeds |
| DYNAMIC | Audi-style: higher RPM hold, strict rev-matching downshifts |
| RACE | Track-focused: near-redline upshifts, aggressive engine braking |
| DRIFT | Holds RPM in the power band, reduces unwanted downshifts mid-slide |
| OFFROAD | Tuned for low grip and uneven terrain |
| MANUAL | TCU disabled — you shift yourself |
F9 (global hotkey, works while Forza is in focus) cycles through modes. F8 toggles logging. Both can be changed in the Web UI settings.
Settings → Difficulty → Transmission → MANUAL (No Clutch)
Settings → Controls → Keyboard:
| Action | Key |
|---|---|
| Shift Up | E |
| Shift Down | Q |
Controller or wheel paddle bindings can stay active at the same time. The TCU only injects E / Q and does not take over throttle, steering, or other axes.
Settings → HUD and Gameplay → Data Out:
| Option | Value |
|---|---|
| Data Out | ON |
| IP Address | 127.0.0.1 |
| Port | 5555 |
| Packet Format | Car Dash (324 bytes) |
When connected, the browser shows:
- Gear / speed / RPM — color-coded tach bar (green → yellow → orange → red)
- Throttle / brake — pedal percentages
- TCU state — cruising, kickdown, engine braking, etc.
- Turbo / engine — boost (bar), power (kW), torque (Nm)
- Stats & shift history — session data and learning progress
- Settings — live tuning; per-car profile export/import
- Logger — start/stop telemetry replay recording
Switch UI language in the page header (English / 简体中文).
virtualTCU/
├── virtual_tcu.py # entry → virtual_tcu.app
├── virtual_tcu/ # Python package
├── web-ui/ # Vue 3 + Tailwind v4 frontend
├── packaging/ # Launch VirtualTCU.bat (bundled in Release zip)
├── virtual_tcu.spec # PyInstaller spec
└── .github/workflows/ # Release CI
- Extract the full zip — exe needs
_internal/beside it. - Close other TCU instances (
python -m virtual_tcuor anotherVirtualTCU.exe) — ports 5555 / 8765 are single-use. - Run from cmd:
cd path\to\VirtualTCUthenVirtualTCU.exe(failed builds pause with an error). - Check
crash.login the data folder shown at startup (exe dir or%APPDATA%\VirtualTCU\).
- Release logs are in
VirtualTCU\logs\next to the exe (or%APPDATA%\VirtualTCU\logs\if fallback). - Click Stop before looking — the gzip file is finalized on stop.
- Use All mode and drive in a race with Data Out ON; Events mode only writes meaningful data around shifts.
- Look for
tcu_replay_*.bin.gz, not.log.
- Data Out ON, port 5555, Car Dash format.
- Must be in a race (no telemetry in menus).
- Forza keyboard: Shift Up = E, Shift Down = Q.
- Run as Administrator.
- Close apps that may capture those keys (Discord overlay, MSI Afterburner, etc.).
- FH6 324-byte Car Dash only — not FH5 or Forza Motorsport.
- Works with any FH6 car — shift points auto-calibrate from telemetry max RPM.
- Reverse protection — no automatic shifts in reverse.
- Low-speed protection — no automatic shifts below ~12 km/h.
- Only sends E / Q keyboard events; does not modify controller inputs.
- Windows 11
- Steam edition of Forza Horizon 6
- Xbox Elite Series 2 controller
Telemetry based on the reverse-engineered FH6 324-byte Car Dash packet (confirmed via live diagnostics).