Controls Reference

Every key, button, gesture and setting in RaceVisor โ€” the same reference that ships with the app.

๏ปฟ# RaceVisor โ€” Controls Reference

RaceVisor is written in C# on WPF (.NET 10) and leverages DirectX (Direct3D 11 / Direct2D / DirectWrite) and the Windows platform directly โ€” shared-memory telemetry, DirectInput wheels, Media Foundation capture, Windows audio โ€” so it renders natively at up to 120 Hz and stays a single small signed exe.

Always-available rescue keys (baked in, cannot be rebound or broken)#

These two fire globally โ€” clickthrough on, window unfocused, sim running, doesn't matter:

ChordAction
Ctrl+Alt+Shift+` (backtick)EMERGENCY RESTORE โ€” loads default layout, opacity 100%, window snapped on-screen, lands in interactive mode. For "the overlay is invisible/unreachable/borked."
Ctrl+Alt+Shift+1OPACITY RESCUE โ€” every widget, every background, and the overlay backdrop back to 100%. Undoes any amount of ghosting in one press (Ctrl+Z reverses it).

Controllers#

Full DirectInput controller support โ€” map any overlay action to your wheel (e.g., Logitech G29), gamepad, or button box.

Keyboard#

F12 is the only rebindable global key. Everything else fires only while the overlay is in interactive mode and focused โ€” so Esc inside iRacing never quits RaceVisor.

Key (default)Action
F12Toggle clickthrough โ†” interactive (blue "๐Ÿ”’ INTERACTIVE MODE" badge while interactive)
EscClose things in order: open menu/panel first, then help, then any child window โ€” and only with nothing left to close, press Esc twice within 2 s to quit (interactive + focused only)
Ctrl+1โ€ฆ4Load preset 1โ€“4
None (rebindable)Previous preset
Ctrl+`Open the Layout Designer
Ctrl+NSave current layout
Ctrl+SLoad saved layout
Ctrl+ZUndo layout change (moves, resizes, menu/panel edits, wheel fades, loads, resets, opacity rescue). Needs the overlay focused in interactive mode - in VR use the right-click menu's Undo last change instead
Ctrl+0Reset to defaults (undoable)
Ctrl+QOpen the Hotkey Editor
Ctrl+RStart/stop telemetry recording (data, not video!) โ†’ red "โ— TELEMETRY REC" badge
Ctrl+OOpen/stop a telemetry replay (loops) โ€” a RaceVisor .jsonl.gz recording or an iRacing .ibt file (see Replaying iRacing's own telemetry below)
None (rebindable)iRacing .ibt disk telemetry on / off โ€” the same thing as Alt+L in the car, from a wheel button (global; iRacing only)
Num 0 (hold)Driver Chat push-to-talk - your mic is sent exactly while it is held (global; bind a wheel button here)
Ctrl+MDriver Chat: open mic on / off (talk without holding anything) (global)
Ctrl+TDriver Chat: open the text box - type, Enter sends, Esc cancels; drops you back into clickthrough afterwards (global)
None (rebindable)Driver Chat: mute on / off (hear nobody, still able to send) (global)
None (rebindable)Stopwatch: start / stop, Stopwatch: lap, Stopwatch: reset - three separate bindings, all (global), meant for wheel buttons

Bindings live in Documents\iRacing\irDash_hotkeys.json โ€” everything above is rebindable in the Hotkey Editor, which warns about duplicates and risky keys.

The toolbar (docks onto the Control Bar widget)#

Visible in interactive mode. It sits on the Control Bar widget โ€” move/resize that widget and the toolbar follows. No Control Bar in the layout? It floats top-left.

โ—€ [preset] โ–ถ cycle presets ยท Save asโ€ฆ ยท โš™ slider overlay backdrop opacity ยท Design inline designer ยท โฌš Group group-select mode ยท Fit shrink-wrap (monitor users only) ยท VR size biggest window = sharpest kneeboard (see "Fit costs sharpness in VR" below) ยท Designer full designer window ยท Keys hotkey editor ยท ๐Ÿ” Find (below) ยท ๐Ÿ”’ Lock back to racing

Fit costs sharpness in VR - keep the window big#

The kneeboard is a picture of the RaceVisor window: OpenKneeboard captures the window at its pixel size and stretches that onto the panel in the headset. So the window's size on the monitor is the kneeboard's resolution. Fit shrinks the window to hug the widgets - handy on a monitor, but in VR it throws pixels away, and with a busy layout (15-20 widgets) each widget is then drawn a few dozen pixels wide, so text goes soft and smears when you turn your head. Found 2026-09-15: an 18-widget layout in a 1300ร—760 window looked fuzzy; the same layout in a 1920ร—1080 window was crisp.

Rule for VR: press VR size on the toolbar (or type vr size in Find) - it makes the window the largest 16:9 that fits your main monitor and the size is remembered across restarts - and never press Fit before a VR session. More widgets = more pixels needed, not fewer. Two SteamVR settings help too, under Video: Advanced Supersample Filtering: Off (it softens flat overlays) and Overlay Render Quality: High.

๐Ÿ” Find - one box for "how do Iโ€ฆ" and "do it"#

Type a few letters into the Find box on the toolbar and a list drops down, best match first:

It uses the same forgiving heuristic as the Help panel's search: headings count most, an exact phrase beats scattered words, and letters-in-order still scores, so kneebord finds the kneeboard and stopwtch the stopwatch. Enter runs the top hit, โ†‘ โ†“ pick another, Esc clears. In VR the drawn cursor clicks results like anything else; typing needs a keyboard.

Hover tooltips - every widget, every control#

Hover anything in interactive mode and a tooltip says what it is and what a click does: each widget (one line on what it shows and how to handle it, plus its live CPU cost), and every control inside a widget - pit-service tiles, media buttons, the sim replay transport, timing tower rows, audio rows and bars, stopwatch and Now Playing buttons, the notes keyboard, FloDee actions, Icon Bar icons and launchers. WPF-hosted widgets (OBS, Driver Chat, Kneeboard position) carry their own tooltips on every button.

Turning them off: Media widget โ†’ SET โ†’ Hover tooltips. One switch for all of them; the Find box and the in-app Help still work with tooltips off. They are interactive-mode only: the moment you go clickthrough (F12) tooltips stop, and any tip left open closes, and the same goes for the drawn cursor - in clickthrough the pointer belongs to the sim and the overlay draws nothing at it.

Mouse โ€” in the overlay (interactive mode; F12 first)#

GestureAction
Drag a widget's bodyMove it
Drag a widget's edge/cornerResize it (opposite edge anchored)
Drag the window's outer edge (~10 px)Resize the whole overlay
Drag empty spaceMove the whole overlay window
Ctrl+wheelZoom the entire overlay
Alt+wheel over a widgetFade that widget (5โ€“100%; sliders reach true 0)
Shift+wheel over a widgetFade just its background โ€” gauges/text stay solid
Right-click any widgetContext menu, drawn inside the overlay so it shows in the headset too: Properties (desktop window) ยท Properties here (VR-friendly) ยท Show background ยท Bring to front / Send to back ยท Undo last change ยท Remove. Track Map adds saved-track, community-library and map-view pages (โ€น back returns). Wheel scrolls long lists; Esc or the X closes it.
Click a Timing rowSelect that driver as differential opponent
Click the Timing titleToggle full field โ†” relative-5 view
Click the Track Map titleCycle map modes (All / Relative-5 / Pace / Classes)
Click the Setup panelSnapshot baseline A for A-vs-current comparison
Plain wheel over TimingScroll the field

Group movement#

GestureAction
Ctrl+click widgetsAdd/remove each from the group (outlined)
Ctrl+drag on empty spaceRubber-band select everything in the box
โฌš Group toolbar toggleSame rubber-band without the keyboard (VR-friendly)
Drag any outlined widgetMove the whole group together (formation locked, edges clamp)
Click empty spaceClear the group
Drag an outlined widget's edgeResize the whole group โ€” proportionally, as one bounding box
Ctrl while resizing a groupSame-amount instead: every widget changes by the same pixels and stays put

Resizing a group#

Drag the edge or corner of any outlined widget and the whole group resizes:

Ctrl is read live, so you can switch between the two mid-drag. Shrinking stops as a group: the smallest widget hits the minimum size and the whole group stops rather than some widgets collapsing while others keep going. Snapping is off during a group resize, the same as during a group move โ€” it would fight the formation.

Fit#

The Fit button packs nothing and rearranges nothing โ€” it slides the whole arrangement to the top-left and shrinks the window to hug it. Every widget keeps its exact on-screen pixels; only the empty border disappears.

Editing made VR-friendly#

Editing in the headset used to be much harder than on the monitor. Two things caused it: the resize edges were a fixed 14 surface pixels โ€” about 2.6 mm of physical kneeboard panel โ€” and they were invisible. Both are fixed, and every part is adjustable in SET โ†’ EDITING & VR ERGONOMICS.

FeatureWhat it doesDefault
Resize handlesEight visible grab handles (4 solid corners, 4 hollow edge midpoints) on whichever widget is under the cursor. Drawn at exactly the grab-zone size, so what you see is what you can hit.On
Grab zoneHow close to an edge counts as "resize", in surface pixels. 8โ€“72.28
Sticky dragClick once to pick a widget up, move with the button released, click again to drop. Releasing the button mid-drag can't strand a widget.Off
SnapWidget edges and centres snap to other widgets and to the surface's edges, thirds and centre lines โ€” so you stop needing precise pointing.On
Snap distanceHow close before it snaps, in surface pixels.12
Alignment guidesGreen lines showing exactly which edge or centre a drag snapped to.On
Pin the toolbarThe toolbar normally docks onto the Control Bar widget, which lives in the layout โ€” so every preset puts it somewhere different and it seems to wander. Pinning fixes it to one spot no preset can move.Off

Group moves are deliberately not snapped โ€” snapping one member would break the formation the group keeps.

Overlapping widgets โ€” grabbing the right one#

Stacking widgets on top of each other - the gear digit over the brake and throttle bars, say - is a perfectly good way to build a dash, and it used to make editing miserable: every click grabbed the wrong one, and the only way to reach the bottom widget was to move everything off it. Since 2026-09-20 the answer is that you never have to hit the right widget with the pointer at all:

๐ŸŽฒ Random layout#

A button in the Layout Designer builds a complete layout at random - not random noise: each press picks a discipline (Endurance, Sprint, Oval, Time trial, VR cockpit, Drift / rally), drops in the widgets that discipline actually needs, packs them so nothing overlaps, and adds a couple of the discipline's optional extras plus a few style choices (panel opacity, gradient bars, marks, colour-only spotters, auto-scaled g). The status line under the list says what it built and why. It replaces what is on the canvas (Undo brings the old one back) and names the preset "Random <discipline> <stamp>", so Save keeps it. Edit it, or press again.

Save and Save as#

The toolbar has Save and Save as... (2026-09-23). Save overwrites the preset the overlay is showing, no dialog - if what is showing is a built-in or has never been saved it falls through to Save as, so nothing is ever created or lost silently. Save as asks for a name and puts the date/time stamp AFTER it ("Bristol night 20260923_1412"), so the preset list sorts and reads by what you called it. Pick an existing preset in the dialog to overwrite it.

Recentring the VR view (the car around you, not the kneeboard)#

Under the SteamVR runtime, holding the Meta button recentres the Oculus space, which SteamVR ignores - so the car never moves and the SteamVR dashboard is out of reach without controllers. RaceVisor now does it for you: Hotkeys โ†’ "SteamVR: recentre the view" binds it to any wheel button (or Find โ†’ "recentre"). It resets SteamVR's seated position on your current head pose, which is the space iRacing sits in under SteamVR, exactly what the dashboard's Recenter does. Needs SteamVR running with RaceVisor attached to it (the VR Performance widget shows that). Not to be confused with the Kneeboard Position widget's Recenter, which moves the kneeboard to your head. Under the Meta Link runtime the Meta button works as expected and this hotkey has nothing to do.

Properties here (VR-friendly)#

Right-click a widget โ†’ Properties here. This draws the properties panel inside the overlay, so it is visible in the headset without OpenKneeboard switching tabs away from the dash you are editing โ€” which is what made the normal Properties window awkward in VR.

The whole right-click menu is drawn inside the overlay the same way (2026-09-01), so widget editing finally works end-to-end from the headset. Two known limitations:

What Ctrl+Z actually undoes (read this if undo "never works" for you)#

Undo covers layout changes: widget moves, resizes, group moves, add/remove, everything changed through either Properties panel or the right-click menu, Alt/Shift+wheel fades, the opacity rescue, preset loads and resets. One press = one step back; the status line says how many steps remain.

It does not cover things that are not layout: OpenKneeboard's pose sliders (those have their own Reload / Original buttons), Media settings, or view-mode cycles like the timing tower's full-field/relative toggle.

The trap: Ctrl+Z only registers while the overlay window has DESKTOP focus, in interactive mode. Click the sim, the desktop, or anything else first and the keypress goes there instead - silently. From inside the headset the overlay almost never has desktop focus, which is why undo can feel like it never works in VR. The fix is the "Undo last change" row in the right-click menu - it needs no keyboard and no focus, so it works from the headset.

It carries opacity, background, font size, the accent swatches, and the no-background toggle, with oversized slider knobs meant to be hit with the drawn cursor. Drag its header to move it; X closes it. The regular Propertiesโ€ฆ (window) entry is still there and still has everything, including the font picker.

Per-widget font#

Every widget has its own Font picker in Properties โ€” any typeface installed on your PC, or Default (Segoe UI). Font size stays a separate slider (60โ€“180%), so you can change typeface and size independently. A layout that names a font you don't have falls back to Segoe UI instead of failing, so presets from other people always render.

Build expiry (pre-1.0)#

Pre-1.0 builds age out on purpose, so a known-buggy copy someone downloaded once does not stay in use forever:

The build date is stamped at compile time, and the banner is drawn in the overlay so it is visible in the headset too, not just on the monitor. Public builds only ever warn; they are never disabled, so a copy you downloaded once will still run months later.

The opacity system (three independent layers)#

ControlScopeWhere
Overlay backdrop sliderThe dark canvas behind everything (0 = widgets float directly on the sim)Toolbar โš™ slider, saved per layout
Widget OpacityThe whole widget, content included (0 = invisible)Toolbox/Designer slider, or Alt+wheel
Background OnlyJust the widget's panel box โ€” content stays solidToolbox/Designer slider, or Shift+wheel
Borderless checkboxHard-off for the panel backgroundToolbox/Designer
Transparent widget backgrounds (all)One click strips every panel in the layoutToolbox

Everything is per-widget, per-layout, saved in your own file โ€” your ghosted-HUD taste never affects anyone else's presets. Ghosted too far? Ctrl+Alt+Shift+1.

Note: in interactive mode, background-less widgets show a faint gray placeholder so you can grab them โ€” it disappears when you Lock.

Sims#

Sim support beyond iRacing is in active development and changes constantly until it stabilises. Treat anything below as work in progress, not a promise: behaviour, and which channels appear, can change from build to build.

RaceVisor reads whichever sim is running and switches automatically as they open and close. Order of preference: iRacing -> Assetto Corsa / ACC -> Automobilista 2 -> rFactor 2 -> demo data. iRacing wins a tie because it is the only one that publishes opponents, deltas and a full session description, so every widget works.

Where each sim stands today#

SimOn the monitorIn VR
iRacingfully supportedfully supported - the setup RaceVisor is built around
Assetto Corsaworkingworking - but read the three VR traps below (DRIVE button, window focus, race hold)
ACCworkingworking - native VR, none of the AC traps apply
Automobilista 2workingworks, but the kneeboard may not appear - see below
rFactor 2working, needs a plugin onceworking - verified 2026-08-31; see its gotchas below

"Working on the monitor" means telemetry was read correctly and the widgets drove from it. Anything marked untested simply has not been sat in front of - it is not a known failure.

If you only care about VR, iRacing is the one to trust. The other sims each pick their own VR plumbing, and that is where the trouble lives - none of it is RaceVisor code.

The one rule that catches everyone: exclusive fullscreen#

A sim running in exclusive fullscreen will hide the overlay. Windows will not draw any other window over an exclusive-fullscreen game - not RaceVisor, not Steam's overlay, nothing. The overlay is still running and still reading telemetry; you just cannot see it.

Set the sim to windowed or borderless and it appears immediately:

SimWhere
iRacingin-game graphics options
Assetto Corsathe AC Launcher Video tab, or FULLSCREEN=0 in Documents\Assetto Corsa\cfg\video.ini. The in-game F11 toggle does NOT persist - the launcher owns that file. Content Manager offers true borderless.
ACCin-game video settings
rFactor 2in-game Display settings (remember to press Apply), or WindowedMode=1 + Borderless=1 in UserData\Config_DX11.ini with the game closed - rF2 rewrites that file on exit

None of this applies in VR: the kneeboard is composited by OpenKneeboard, so the sim's desktop display mode is irrelevant.

Also check which monitor it is on. The overlay reopens wherever you last left it. An overlay sitting on a second screen while the sim is on the first looks exactly like a broken overlay.

Assetto Corsa and Assetto Corsa Competizione#

Nothing to install or configure - both publish shared memory, and because ACC is an AC spin-off that kept the same interface, one code path serves both.

You get: rpm, gear, speed, throttle, brake, steering, fuel (litres and %), lap number and lap percentage, lap times, position, tyre temperatures, tyre wear, tyre pressures and g-force. The car's real rev limit drives the shift lights.

You do not get, because AC does not publish it: other cars (so the radar, timing tower and gap widgets stay empty), the best-lap delta (it shows -- rather than inventing one), and clutch position.

Automobilista 2 - one setting, off by default#

Settings -> System -> Shared Memory must be set to "Project CARS 2". It ships off, and with it off RaceVisor cannot tell AMS2 apart from AMS2 not running at all - you get demo data and no warning. This is the single most common "AMS2 does nothing" cause.

Set the game to Windowed or Borderless as well. In exclusive fullscreen AMS2 gets ejected from its display mode and will not restore from the taskbar.

AMS2 uses the Project CARS 2 shared-memory layout, so you get rpm, gear, speed, throttle, brake, clutch, fuel, lap and sector times, position, tyre temperatures and g-force, plus opponents.

VR: what actually has to be true#

The dash reaches the headset through OpenKneeboard, which composites it over the sim. RaceVisor itself is headset-agnostic - anything OpenKneeboard supports (SteamVR/OpenVR, OpenXR) will do, including Index, Reverb, Vive, Pimax, Quest over Link or Virtual Desktop, and Valve's Steam Frame in PC-VR (streaming) mode - it is a SteamVR headset, so it takes the same SteamVR + OpenKneeboard chain with none of the Quest/Meta-runtime gotchas below. Not in the Frame's standalone mode (nothing Windows runs there, the sims included). Not yet hands-on verified on a Frame.

Four things must be right, and every one of them cost the author a session to find:

1. OpenKneeboard -> Settings -> VR -> SteamVR support must be enabled if the sim runs through SteamVR/OpenVR. It is off by default. With it off the kneeboard never injects, nothing appears in the headset, and recentering does nothing at all. 2. OpenKneeboard needs a Window Capture tab pointed at the RaceVisor window, and that is the tab to select in the headset - not OpenKneeboard's own dashboard tab. 3. Start OpenKneeboard before the sim. It injects at game launch; starting it afterwards does nothing until the sim is restarted. 4. The Rendering API in OpenKneeboard's game entry must match the API the sim actually uses. Sims do not all agree, and the label on the Steam launch option is not evidence.

5. Trails / ghosting on the kneeboard (and everything else) while the GPU sits idle = the sim is being throttled and reprojected. When the VR runtime decides the sim finishes its frames too late, it holds the sim to half rate and fills in with synthesized, warped frames. High-contrast flat things smear worst, so the kneeboard's big gear digit is where you see it first. RaceVisor's VR Performance widget calls the state out in red ("SteamVR THROTTLING"). Two causes seen on the author's rig, 2026-09-15:

6. Anything that grabs keyboard focus while you race can cost you the sim's input - Assetto Corsa in particular reads the wheel only while its window has focus. A desktop helper can do that from behind your back: FloDee's floater, for one, takes focus the moment the mouse pointer rests on it, so a pointer parked on the dot while you are in the headset hands focus to FloDee. Park the pointer somewhere empty, or close FloDee before driving - the โ—‰ icon / FloDee widget does that from inside the dash. 7. A desktop app that repaints a transparent window nonstop halves the kneeboard's frame rate. OpenKneeboard shows whatever the overlay window last drew, and the overlay draws once per desktop frame tick. A layered (see-through) window that redraws itself continuously - FloDee with Floater colour rotate, Floater border rotate or Panel colour rotate switched on is the case measured (2026-09-15: overlay ticks fell from 62/s to 29/s the moment FloDee ran, and dipped to 12-17/s in stretches) - makes the kneeboard feel laggy and jerky, worst with Follow head on, while the sim itself stays perfectly smooth. Turn those colour-rotate options off in FloDee's settings (or close FloDee while racing; FloDee releases after 2026-09-15 pause those effects by themselves while a sim is in front or the mouse and keyboard have been idle 30 s). Verified on track after the fix: the overlay held the monitor's full 75 ticks/s, Follow head included. RaceVisor's opt-in perf log (Documents\RaceVisor\perflog.on) prints "WPF ticks/s" so you can see the tick rate directly. Also fixed the same day: the overlay's own refresh gate lost a quarter of the ticks when set to 60 Hz; settings of 55 Hz and above now render every tick.

8. Headset frozen on the last frame after the sim closes (SteamVR runtime + Quest Link). The picture in the headset stops dead, the desktop shows SteamVR Home with the kneeboard still up, and nothing recovers on its own. Seen twice in three sessions on the author's rig, 2026-09-17. The logs say what it is: SteamVR's compositor prints "WaitForAcquire timed out - the driver did not take the sync texture" every frame and vrserver prints "oculus: OVR Error" every frame - SteamVR's bridge to the Meta runtime has wedged. This time it followed a half-second USB re-enumeration of the Quest (the Oculus audio device vanished and came back) and the headset being lifted off and on. The Quest itself is NOT hung: Link keeps streaming the stuck frame. So do not hard-reset the headset - restart SteamVR on the PC instead: Recover-SteamVR.ps1 in the release workspace kills SteamVR and starts it again, and the picture is back in seconds. The real fix is to stop using SteamVR as the OpenXR runtime for Quest over Link at all: in the Meta Quest Link app set Meta Quest Link as the active OpenXR runtime (which the Passthrough Portal needs anyway) and keep SteamVR only for the VR View filming route. A USB blip preceded this one, so also try another port or cable.

Quest / Link users, note: a sim may quietly choose the native Oculus (LibOVR) API when you are on Link, even with SteamVR running. OpenKneeboard's Oculus path is legacy, and on a current Meta runtime it can black out the headset entirely while the desktop mirror keeps working. If the headset goes black the moment VR starts, set that game's Rendering API to No overlay to confirm, and expect no kneeboard in that sim until OpenKneeboard's Oculus support is fixed. Headsets with no Oculus runtime at all - Index, Reverb, Vive - do not hit this, because the sim falls back to SteamVR/OpenXR.

Assetto Corsa in VR - the three things that look like dead pedals but are not (each one cost the author hours):

1. You land at the pit/setup screen and must click DRIVE. In VR that screen is easy to miss entirely - the session looks started, the engine note plays, and the car sits held with the brake on ignoring every input, because it is not yours yet. Point the mouse at DRIVE in the headset view and click. 2. AC only reads the wheel while its desktop window has focus. Click anything else on the desktop - even once - and every pedal and button goes dead until you click AC's window again. On the monitor you notice immediately; in VR it just looks broken. 3. In a RACE session the AI holds your car with the brake on until the start sequence hands over. Telemetry shows brake pinned at 1.0 and a fixed rpm - that is the hold, not a fault. Test in PRACTICE first.

Most of the community runs Content Manager instead of the stock launcher - not required for VR to work, but it puts session, controls and VR mode in one place. Content Manager is a third-party launcher by x4fab, free from acstuff.club/app (a paid key unlocks extras; the free Lite version covers everything mentioned here).

None of the above affects the monitor overlay, which works regardless.

rFactor 2 - needs a plugin, once#

rF2 publishes nothing to third parties on its own. It needs The Iron Wolf's rF2 Shared Memory Map Plugin - the same one Crew Chief and TinyPedal use. Also covers Le Mans Ultimate.

1. Put rFactor2SharedMemoryMapPlugin64.dll in rFactor 2\Bin64\Plugins\ 2. Launch rF2 once and quit fully - that is what registers it 3. With rF2 closed, open UserData\player\CustomPluginVariables.JSON and set the plugin's " Enabled" to 1. Note the leading space in that key name - the one without it does nothing. rF2 rewrites this file when it exits, so editing it while the game runs is wasted. 4. Start rF2. Check_rF2_Telemetry.ps1 confirms the plugin is publishing.

rF2 gives everything AC does plus opponents (up to 128 cars), so the radar, timing tower and track map work there. Its gear numbering already matches RaceVisor, and it reports the true rev limit per car.

rFactor 2 gotchas (every one verified the hard way):

Launch scripts you can copy and adapt#

Getting a VR session up is mostly about starting things in the right order. These scripts are plain PowerShell - save them as .ps1 files, adjust the paths in the CONFIG block at the top, and run them from a shortcut or terminal. Everything you might need to change is in that block; the logic below it should not need touching.

VR session launcher#

Starts the whole chain in the order that works: wheel software -> SteamVR -> OpenKneeboard -> RaceVisor -> the sim. Each step is skipped if the program is already running.

```powershell

$WheelSoftware = "C:\Program Files\LGHUB\lghub.exe" # G HUB / SIMAGIC / whatever your wheel needs; "" to skip $SteamVR = "C:\Program Files (x86)\Steam\steamapps\common\SteamVR\bin\win64\vrstartup.exe" $OpenKneeboard = "C:\Program Files\OpenKneeboard\bin\OpenKneeboardApp.exe" $RaceVisor = "C:\Path\To\RaceVisor.exe" # wherever you put it $SimSteamId = "244210" # Steam app id: iRacing 266410, AC 244210, ACC 805550, AMS2 1066890, rF2 365960 $NeedSteamVR = $true # $false for sims that do not use SteamVR/OpenVR

function Start-IfNeeded($exe, $procName) { if ($exe -and -not (Get-Process $procName -ErrorAction SilentlyContinue)) { Start-Process $exe return $true } return $false }

if ($WheelSoftware) { Start-IfNeeded $WheelSoftware ([IO.Path]::GetFileNameWithoutExtension($WheelSoftware)) | Out-Null; Start-Sleep 8 } if ($NeedSteamVR) { if (Start-IfNeeded $SteamVR "vrmonitor") { while (-not (Get-Process vrmonitor -ErrorAction SilentlyContinue)) { Start-Sleep 3 } Start-Sleep 8 # let the compositor settle before anything tries to inject } } Start-IfNeeded $OpenKneeboard "OpenKneeboardApp" | Out-Null; Start-Sleep 6 # BEFORE the sim - it injects at game launch Start-IfNeeded $RaceVisor ([IO.Path]::GetFileNameWithoutExtension($RaceVisor)) | Out-Null; Start-Sleep 4 Start-Process "steam://rungameid/$SimSteamId" Write-Host "Chain up. Remember: click DRIVE (AC/rF2), keep the sim window focused, headset on before it loads." ```

To adapt it: change the paths, change $SimSteamId, and set $NeedSteamVR = $false for a sim running native Oculus or OpenXR-on-Meta. Add extra programs (OBS, crew chief, etc.) as more Start-IfNeeded lines - order matters, OpenKneeboard must beat the sim.

Telemetry sanity check#

When the dash shows nothing, this settles in seconds whether the sim is even publishing. Run it while the sim is on track; each section prints live values or "absent".

```powershell

try { $m=[IO.MemoryMappedFiles.MemoryMappedFile]::OpenExisting('Local\acpmf_physics','Read') $a=$m.CreateViewAccessor(0,0,'Read') "AC/ACC live: rpm={0} throttle={1:N2} brake={2:N2}" -f $a.ReadInt32(20),$a.ReadSingle(4),$a.ReadSingle(8) $a.Dispose();$m.Dispose() } catch { "AC/ACC: absent (not running, or not in a session)" }

try { $m=[IO.MemoryMappedFiles.MemoryMappedFile]::OpenExisting('$pcars2$','Read') "AMS2: publishing (remember Shared Memory = 'Project CARS 2' in its settings)" $m.Dispose() } catch { "AMS2: absent (game closed, or Shared Memory setting is OFF - it ships off!)" }

try { $m=[IO.MemoryMappedFiles.MemoryMappedFile]::OpenExisting('$rFactor2SMMP_Telemetry$','Read') $a=$m.CreateViewAccessor(0,0,'Read') "rF2: publishing, {0} vehicles in session" -f $a.ReadInt32(12) $a.Dispose();$m.Dispose() } catch { "rF2: absent (game closed, or the shared-memory plugin is not installed/enabled)" } ```

How to read the results: absent while the sim is on track means the sim-side setup is wrong (AMS2's shared-memory setting, rF2's plugin) - no overlay setting will help until that prints live values. Live values here but a frozen dash means the car is not actually yours yet (AC's DRIVE button, a race-start AI hold) or the game window lost focus.

Several instances at once#

RaceVisor has no single-instance lock: launch RaceVisor.exe as many times as you like (monitor overlay + headset overlay + an OBS feed, each on its own layout/preset). They share the same settings files and track cache; the community library syncs once per instance.

Presets#

Widgets#

RPM (cluster/horiz/vert) ยท Shift light ยท Gear ยท Speed (km/h / mph) ยท Inputs ยท Tires ยท Fuel & engine ยท Timing tower ยท Differential ยท Delta / Gap graphs ยท Tire wear trends ยท Fuel consumption ยท Setup comparison ยท Corner pace ยท G-force circle (with auto scale) ยท G Long bar / G Lateral bar (g as a sweeping centre-zero bar, vertical or horizontal) ยท Brake vs G / Throttle vs G (pedal beside the g it produced - shows a locking or spinning wheel) ยท Steering vs G (steering beside the lateral g it produced) ยท Steering bar ยท Spotter ยท Radar (with closing speed) ยท Pit Stop Planner (fuel to the end, litres to add, PIT THIS LAP) ยท Weather ยท Pit service (sends real pit commands) ยท Media ยท Track map ยท Control Bar ยท Track Progress (Horiz / Vert) - a flat/linear track map: the lap unrolled into a straight strip with start-finish at both ends, quarter-lap ticks, and every car on track placed by lap distance. You are the fat accent marker, the selected opponent gets a green ring, cars in the pits go dim. Because it needs no track shape it works on lap one of a track you have never driven, which the Track Map cannot. Horizontal runs left to right, vertical runs bottom to top. The original Track Map is unchanged - these are extra widgets, not a replacement. ยท Gear (RPM + brake color) (one big digit that is also a rev gauge: it fills from the bottom up with rpm / redline, blue at the bottom through the cold-to-hot gradient to the colour for that rpm at the fill line, the rest of the digit dimmed; it strobes red at the shift point, and brake pressure pulls the whole digit toward pure red - 100% brake = 255,0,0, 0% leaves the rpm colours alone; N and R keep the warn color. Properties -> Bar marks & gradient -> Gradient fill off gives the older single-colour digit that just changes hue with rpm) ยท Steering wheel (round, turns with your real wheel, angle in degrees; the Inputs widget carries the same wheel plus % values on its pedal bars) ยท Clutch / Brake / Throttle (one pedal each, big % readout; pick the (Horiz) or (Vert) palette entry, or just resize - wider than tall lies flat, taller than wide stands up; force it in Properties โ†’ Pedal orientation) ยท Spotter Left / Right / Clear-Hold (the spotter split into three lamps you can park where you look: LEFT and RIGHT light amber for one car, red for two or 3-wide; the status lamp shows HOLD while anyone is alongside, CLEAR once both sides have been quiet for the set delay and no car is within the set range, CLOSE in between) ยท Clocks: Local (wall time + date), Track (sim time of day), Session (elapsed), Remaining, All-in-one, and Clock (Analog) - a proper dial with hour, minute and sweeping second hands showing local time, date underneath when the box is tall enough ยท Stopwatch (Analog) and Stopwatch (Digital + laps) - see Stopwatch below ยท Driver Chat (voice + text with other RaceVisor users, independent of the sim's comms - see its own section below).

Why the tire temps and wear never move while you drive: iRacing itself only refreshes the tire temperatures, wear and cold pressures it publishes to any telemetry app when you are stopped in your pit stall (and once more when you leave the garage). That is a deliberate anti-cheat in the sim - live tire data is not available to overlays in official sessions - so the Tires widget shows the last pit-stall reading, which is why it looks different every time you check but never changes in front of you. Nothing is stuck; the sim is not sending it. The other sims (AC, ACC, AMS2, rF2) publish live tire data and the widget moves normally.

Widget Properties (right-click โ†’ Propertiesโ€ฆ)#

Every widget has its own control panel: opacity, background-only opacity, font size (60โ€“180%), font family (any installed typeface), accent color (hex + swatches), outline text, borderless, shadow, remove.

Outline text draws a dark outline behind everything the widget writes. Turn it on when light text sits over a pale sky, a bright livery or a busy wallpaper โ€” a white gear digit over a blue sky is otherwise almost unreadable. The outline is a true stroke of the glyph shapes with round corners (since 2026-09-23 - the old one was a ring of offset copies and scalloped every corner), in any colour and width you set. It costs a little extra draw time on text-heavy widgets (the hover tooltip's ms/frame readout will show it), which is why it is per-widget and off by default.

Drop shadow puts a soft shadow behind the widget's panel and behind every character it writes. Angle (0 = right, 90 = down, 180 = left, 270 = up) and Distance (surface pixels, 0 = directly behind, i.e. invisible) move it; the default is 45ยฐ / 4 px, down and to the right. Text drawn straight over the sim with no panel gets the character shadow only, which is often all the separation it needs without the heavier outline.

Color dropper โ€” grab your team colors. Next to the accent swatches, โŠ• Pick color from screen samples any pixel on your desktop: click it, move the cursor over a livery, a logo, a sponsor page or another app, and the widget previews that color live as you move. Click to keep it, Esc to cancel and put the old color back. It reads the screen directly, so it is not limited to RaceVisor's own window. Edits apply live and save with the layout.

G-force meters get their own block: lock horizontal (ignore lateral - a pure accel/brake meter) or lock vertical (ignore accel/brake - a pure cornering meter), trail on/off, dot size (50% to 400% of the normal dot on the g circle - bigger for a small or far-away widget), peak hold on every g widget - the circle, the Long g and Lateral g bars and the Brake vs g / Throttle vs g bars (amber ticks at the highest g per direction plus the peak numbers; Hold peak for sets how long a peak stays, 1-30 s, before it bleeds off at a quarter g per second), flip up/down or left/right, full scale 1-5 g in half-g steps, auto scale (the outer ring follows the highest g of the last ~10 s, rounded up to the next half g, eased so it never jumps - a road car and an open-wheeler both fill the circle; the full-scale slider is ignored while it is on), and dot smoothing.

Spotter lamps get their own block: how long a lamp stays lit after the spotter goes quiet (default 0.5 s - kills flicker at the overlap line); for the Clear/Hold lamp also the quiet time before it says CLEAR (default 1 s) and the distance that must be car-free ahead and behind (default 10 m; 0 = trust the spotter alone). No words (colour only) turns a lamp into a plain colour block with nothing written on it - no LEFT / RIGHT / CLEAR / HOLD / 3-WIDE. Grey is spotter-off, green clear, amber a car alongside (or hold), red two cars or 3-wide. Faster to read out of the corner of your eye, and it still works shrunk to a thin strip along an edge.

Rotation - every widget (Properties -> Rotation): turn any widget about its own centre, 0 to 359 degrees clockwise. Drawing, resize handles and clicking all follow the angle, on the overlay and in the Layout Designer. The slider snaps to the step you pick (free, 5, 15, 30, 45 or 90 degrees) and the 0 / 90 / 180 / 270 buttons jump straight there. A vertical pedal bar at 90 is a horizontal one that fills the other way; a gear digit at 15 degrees matches a tilted wheel.

Bar marks & gradient - every sweeping bar (pedals, the g bars, Brake vs g, Throttle vs g, the horizontal and vertical rpm bars and the three bars inside Inputs): Properties -> Bar marks & gradient. The rpm bars are a cold-to-hot gradient from idle to the redline by default - untick Gradient fill there and they paint the accent colour flat instead. Marks puts a line across the bar every N percent (25 = marks at 25 / 50 / 75, the 50 line brighter), so you can see how far an analog pedal actually travelled instead of guessing from the fill; Number the marks prints the percentage beside each one when the widget is big enough. Gradient fill runs cold to hot like a heat map: blue at 0%, through cyan, green and yellow, to red at 100%. Pick a far colour instead (amber, green, cyan, purple, white) and it runs blue to that colour. The rpm bars, the cluster arc and the shift LEDs use the same cold-to-hot scale. Marks flip with Fill from the other end, so 25% is always a quarter of the travel.

Over-rev threshold (Properties -> At the shift point -> Over-rev at, on the rpm cluster, both rpm bars, the shift light and Gear (RPM + brake color)): where this widget starts its flash / solid light, as a percentage of the car's redline (50-120%). Far left = Auto, the car's own shift rpm from the session data, which is the default. Each widget has its own, so a shift light can fire early as a warning while the gear digit waits for the real shift point.

Rpm bars - the over-rev light (Properties -> At the shift point -> Over-rev light at the end of the bar): the round light at the end of the horizontal / vertical rpm bar can be switched off. The bar then takes the whole box and still strobes red past the shift point on its own.

G-force bars (g as a sweeping bar)#

The g circle shows both axes at once; sometimes you want ONE axis as a bar you can read like a pedal. G Long bar is braking and acceleration, G Lateral bar is cornering. Both are centre-zero: the fill grows out of the middle toward whichever way the force pushes, with a centre line and, with marks on, ticks outward in both directions (50 = half of full scale each way). Palette entries come in (Vert) and (Horiz); Fill from the other end flips which way counts as positive, so up/down/left/right are all reachable. Range, auto scale, the flip switches and smoothing are shared with the g circle (same Properties block, minus the circle-only rows), so every g widget on a layout agrees.

Brake vs G is the one to put on a wet track. Two lanes sharing one sweep: the pedal and the deceleration it actually produced (longitudinal g, decel only, on the same scale as the g bars). Push harder and watch the second lane: when the pedal keeps rising and the g lane FALLS, the tyres have locked - which is exactly the thing you cannot feel through a wheel. The widget frames itself red and says LOCKING when hard pedal meets a g that has dropped well below its own recent best, and clears as soon as the g comes back. Match your braking to the g lane and you are braking at the limit the surface allows. Lay it over the plain Brake bar if you like the pedal big and the g small.

Throttle vs G is the same idea the other way round: the throttle pedal beside the acceleration it actually produced. Feed in more throttle and watch the g lane - when it falls while the pedal keeps rising the driven wheels are spinning, and the widget frames red and says SPINNING. That is the traction limit out of a slow corner, in the wet or on cold tyres, made visible. Every g widget - the circle, both g bars, Brake vs G and Throttle vs G - has the same auto scale switch, so pick it per widget or leave the range fixed.

Steering vs G does for cornering what Brake vs G does for braking. Two centre-zero bars sharing one sweep: the steering wheel on top and the lateral g it produced under it. Turn left and both bars sweep left; turn right and both sweep right. Wind on more lock and watch the g bar - when the steering keeps growing and the g does not, the front tyres have stopped answering. Palette entries come in (Horiz) (two rows) and (Vert) (two columns). In Properties: Lateral g bar first swaps the two bars; Invert mirrors the steering bar and Flip left / right mirrors the g bar, for a sim that publishes either one the other way round; Auto scale steering (on by default) lets full scale follow the most lock you used in the last 10 seconds, or turn it off and set Full lock yourself (30-900 degrees each way); the g bar has the usual range, auto scale, smoothing and peak hold; Gradient fill can go on both bars or on just one (Gradient on); tick marks and Fill from the other end work as on every other bar.

Steering bar is the steering lane alone, (Horiz) or (Vert), with the same steering options. Its partner as a separate widget is the G Lateral bar above, so you can place and size the two independently instead of using the combined widget.

Flash or just turn on (Properties -> At the shift point): every widget that reacts to the shift point - the cluster, both rpm bars, the shift light and Gear (RPM + brake color) - can strobe as before, or simply light solid the whole time you are past the shift rpm. Per widget, so one gauge can flash while its neighbour stays steady.

Pedal threshold flash (Properties -> Threshold flash, on Clutch / Brake / Throttle): tick it and set a percent (default 90%). At or above that the whole widget flashes - the bar strobes red and a red frame pulses round the panel - and it keeps flashing the entire time you are above the threshold, rather than blipping once as you cross it. Meant to be caught in peripheral vision.

All five rpm meters get a peak-rpm marker (Properties -> Peak rpm marker): Off, Hold for a few seconds (0.5-10 s after the peak, default 2), or Keep the highest until reset. Show only above is the threshold: the marker stays hidden until the peak is at least that percentage of the car's redline (always, by default), so it ignores the low peaks from pootling around and only reports the ones that matter near the shift point. The cluster dial marks it with a white tick (the red tick stays the redline) and prints the number beside the live rpm; the horizontal and vertical bars get a white line across them; Gear (RPM + brake color) gets a white line across the digit at the peak's height on its gauge scale plus the number underneath; the single shift light, having no scale, wears a ring tinted with the gradient colour that rpm reached. Every rpm widget shares one peak, so two gauges can never disagree - only the display rule is per widget, which is what lets one gauge hold until reset while another forgets after two seconds. Reset it from the button in Properties, the Reset peak rpm Icon Bar icon, or the rebindable global hotkey.

Radar widgets get their own block: car blip width and length (0.5-2.5x), the distance at which a car counts as alongside (slides into its lane, border warning - default 7 m), the distance at which it clears again (default 10 m, never less than the first, so blips do not flicker at the boundary), and Swap left and right if the spotter's sides read backwards to you. Since 2026-09-16 the radar also reads closing speed: a blip behind you that is gaining at more than about 5 km/h turns amber, and the strip under the plot names the nearest car ahead and behind with the distance and "closing 9 km/h" / "pulling away 4 km/h" - the difference between a car that is racing you and one that is just there.

Pit Stop Planner (fuel to the end, pit this lap)#

The question you leave the headset to do maths for. One panel, one verdict line at the top:

Under it: fuel now, use per lap (measured from the fuel level at each lap change, averaged over the last three clean laps - "(est)" means it is still using the sim's instantaneous rate until two laps exist), laps in the tank, laps to go (from the lap count in a lap-limited session, else time left รท lap time, marked "timed"), fuel to finish including the reserve, add at stop in litres (next to the amount currently set in the sim's pit menu, amber when that is short), and the worst tyre's remaining wear. The reserve is one lap by default (Properties โ†’ Pit reserve, 0 to 5). Tyre wear, like tyre temps, only updates when the sim reports it - in iRacing that is in the pit stall.

Icon Bar widget#

A strip of tiny always-available action icons โ€” place it anywhere, size it, fade it like any widget, and it stays clickable even in clickthrough mode while you race.

Default icons: ๐ŸŽจ Designer ยท โŒจ Hotkeys ยท ๐Ÿ”’/๐Ÿ”“ Lock ยท โœ• Close RaceVisor ยท โ—€ โ–ถ preset spinner ยท โ˜… Favorite preset (left-click loads it, right-click sets the current preset as favorite). The โš™ gear (interactive mode only) opens Properties, where checkboxes add/remove icons. Fully opaque by default โ€” fade it only if you choose to. Optional icons: ๐ŸŽฏ Recenter kneeboard ยท ๐ŸŒ‘ Fade ยท โ†ป Reset peak rpm ยท ๐Ÿ‘“ Kneeboard on/off ยท ? Help ยท ๐Ÿ’ฌ Driver Chat text box ยท ๐ŸŽ™ Driver Chat open mic on/off ยท โฑ Stopwatch start/stop (turns red while running) ยท ๐Ÿ Stopwatch lap ยท โ†บ Stopwatch reset ยท โฏ โญ โฎ Media play/pause, next, previous (system media keys - drive whichever player has the music).

Launchers - start any app from the bar. In the Icon Bar's Properties, the Launchers box takes one line per launcher: Label | path | arguments (label and arguments optional). Each line becomes a purple icon showing the label's first two letters; clicking it starts that program, script, shortcut or file - Crew Chief, OBS, SimHub, a PowerShell script, a setup PDF. Add app / fileโ€ฆ browses for one; Import FloDee shortcuts pulls every app and script on your FloDee user grid in one go (folders are skipped), so the two share one launch list. Hover an icon for its label and path. Works in clickthrough like every Icon Bar icon.

Window Portal (any desktop window inside the dash)#

The reason VR racers take the headset off: the browser, Discord, OBS, Crew Chief, a notes file - all on the monitor. The Window Portal widget shows any of them live inside the dash, so it floats in the cockpit with everything else. Add as many portals as you like, one window each.

A Window Portal shows a window. The Passthrough Portal shows the real world: the Quest's colour cameras, through a hole of any shape, exactly where you put it on the kneeboard - your keyboard, the button box, a coffee cup. On the monitor it is only an outline; the picture is composited inside the headset by RaceVisor's own OpenXR API layer, which sits between the sim and the runtime, switches on Meta's passthrough on the sim's behalf, and draws the camera feed on a mesh in the shape you drew. The sim itself never knows.

What it needs, and this is the catch: 1. Meta Quest Link as the active OpenXR runtime (Meta Quest Link app โ†’ Settings โ†’ General โ†’ Set Meta Quest Link as active). SteamVR's runtime has no passthrough API, so the portal is simply absent under SteamVR - nothing breaks, it just does not draw. Virtual Desktop's runtime exposes the same Meta extension on recent versions. 2. Passthrough over Link switched on in the Meta Quest Link app (Settings โ†’ Beta). 3. The layer installed once: Find box โ†’ "passthrough" โ†’ Install (one UAC prompt; it registers %LOCALAPPDATA%\RaceVisor\PassthroughLayer as an implicit OpenXR layer, like OpenKneeboard does). "Remove" in the same place takes it out. Restart the sim after either. 4. A Quest 2 / 3 / 3S / Pro. Headsets without cameras that reach the PC have nothing to show.

Then: add Passthrough Portal from the palette, size and place it on the kneeboard, and right-click โ†’ Draw mask for any shape (or leave it as the whole box). The widget says on its face whether the layer is installed. It follows the kneeboard: RaceVisor writes the portal's position on the kneeboard's plane (from the Kneeboard Position widget's pose) to %LOCALAPPDATA%\RaceVisor\passthrough.json, and every Recenter / Follow head re-origins the portal and the kneeboard at the same instant, so they stay together. If the hole sits a little off the keys, nudge the widget - small differences in how OpenKneeboard fits the picture show up as a small offset.

Why the two portals both exist: the Window Portal + a webcam works on every headset and every runtime, sharper than passthrough; the Passthrough Portal needs no webcam and shows your real hands, but only on Quest over Link. A log of what the layer did is at %LOCALAPPDATA%\RaceVisor\passthrough-layer.log.

See your real keyboard in VR (keyboard cam): point any USB webcam at the keyboard, open the Windows Camera app (it can sit behind the sim), add a Window Portal, Pick window โ†’ Camera, then crop it down to the keys. You now have a live, readable view of your hands and keycaps in the cockpit, on its own layout or in a corner of the kneeboard. Sharper and in colour, unlike the Quest's grey passthrough (double-tap the headset), which still works for a quick glance.

Audio widget (devices, volumes, mic mute - without leaving the headset)#

Which device Windows sends the sim to, what you hear in the headset, how loud Discord is next to the engine: all of that lives in Windows' sound settings, on the monitor. The Audio widget puts it in the dash. Three blocks:

Every row has a volume bar - click anywhere on it to set the level (5% steps, easy to hit in VR) - and a mute button at the end (โ™ช = on, โœ• = muted). Everything applies instantly and is plain Windows state, so the Windows sound panel and the widget always agree. The widget refreshes its device list once a second, so a headset that just connected appears on its own.

Like the Media widget, it is a hot island: with Hot zones on (Media settings) it stays clickable in clickthrough; otherwise unlock with F12 first.

VR Performance widget (what the headset is really getting)#

Tuning VR graphics is done blind - "it feels stuttery" is the only readout. The VR Performance widget shows SteamVR's own frame timing in the cockpit, next to the settings that move it:

Needs SteamVR running (it does not have to be the OpenXR runtime, same as the head-pose features) and a VR app presenting frames. Without either it says so and just shows RaceVisor's draw cost.

Notes widget (pit notes per track, typed in the headset)#

The Notepad on the monitor - brake markers, fuel per lap, "T4 is treacherous in the rain" - moves into the cockpit. The Notes widget keeps one note per track (named after the track and layout the sim reports) plus a General note; the header button flips between them.

FloDee widget (the author's desktop companion, driven from the dash)#

RaceVisor and FloDee are from the same author, and they work together. The FloDee widget shows whether FloDee is running and puts its actions in the cockpit:

Now Playing widget (media keys)#

Play / pause, next, previous and stop for whatever is playing - Spotify, a browser tab, VLC - without leaving the headset. The buttons send the system media keys, exactly what the keys on a keyboard send, so every player responds and nothing needs an integration. The line above the buttons shows what is playing when the player says so in its window title (Spotify does: "Artist - Song"; browsers show the page title for YouTube / music tabs). The same three actions are also Icon Bar icons โฏ โญ โฎ. Hot island: clickable in clickthrough with Hot zones on.

Stopwatch#

One stopwatch, two faces. Stopwatch (Analog) is the classic: a big red sweep hand doing one turn a minute, a 30-minute sub-dial, the time in digits underneath, and the ring turns green while it runs. Stopwatch (Digital + laps) is the working one: big digits, the lap you are on and its running time, a lap list (newest first, the best lap in green, each lap's gain or loss against the one before it), best and average once you have two laps, and three buttons - START / STOP, LAP, RESET. Both widgets show the same timer, so add either or both.

Driving it, in order of usefulness while racing:

Rules: LAP only counts while running; RESET only works when stopped (so a mis-press can't wipe a live timer); every action flashes what it did in the status line. Times read m:ss.hh and grow to h:mm:ss.t past an hour. The stopwatch is wall-clock, independent of the sim - it keeps running through a sim crash, a replay, or with no sim at all.

Track Map#

The map learns each track's real shape from one clean lap (dead-reckoned from speed + heading at 60 Hz โ€” no GPS). Until a shape is learned it shows a plain placeholder ring with "learning shapeโ€ฆ N%" in the corner; the learned outline is saved per track and reused forever after. Pit lane and partial laps are ignored, so drive one full lap on track.

Click the title to cycle modes: All cars ยท Relative-5 ยท Pace vs you ยท Classes.

Right-click the map:

Your own car draws big and bright (glow + white ring); other cars are smaller dots. Leaving a session keeps the map on the track you just drove. Each widget saves its own view, so a north-up overview and a chase map can coexist on one layout.

Community Track Library & Track Pioneers#

### โณ Available soon โ€” currently switched off The Community Track Library is not active yet. RaceVisor makes no connection to it: it does not download shapes, does not upload anything, and the settings below are visible but disabled. When it goes live the existing track list will be cleared and Track Pioneer credit starts from scratch, so nobody is advantaged or disadvantaged by having tested early. Everything described below is what will happen once it is enabled.

RaceVisor ships with no track outlines โ€” every shape is learned by a driver. The Community Track Library links the app to the website so learned shapes are pooled, and the first driver to learn a track is credited forever as its Track Pioneer โ€” in the app and on racevisor.flodeeapp.com โ†’ Track Pioneers.

What happens by default (no opt-in needed): at start-up and every 6 h, RaceVisor downloads any community shapes you don't have yet (read-only; sends nothing about you), so your Track Map knows a circuit before your first lap. The map's corner shows ๐Ÿ pioneer: <name> and the View saved track menu shows the pioneer + date/time as a tooltip.

Sharing & claiming credit (opt-in): Settings (Media widget โ†’ โš™ / Icon Bar โ†’ Settings) โ†’ COMMUNITY TRACK LIBRARY ยท TRACK PIONEERS:

What is logged: track (name/config/iRacing id), driver display name + iRacing customer id, date and time (UTC), RaceVisor version, hashed IP (rate limiting). Never laps or telemetry.

Track Pioneer credit is an acknowledgement only. Being listed confers no rights, privileges, priority or additional support, compensation, or other consideration of any kind, and creates no relationship with the author beyond the listing itself. Participation is strictly opt-in. The author may withhold, correct or remove a credit at any time (errors, ineligible or abusive entries, removal requests). Full terms: LICENSE.md ยง4.

Community shapes are plain <track key>.v2.json files in Documents\RaceVisor\trackmaps, identical to locally learned ones; pioneer credits are cached in _community_index.json there. A locally learned shape is never overwritten by a download.

Driver Chat (voice + text between RaceVisor users)#

Talk and type with other drivers without touching the sim's own voice or text chat - it works across sims, in practice, in a private league room, or while one of you is still in the menus. One driver hosts, the others join; the host relays everything. No RaceVisor server is involved and nothing is recorded or sent anywhere else.

Setting it up (once):

1. Add the Driver Chat (voice + text) widget to a layout (Layout Designer palette, or right-click the overlay โ†’ Add widget). Size it like any widget. 2. Click โš™ on the widget: your name, the port (default 41777), microphone and speakers (pick the headset, or chat comes out of the monitor speakers), mic gain, volume, and optional auto-host / auto-join at launch. 3. Host: click Host. Give the others your address. Join: type the host's address (name-or-IP, or IP:port) and click Join.

Your address is on the widget, always. A Give friends: strip sits under the title and shows the addresses to read out, each already carrying your port - click any one to copy it:

ChipWhat it isWhen to give it out
LANyour address on this networkanyone in the same house or on the same LAN
Tailscale / ZeroTier / Hamachiyour mesh-VPN address, shown automatically when one of those is runningthe easy way to play over the internet
WANyour internet-facing addressonly works if you forward the port on your router

Adapters a friend could never reach are left out on purpose - VirtualBox and Hyper-V host adapters, Bluetooth, and any interface that failed to get an address. The strip re-checks itself every few seconds, so starting Tailscale or plugging in a cable mid-session just appears. Finding the WAN address means asking an outside service (checkip.amazonaws.com, then api.ipify.org); switch that off with โš™ โ†’ Show my public IP in the widget and the LAN and VPN chips still work.

Reaching each other: on the same LAN, the host's local IP just works. Over the internet the easiest route is a mesh VPN - Tailscale, ZeroTier or Hamachi - which gives every PC an address the others can reach with no router changes. Otherwise only the host forwards the one TCP port on their router; the joiners need nothing.

If port forwarding just will not work, it is probably not your fault. Many ISPs put customers behind carrier-grade NAT (CGNAT), where your router's "public" address is shared with other customers and nothing you forward is reachable from outside. Mobile broadband and Starlink are almost always CGNAT; cable and fibre often are now too. How to tell: compare the WAN chip on the widget with the WAN/internet address on your router's own status page. If they differ - or the router shows something starting 100.64. through 100.127., 10., or 192.168. - you are behind CGNAT. The fix is the VPN route, which works regardless because both ends dial out rather than accept an incoming connection. Some ISPs will give you a real public address on request, occasionally for a fee.

While racing:

Audio: 16 kHz mono voice, sent only while transmitting - a talker costs about 16 kB/s. The mic level meter on the widget moves even when you are not transmitting, so you can check the right mic is selected before anyone joins. Leaving the room releases the microphone.

Wheel buttons: in the Hotkey Editor, every Driver Chat action can take a controller button as well as a key, exactly like the layout hotkeys - push-to-talk on a wheel button is the natural setup in VR.

Security - read this before port-forwarding#

A driver who forwards the chat port is exposing a service to the internet, so Driver Chat carries the same layers as the author's JVNC remote desktop, scaled to a chat room. All are in the widget's settings, and all are on by default except approval and the allow list.

The honest summary. Best: put everyone on a VPN (Tailscale, ZeroTier, Hamachi) and never open a router port - the room is then unreachable from the internet regardless. If you must port-forward: keep encryption on and set a room password. With both, a stranger who finds the port gets a TLS handshake, then a password challenge they cannot pass, then a 15-minute ban.

LayerWhat it does
Room passwordOne password for the room. The host stores only a PBKDF2-SHA256 verifier (100 000 iterations, random salt); joiners keep their copy encrypted with Windows DPAPI for their own account. On join the host sends a salt and a random nonce and the joiner answers with an HMAC of them - the password never crosses the network and a captured exchange cannot be replayed.
Encryption (TLS 1.2 / 1.3)Voice, text and the password proof are encrypted. The host's self-signed certificate is created on first use; the widget and settings show its fingerprint. Joiners pin it on first connect (trust on first use) and are refused with a loud warning if it ever changes - either the host regenerated it, or someone is in the middle. Forget pinned hosts in settings resets that, and only then.
Public-address rule (default on)With no room password, only LAN / VPN / Tailscale addresses can join; internet addresses are refused. So a forgotten port-forward can never expose an open room.
Lockout (always on)5 wrong passwords from one address = 15-minute ban, and every wrong password costs a second. Brute force dies.
Approve each joinThe host sees "X wants to join" with Allow / Deny in the widget's roster (works in VR); the joiner waits up to 45 s.
Allow listOptional IPs / networks that may connect at all - 192.168.1.0/24, 100.64.0.0/10 (all Tailscale). Everyone else is dropped silently, before the greeting.

What it does not do: RaceVisor's protocol code is small and reviewed, not independently audited; a joiner who knows the password is inside the room and hears everything; and nothing here protects the sim's own comms, only Driver Chat. Both sides need the current RaceVisor - an older build cannot join a secured room and says so.

Hover tooltips#

Everything shows a tooltip on hover (icons by name; widgets show the drag/resize/right-click hints). Learned the app? Turn them off: SET โ†’ "Show hover tooltips in the overlay."

Resource cost in tooltips: hovering a widget in interactive mode also shows its live CPU draw cost โ€” cost: 0.31 ms/frame ยท 18% of overlay ยท medium โ€” so you can see which widgets are heavy (rating: low < 0.15 ms, medium < 0.5 ms, HIGH above). Segmented rpm bars, a rotating track map, and the timing tower are the usual heavyweights.

System requirements#

MinimumNominal (recommended)Preferred
OSWindows 10 64-bit (21H2+)Windows 11Windows 11
CPUQuad-core (i5-8400 / Ryzen 5 2600)6โ€“8 cores (i5-12400 / Ryzen 5 5600X)8+ cores (i7-13700 / Ryzen 7 7800X3D / Ryzen 9)
RAM8 GB16 GB32 GB+
GPUAny DirectX 11 GPU, 2 GB VRAMGTX 1660 / RTX 2060 classRTX 3070+ (RTX 4080/4090 for VR at max)
Storage300 MB free1 GB (recordings grow)NVMe SSD, 10 GB+ for videos/telemetry
Display1080p monitor1440p or second monitor for the dashboardQuest 3 / PC-VR + OpenKneeboard, or triple screens
Overlay refresh30 Hz (โšก Low power)60 Hz120 Hz
AlsoiRacing installed; .NET 10 runtime (bundled)+ OpenKneeboard for VR+ OBS Studio for streaming/recording control

The overlay itself is light โ€” measured โ‰ˆ2% of a 12-core Ryzen 9 at 60 Hz (about half a thread), 10โ€“20% of a quad-core. iRacing's own requirements dominate; anything that runs iRacing comfortably runs RaceVisor at Nominal.

Performance / Low power#

The overlay is light (โ‰ˆ2% of a 12-core Ryzen at 60 Hz โ‰ˆ half a thread), but that same work is ~10โ€“20% of a modest quad-core. SET โ†’ Overlay refresh throttles render + poll together; the โšก Low power (30 Hz) button halves the work with no readability loss. Rotating/chase track maps rebuild their geometry every frame โ€” switch the map to north-up on weak machines.

Media widget#

ButtonAction
โ— REC / โ–  STOPRecord MP4 (screen + overlay, H.264 + AAC) โ†’ Documents\RaceVisor\videos
SHOTScreenshot โ†’ Documents\RaceVisor\screenshots
SCR: 1 / ALLCapture primary monitor or all monitors
SETRecording settings: fps, bitrate, resolution cap, audio source, overlay refresh rate, cursor size, YouTube setup
YT โ†‘Upload latest recording to YouTube as private โ€” title/description/tags pre-filled from the session (track, car, finish position, best lap, conditions). Review dialog: edit anything or just hit Upload. One-time OAuth setup via SET โ†’ "Setup guide โ†—".
Transport rowOpen/play/seek recordings in-overlay; bottom row drives the iRacing replay itself

The Media widget can stay clickable even in clickthrough mode (hover it - it is a "hot island").

Hot zones now ship OFF. They were catching clicks meant for the sim underneath - a click on AMS2's DRIVE button, and getting on track in Assetto Corsa, both went to the overlay instead of the game. Turn them back on in Media settings -> Hot zones if you actually drive the Media, OBS or Icon Bar widgets from inside clickthrough; leave them off otherwise and use interactive mode (F12) for those widgets.

Ctrl+R is NOT video โ€” it records telemetry data for replay analysis. Video is the REC button.

Replaying iRacing's own telemetry (.ibt)#

iRacing writes its own telemetry file when you press Alt+L in the car (or always, if Options โ†’ Misc โ†’ Auto-log telemetry is on): a .ibt in Documents\iRacing\telemetry, every channel at the sim's full 60 Hz, plus the session info โ€” track, car, driver names. It is the same file MoTeC i2, Garage 61, VRS and the other analysis tools read.

RaceVisor plays those files straight through the dash: Ctrl+O, pick the .ibt, and every widget runs off it exactly as it did live โ€” loops at the end, Ctrl+O stops. The status line shows โ–ถ replay โ€” <file>. Nothing is converted or written; the file is memory-mapped read-only.

Two ways to make one from RaceVisor's side, both iRacing only:

A file the sim is still writing can't be opened yet โ€” stop logging first (Alt+L again, or the hotkey) and it appears on disk complete.

Works offline too: while the iRacing service is down for maintenance, its Demo Drive still writes .ibt files on Alt+L, and RaceVisor plays them the same way (verified 2026-09-09).

VR (OpenKneeboard)#

Every position is measured from your eyes - specifically from where your head was at the last recenter, which OpenKneeboard treats as 0,0,0. So 30 cm / 11.8 in ahead means exactly that, in front of your eyes. Distances are shown in both centimetres and inches (feet and inches past a foot). Recenter while seated in your driving position - recenter while leaning in to the desk and every offset is wrong by that much.

The one thing to know: OpenKneeboard reads this pose only when it starts. It ignores the settings file while it is running, so dragging a slider changes nothing you can see, and Recenter just re-anchors the pose OKB already had in memory - which is why the kneeboard seems to land in the same place no matter what the sliders say. That is why Restart OpenKneeboard on Apply is on by default. Set your pose before you launch the sim. OpenKneeboard injects into the game at launch, so restarting it mid-session leaves you with no kneeboard at all until the sim restarts too.

Reset sliders puts everything back to OpenKneeboard's default pose - 30 cm / 11.8 in ahead, 20 cm / 7.9 in below eye level, tilted back 19 degrees, 40 x 75 cm - and applies it. That is the rescue when you have dragged the kneeboard somewhere you can no longer find it. (It deliberately does not zero every slider: 0,0,0 is your eyeballs, which would bury the kneeboard in your face.)

Snap (on by default) notches every slider at its centre (position and angles) or OKB's default (width/height); off = fully free.

Capturing the VR view - troubleshooting#

SymptomCause and fix
Capture shows iRacing but no dashOpenKneeboard is drawn by the VR compositor, on top of what the sim submits - it is never inside iRacing's own window. Capture SteamVR's VR View mirror instead.
"VR View" missing from OBS's window listThat window only exists while it is open. Open SteamVR menu -> Display VR View first, then pick it in OBS - and re-pick it each session, because it leaves the list when SteamVR closes.
Capture shows the SteamVR Status windowBoth windows belong to vrmonitor.exe. Set the source's Window Match Priority to Window title must match.
Capture shows your desktop / whatever is on topCapture Method is on Auto (BitBlt). Set it to Windows 10 (1903 and up).
Recording is entirely blackIn order: wrong source (not the VR View window); OpenXR runtime is not SteamVR, so the session never reaches its compositor; headset asleep - iRacing stops rendering when the proximity sensor sees nothing (black with the dash floating on it means exactly this).
Dash missing in the headset, not just the captureOpenKneeboard must be running before the sim starts, the sim must be on the OpenXR path (not OpenVR), and OpenKneeboard must be on the tab capturing RaceVisor.
Recording blurry though the dash is visibleA window capture records at the window's on-screen size. Full-screen the VR View on your biggest monitor, then in OBS: Transform -> Reset, Fit to Screen, Scale Filtering -> Lanczos.

Files & folders#

WhatWhere
Layouts (yours + presets)Documents\RaceVisor\layouts
Track map cache (learned + community)Documents\RaceVisor\trackmaps (_community_index.json = pioneer credits)
Videos / screenshotsDocuments\RaceVisor\videos, โ€ฆ\screenshots
Telemetry recordings โ€” RaceVisor .jsonl.gz and iRacing's own .ibtDocuments\iRacing\telemetry
HotkeysDocuments\iRacing\irDash_hotkeys.json
Driver Chat settings (name, port, devices)Documents\RaceVisor\driver-chat.json
Media, YouTube + Community Track Library settingsDocuments\iRacing\irDash_media.json