Descent3
Descent 3 by Outrage Entertainment
A race engineer for F1 26
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A race engineer for F1 26. It reads the game's UDP telemetry, keeps a model of the session, decides what is worth saying, says it over your headset, and shows it on a second monitor. Pitwall runs on your local network. Nothing leaves it.
Install on a Windows PC with PowerShell:
irm https://raw.githubusercontent.com/artsworks/f1-pitwall/main/install/install.ps1 | iex
Install on a Mac or Linux server:
curl -LsSf https://raw.githubusercontent.com/artsworks/f1-pitwall/main/install/install.sh | sh
Mac and Linux servers play speech in the dashboard browser tab only.
You need Git and uv. uv installs Python 3.12 for you, so nothing else is required. In PowerShell:
# 1. Install uv and Git (skip either if you already have it), then close and reopen PowerShell
winget install --id astral-sh.uv -e
winget install --id Git.Git -e
# 2. Get pitwall
git clone https://github.com/artsworks/f1-pitwall.git
cd f1-pitwall
uv sync # creates .venv with Python 3.12 and all dependencies
# 3. Optional: natural voice (~60 MB download into voices/, git-ignored)
uv run pitwall voice get
uv run pitwall voice warm # optional: pre-render fixed phrases (speech.warm_phrases, default 150)
# 4. Check the setup, then run
uv run pitwall voice say # radio check through your headset
uv run pitwall doctor # ports, wire format, packet rate, speech
uv run pitwall start # engine + speech + dashboard
Then in F1 26, Settings → Telemetry Settings:
| Setting | Value |
|---|---|
| UDP Telemetry | On |
| UDP Broadcast Mode | Off |
| UDP IP Address | 127.0.0.1 |
| UDP Port | 20777 |
| UDP Send Rate | 30 Hz |
| UDP Format | 2026 |
Open http://localhost:8000 on the second monitor (/radio is the compact
log view). You should hear "Pit wall online." on start, and the dashboard goes
LIVE as soon as you are on track (the game sends nothing from the menus).
In the game's controls menu, bind a free wheel button to UDP Action 1 (and optionally another to UDP Action 3). The pit wall answers every press by voice.
| Press | Action |
|---|---|
| UDP 1 single | Acknowledge the last call ("Copy.") |
| UDP 1 double | Negative ("Noted."); with no recent call, quiet for 5 minutes |
| UDP 1 held ≥ 0.8 s | Radio silent on/off: no speech (urgent P1 calls still speak), dashboard keeps the radio |
With voice.enabled: true, the wheel gestures stay the same. The mic listens while the driver menu is open, or for 2 s after you press V on the dashboard.
Update with the Pitwall Update shortcut, or run pitwall update.
| Symptom | Fix |
|---|---|
winget not recognised | Use Astral's installer instead: powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" (ByPass applies to that one command only) |
uv not recognised after install | Close and reopen PowerShell so the new PATH is picked up |
| Dashboard says STALE | Run pitwall doctor --seconds 30 while driving. 0 datagrams → check the game settings above, restart the game after changing them, then allow UDP 20777 in Windows Firewall (doctor prints the netsh commands). |
| No speech | pitwall voice say prints the error. --engine piper uses the downloaded voice, and --engine omnivoice uses the configured OmniVoice server. |
| Robotic voice | pitwall voice get, then restart pitwall start. |
More in docs/getting-started.md.
| Call | When |
|---|---|
| Qualifying | Clean-air release, abort advice, and a push/cool/box/push-now run plan with fuel and battery reminders |
| Race strategy | Plans A/B/C, pit windows, undercut and overcut advice, and safety-car or VSC stop calls |
| Tyres | Out-lap checks, thermal advice, and life from the minimum of worst-corner wear life and the pace cliff |
| Fuel and ERS | Fuel margin, deployment and energy-budget calls |
| Driving and flags | Wing damage, boost left on, yellow flags, lock-ups, spins and slides |
Calls rotate through several phrasings, and repeat the same mistake often enough and the engineer gets drier about it (ADR 0008).
Every call is a rule in src/pitwall/config/defaults/rules/shared.yaml
with thresholds in thresholds.yaml.
No steps are required. Pitwall grades sessions at the end and runs upkeep at the next start. Optional review and learning commands are in After a session.
Pitwall grades each session when it ends, then refits pace, tyre wear, fuel, thermal
and energy priors and adjusts rule cooldowns from the grades.
The refit values also go to the per-track files in ~/.pitwall/tracks/.
Two steps stay manual by design: grading calls at /debrief/latest and applying the
threshold YAML changes that pitwall propose writes. Your grades always override
automatic ones. Rule thresholds never change without your review, and cooldown
multipliers stay between tune_min_cooldown_mult and tune_max_cooldown_mult.
Set learning.auto_calibrate: false to turn off the refit and cooldown steps.
To propose your learned per-track values for the packaged defaults, share only
learnings/learning-latest.json. Do not share the SQLite database, digests, profile
or certificates. See Contributing your learnings.
flowchart LR
game[F1 26<br/>UDP 20777] --> ingest
ingest --> rec[(recordings/<br/>.f1bin.zst)]
ingest --> state[session state<br/>10 Hz snapshots]
state --> rules[rules<br/>YAML, hysteresis]
rules --> disp[dispatcher<br/>priority, cooldown, budget]
disp --> log[(decision log<br/>.jsonl)]
disp --> speech[speech<br/>Piper / OmniVoice]
disp --> ws[WebSocket 8000] --> ui[dashboard<br/>2nd monitor]
rec -.replay, same path.-> ingest
Recordings replay through the same ingest → state → rules path, so every rule is tuned and tested offline against real sessions instead of by driving another race.
Every session is recorded under recordings/ (local only, git-ignored).
The default lite profile is about 35 MB per 3 hours; use --record full
when you want a session for debugging.
pitwall start --record full # everything at 30 Hz
pitwall replay recordings\<file>.f1bin.zst --speed 10 --stats
pitwall replay recordings\<file>.f1bin.zst --serve # watch it on the dashboard
| Command | What it does | Example |
|---|---|---|
pitwall start | Run live: listens to game telemetry, makes calls, speaks them. | pitwall start |
pitwall doctor | Check your setup: tests the UDP port and shows which telemetry arrives. | pitwall doctor --seconds 10 |
pitwall update | Update Pitwall: pull the latest code with git, then sync dependencies with uv. | pitwall update |
pitwall cert | Set up HTTPS for the phone radio page: makes a trusted certificate with mkcert. | pitwall cert |
pitwall recordings | List recordings newest first, with the # that other commands accept. | pitwall recordings |
pitwall sessions | List stored sessions newest first, to find a session uid. | pitwall sessions --limit 5 |
pitwall replay | Rerun a recording through the engine to see the calls it makes. | pitwall replay latest --speed 4 --serve |
pitwall stats | Show what a recording holds, or what Pitwall has learned so far. | pitwall stats --learned |
pitwall digest | Learn from recordings: grades each session and writes its digest. | pitwall digest recordings/ |
pitwall debrief | Export a session debrief as one HTML file you can open or share. | pitwall debrief |
pitwall setup | Suggest car setup changes from how a recorded run went. | pitwall setup --mode garage |
pitwall evaluate | Did the calls help? Compares calls-on vs calls-off outcomes. | pitwall evaluate |
pitwall calibrate | Fit track priors for pace, tyre wear and fuel from your sessions. | pitwall calibrate --track 7 --dry-run |
pitwall voice | Manage speech: list and download voices, pre-render phrases, test audio. |
Run pitwall <command> -h for its options and an example. Run pitwall --help-all to list
the advanced commands for rule-engine work: diff, bench, rules check, propose,
tune, restore and trim.
Gauges are a solved problem. The value here is judgement: knowing that the undercut is worth 1.2 seconds, that there are three laps of life left in the fronts at this pace, and, above all, knowing when to stay silent.
Use
| Document | Contents |
|---|---|
docs/status.md | What works today, what is next, known gaps |
docs/getting-started.md | Install, game settings, after-session commands, recording profiles, replay |
docs/07-replay-and-debug.md | Recording format, replay CLI, A/B diffing, live diagnostics |
docs/08-configuration.md | Settings model, verbosity presets, balanced/aggressive mindset |
docs/20-learning-loop.md | Automatic grading and upkeep, calibration, learned state |
Design
| Document | Contents |
|---|---|
docs/01-architecture.md | Layers, stack, cross-cutting decisions, repo layout |
docs/02-ingestion.md | Packets consumed, parser design, pause/flashback, recording format |
docs/03-strategy.md | Rule format, pace and degradation model, pit loss, race and quali calls |
docs/04-audio-ui.md | Priorities, suppression, speech constraints, WebSocket protocol |
docs/09-performance.md | Co-hosting with the game: stutter causes, budget, measurement |
docs/12-driver-input.md | Wheel button and spacebar: acknowledge / negative |
docs/13-league-multiplayer.md | Friends-league target: restricted telemetry, league preset |
docs/15-dashboard-design.md | Second-monitor dashboard design (implemented in web/) |
docs/16-debrief-design.md | Session debrief: built sections, grading and deferred work |
Decisions and reference
| Document | Contents |
|---|---|
docs/adr/ | Architecture decision records: what live sessions taught us |
docs/05-roadmap.md | Next work and later options; the finished M0–M4 plan as history |
docs/reference/f1-26-udp-notes.md | Verified format-2026 packet facts |
docs/00-review-of-v1.md, 06, 10, 11, 14 | History / early planning (kept for reference): review of the first plan, direction changes, open angles and questions, adversarial review |
The project follows Semantic Versioning 2.0.0. While the version is 0.x, a breaking change bumps MINOR instead of MAJOR. Moving to 1.0.0 is a manual decision.
Pull requests are squash-merged, so the PR title becomes the commit on main. The PR title must be a Conventional Commit, and CI checks it. On each push to main, the release workflow reads the title and bumps the version:
| PR title | Bump on 0.x |
|---|---|
fix: ..., perf: ... | PATCH |
feat: ... | MINOR |
feat!: ... or a BREAKING CHANGE: footer | MINOR |
docs:, chore:, refactor:, test:, build:, ci: | none |
The workflow updates pyproject.toml and uv.lock, adds an entry to CHANGELOG.md, and pushes a vX.Y.Z tag, then creates a GitHub Release with the same notes. Do not edit the version by hand.
GPLv3 — see LICENSE.
f1-pitwall is an unofficial project for education and experiments. It is not affiliated with, endorsed by or connected to Formula 1, the FIA or the makers of the F1 games. Formula 1, F1 and related marks are trademarks of their owners. The tool reads the game's UDP telemetry on your own PC. Development and tests use previously recorded and synthetic timing and telemetry data.
pitwall voice say "Box this lap" |
pitwall cleanup | Reclaim disk space and keep recordings not learned yet. | pitwall cleanup --learn |
pitwall report | Bundle a recording and its decision log into a zip for a bug report. | pitwall report latest -o report.zip |
docs/17-quali-run-plan.md | Qualifying run plan and coaching |
docs/18-race-engine.md | Race engine, tyre life, degradation priors and persistence |
docs/21-voice-command.md | Voice-command design and implementation status |
docs/22-setup-advisor.md | Setup advisor proposal: parameter effects, parc fermé matrix, balance signals, rule tables, learning loop |