Every user-visible change, newest first. 92 releases; the latest five are open, older ones expand on click.
3.0.3
Backend
Registration now solves a proof-of-work challenge. Because this source is public, knowing
the request shape must not be enough to fill the backend with fake installations. Before its
first registration the plugin fetches a signed challenge from api.moverlay.com, spends about a
second of one CPU core on the backend thread finding a counter whose SHA-256 starts with the
requested number of zero bits (20 by default), and sends token and counter with the
registration. Nothing changes for an installation that already has its secret, for the
update check, or for the usage report. An expired or rejected challenge is retried once; a
closed, throttled or unreasonably hard challenge skips registration until the next SimHub
start, and a backend older than 0.2.5 is registered with the previous body. Details in
docs/BACKEND-SYNC.md.
3.0.2
Overlays
The Pit Strategy card's Compact layout fills its canvas and carries the evidence. Until 3.0.1
Compact was the dense 2.25 ladder at a fixed size, so on the 500 × 500 canvas a one-stop plan left
the lower third of the card empty above two small footer lines. Compact is now the fuller view
the layout is meant to be: the two footers become a row of gadget tiles — the fitted set's life and
wear (MEDIUM LIFE · 11 LAPS · 10% WEAR), its degradation slope (DEG PER LAP · 0.12s), the
pit-loss estimate with its source (22.5s · TRACK DEFAULT, amber under a caution) and the plan's
confidence with what the plan costs (HIGH · COST 31.4s) — and the whole ladder is scaled so the
stack the state shows fills the height, about 12 % larger on the common one-stop plan than
before, with no empty band. A tile whose switch is off (ShowReasons, ShowPitLoss) gives its
width to the rest; the life tile steps aside under NO STOP, where the LIFE strip already says it.
Above 100 % text size the tiles go after the alternatives and the caption, before the strips.
The Large layout is unchanged. The header tag (RACE, UNDER SAFETY CAR) now keeps a gutter's
distance from the title instead of a fixed width.
Sizing policy written down.docs/DESIGN.md gains "Sizing within a card": the canvas never
changes between layouts; Large spends it on size (only the critical rows, slack allowed) and
Compact spends it on information and fills it (more gadgets, the ladder scaled to the space the
state leaves, fillCap 1.4). Pit Strategy is the first card on the contract; the other Compact
layouts keep the fixed 2.25 numbers until they are revisited.
3.0.1
Installer
The 3.0.0 rename missed four things SimHub itself keeps by the old MoverlayF1 names; an update to
3.0.1 migrates all four, once, and leaves anything it cannot read untouched:
Keybinds and StreamDeck buttons in PluginsData/PluginManagerSettings.json bound to a
MoverlayF1Plugin.* action are rewritten to MoverlayPlugin.*.
Dash Studio's per-dashboard render mode, transparency and button bindings in
PluginsData/Common/DashStudioSettings_2.json follow a renamed dashboard instead of resetting to
defaults the next time Dash Studio opens it.
A device's screen assignment in PluginsData/Common/Devices/<device>/settings.json (the dashboard
shown on a wheel or other display, its idle dashboard, a per-car override) is updated to a renamed
dashboard; a numbered backup under _Backups/settings_b*.json is left alone.
A dashboard sitting under an old folder name a rename did not otherwise recognise - the 1.9.0
MoverlayF1 - Leaderboard Lastname folder is the known case - is now found by its fixed dashboard
identity, and its folder, files, saved overlay layout references, Dash Studio entry and device
screen assignments are all renamed together, preserving the saved layout position.
Strategy model
The Pit Strategy card no longer reads "0 STOPS" over a plan with a stop in it. Since 2.28.2
its headline printed the number of stops after the next one, so the common one-stop plan - a
13-lap Grand Prix on a medium with a mandatory stop to the soft at lap 5, in the maintainer's own
race - read 0 STOPS · SOFT · L6-L13. The count is now the plan's stops, the next one included,
and the plan is published as a race timeline the cards share: the stint on the car first, then
every planned stint, and one entry per stop with its box lap, the window it may be taken in, the
compound it fits and what it costs - the Pit Window's LAP 5-12 and the strategy card's stop are
now one value, not two calculations. In the first seconds after lights out, before the game has
sent the stint history, the card reads Waiting for tyre history instead of planning a race
without the two-compound rule, and NO STOP cannot be called until the history is there.
(/api/v1/pitstrategy-state gains CurrentLap, StopCount, PlannedStops[], Verdict,
Alternatives[], FittedLifeLaps, DegradationSecondsPerLap and per-stint IsFitted /
LifeLaps; the existing keys keep their meaning, the projection-key golden was extended
deliberately, and the SimHub property surface is unchanged.)
A stop just made under the safety car no longer produces a second "BOX NOW". Right after a
safety-car stop onto a fresh soft with two laps to go, the Safety Car Helper said STAY OUT · STOP DONE while the Pit Window and the Pit Strategy card still advised boxing again for another soft:
a running safety car used to veto NO STOP outright and put a stop on the table by itself, so the
cards published the stop-now plan - the cheapest set that reaches the flag - without asking whether
the stop pays for itself or whether the helper had already recorded one. While a period runs the
Safety Car Helper's verdict now decides whether a stop is on the table, and a caution no longer
makes a stop free: it has to win back its own (reduced) pit loss. After the stop all three cards
read the same thing: NO STOP, No stop planned, STAY OUT · STOP DONE. The review of this
release closed two gaps in the same rule: NO STOP is now decided on the very totals the card's
alternatives are priced on (staying out against the cheaper of the planned and the immediate
plan, all three in seconds against the fitted set's pace to the horizon), so the card can no
longer read 1 STOP beside a cheaper NO STOP alternative or the reverse; and the Safety Car
Helper's green hold at a restart (the half second between the resume event and the status
clearing) counts as the helper holding, so the stop-now plan no longer flashes there. And the
verdict is the same whichever overlays are open: the totals it is decided on are computed for
the Pit Window and the Safety Car Helper whether or not the Pit Strategy card or a dashboard's
strategy gadget is drawing the timeline (opening the card used to be able to flip NO STOP).
The 3.0.0 notes left five judgement constants "for the maintainer's decision". Each was measured on
the recordings on this PC (docs/TIMING-VALIDATION.md 3.0.1 has the numbers) and decided on that:
Tyre degradation is fitted per session, per compound, instead of one 2.2 s/lap full-life line
for every compound and circuit. The main source is the game's own per-set lap delta over the sets
of a compound at different wear (the set on the car is one of them), read back as seconds per wear
point times the set's measured wear per lap; the session's clean laps (every car, regressed within
each stint) and the old constant over the compound's usable life are weighed in beside it, by the
laps of evidence each holds. With nothing measured a fresh set is priced exactly as 3.0.0 priced
it; a worn fitted set is deliberately not - the old constant spread its 2.2 s over the laps LEFT,
so a set with five laps to go degraded at 0.44 s a lap, and it now spreads over the compound's
usable life (0.11) like every other set - and after a few laps on a set the slope follows the
game's model. The set's wear per lap behind it is the Tyre Life card's measured rate first
(right for a set fitted used, caution laps excluded), then the set's own wear over its age from
the wear it had when it went on (a set fitted at 12 % no longer reads 11 points a lap), and
under a safety car or VSC - where the game rescales its own deltas - the slopes fitted on the
last green lap are held. Measured: at Baku a medium loses 0.03 s a lap of age
where the constant said 0.09, at Madrid a soft 0.4-0.6 s where it said 0.22, at Texas a medium
0.16-0.19 against 0.17 - so the Baku sprint's predicted stop moves three laps later, Madrid's soft
stints one to three laps earlier, Texas not at all. The Pit Strategy card, the Pit Window's
predicted lap, NO STOP and the Safety Car Helper's net all price on the fitted slope (the
per-compound rows - slope, source, laps of evidence - are kept on the engine's state for the tests
and the replay harness, not on the JSON views, whose key sets are pinned).
Safety-car pit-loss factors: 0.60 under a full safety car (was 0.45), 0.85 under a VSC (was
0.65). 46 stops under a full safety car across three recordings lose a median 0.10 laps of
progress against the cars that stayed out - 11.7 s at the field's pace, 0.62 of the green-flag
loss - but the spread is the state of the train: 0.35 once it has formed (Baku, twenty stops on
one lap), 0.7-1.2 in the deployment lap itself (Madrid, Baku online). Under a VSC (two stops)
0.85-1.2, which is also what the pace ratio predicts. The new numbers are the pooled medians; the
period learning below tracks the difference during the period itself.
Rain forecast inside the race ends the dry plan there. When a forecast sample's own weather
code (never the percentage, never an approximate forecast) puts rain inside the race and a wet set
is in the allocation, the dry stints are planned only to the rain lap and every plan ends on the
stop for intermediates at that lap - the strategy card's last row and last stop; a dry stop is
planned inside those laps only when it pays for itself before the rain, and a set that reaches
the rain lap needs no dry stop at all (the fitted set's reach is measured to the rain lap like
every other horizon). The forecast's weather code is judged over the whole of the race that is
left, not the next stint, so rain forecast beyond the game's own pit window is seen from lap
one. No recording on this PC has rain inside a race (Madrid's samples all flipped after the
flag), so this is fixture-tested.
Pit loss is learned under a safety car and VSC too. A rival's stop under a period is measured
over lap progress, converted at the field's green lap (captured once, as the period begins, from
the last green snapshot - a marshal zone the game keeps up through the period no longer blocks
it, and a VSC that becomes a full safety car keeps it) and divided by the period's factor, then
held to the same rules as a green stop; at Madrid 24 of 25 stops were under a caution and the
estimate never left the table value. Run over that recording's whole field, nine of the eleven
stops under the lap-4 safety car are learned; their green-equivalent (29.9 s against the 22 s
table) is the deployment-lap effect the factor notes describe, and a green stop afterwards
corrects the median.
Seconds per place stays 2.5 s (already a Safety Car Helper setting, 0.5-10 s). The measurable
alternative - the field's spacing - is 0.3-0.5 s between consecutive cars on every recording, and
pricing a place at the gap would turn a 10 s stint gain into twenty places regained; the constant
is the cost of a pass, which no recording measures in a controlled way, so it stays a judgement
the driver can set.
Fixes after review
An independent review of the strategy model, before this release shipped, caught two more
user-visible gaps:
A set that already reaches a forecast rain lap no longer plans an unneeded dry stop. The
plan's dry horizons were capped at the rain lap everywhere except the fitted set's own reach, so
a set with life past the rain but not the flag was still planned a dry stop before the rain stop
that ended the race anyway - two stops for a set that needed one.
NO STOP now reads the same whether or not the Pit Strategy card is open. The totals it and
the card's alternatives are priced on used to exist only while the card or a dashboard's
strategy gadget was drawing the full timeline, so opening the card could flip a Pit Window or
Safety Car Helper verdict that had just read the opposite way.
Overlays
The Pit Strategy card is redesigned in the Pit Window card family, in both layouts. The
2.28.2 card - a stop count, a compound pill and bare lap ranges (0 STOPS · SOFT · L6-L13 in the
maintainer's 13-lap race) - is now the Pit Window's sibling at the same 500 × 500 size: the same
header band, one headline (1 STOP / 2 STOPS, or BOX NOW in amber, NO STOP in green,
WAITING) with its reason under it (2-COMPOUND RULE, FASTEST TO THE FLAG, STOP DONE · RULE SATISFIED, FOR TYRE HISTORY ...), the next set's compound pill (the fitted set, TO THE FLAG,
under NO STOP), rows with the coloured left rule and right-aligned values - BOX · WINDOW 5–12
→ L5 (the Pit Window's own window, one value), PIT · REJOIN P21 → 22.5s (amber under a
caution), BOX 2 · HARD → L38 for a second stop, TO GO / SOFT LIFE under NO STOP - and, as
the last row, a stint bar: the race as laps 1..N, stints coloured by compound, the laps run dimmed,
the current-lap needle, a pin at each box lap and the first stop's window underlined. Large adds the
priced alternatives (BOX NOW +2.8s) when the height allows; Compact keeps the evidence footers
(confidence and fitted degradation, pit loss and its source). NO STOP and the post-lights-out wait
are drawn on the card (green headline; WAITING with the dash vocabulary) instead of a status chip.
Both layouts hold the 28 / 18 px effective reading floor at the card's placement; the Compact floor
baseline is re-pinned for this card alone. ?demo=1 is now the 13-lap race (&scene=scdone,
twostops, boxnow, waiting for the others), ?selftest=1 runs the five scenes in both layouts,
and tools\Selftest-Renderers.ps1 gained the page with two fixtures.
The Race Control Dashboard's brand badge is readable at its placement. The small F1/F1 25
mark the 3.0.0 rename added beside the header sat 2 px under the 18 px label floor; it now sits
on it.
Performance
The strategy engine re-solves on events, not on every snapshot. The maintainer keeps the
Race Control Dashboard with its strategy gadget open, so the 3.0.0 gate (which only skipped the
plan when nothing drew it) never applied to them, and a set delta creeping by a few milliseconds
ran the whole ranking, window and multi-stop search ten times a second - 0.76-0.86 ms a snapshot
at 3.0.0, 0.85-1.44 ms with the fitted degradation of 3.0.1. The tyre engine now keys everything it
computes on the inputs the answer depends on - the lap, the set on the car, the safety-car and
red-flag state, the two-compound rule, the forecast samples, the pit loss (learned, penalty and
wing), every set's wear to the whole per cent, life to the whole lap and delta to 0.1 s, every
rival's compound, age, stops and clean lap, the fitted degradation - and re-solves only when one
of them moves or on a 2 s heartbeat of session time; in between it publishes the previous state
by reference, so the views' ETags hold and the dashboards redraw nothing. A stop, a lap, a caution
or a rule change is inside the key and is reflected on its own snapshot. The two decisions made
after the engine (a stop on the table now, which plan the card shows) clone the shared state only
when they actually change. Measured on the 22-car fixture with the dashboard on and a delta
creeping every snapshot: see docs/TIMING-VALIDATION.md 3.0.1 (the new "creeping" benchmark line
is pinned at 0.30 ms; the idle read stays where it was).
Tyre Prep
The carcass windows were checked against the game, not adjusted. On five recordings a set
driven hard settles at one carcass temperature per Pirelli compound whatever the circuit - C5 80 C,
C4 85 C, C3 90 C - each inside the card's window, 5-10 C above its cold edge; qualifying flying
laps that set a time started from 70-89 C on the C5 (never below the window; once exactly on its
edge, which the card has always read as in the window), and at a safety-car restart a C4 at 67 C
and a C5 at 69 C read COLD and were slow. The three slow flying laps that began with a
warm carcass all had a cold surface, which the card prints beside the carcass but does not judge.
The intermediate and wet windows stay as they were and unvalidated: no wet-track recording exists,
and Madrid's intermediates on a drying track ran 83-100 C, hot by their window, as they should.
3.0.0
Renamed the product from MoverlayF1 to Moverlay: the plugin file, its settings page, every
shipped overlay and dashboard, the installer, and every "Waiting for..." / "Connecting to..."
string now use the new name throughout.
Breaking
The configuration file changes shape (revision 5): the 2.x Overlays section becomes
Profiles.eaf1 and General, Analysis and SoundCommands move to the root, with every value
kept. This happens once, on the first start of 3.0.0, and the previous file is copied to
config.json.pre-3.0.bak next to it first; a 2.x build reading the new file would see an empty
configuration and save its defaults over it, which is what the backup is for. Nothing to do
unless you edit config.json by hand or want to go back. A downgrade to 2.x re-mints the
installation id (the identity the backend knows you by changes) and rewrites the file in the 2.x
shape; 3.0.0 recognises such a file whatever revision it carries, keeps every value it holds and
takes another backup (config.json.pre-3.0.2.bak, ...) before reshaping it again. A file the
plugin cannot read at all is kept as config.json.invalid.bak before the defaults replace it, and
a backup copy that fails is logged as a warning rather than treated as an unreadable file.
Every Dash Studio property changes prefix from MoverlayF1Plugin.* to MoverlayPlugin.*.
A dashboard shipped with the plugin is migrated automatically (see below), but a formula you
built yourself in Dash Studio that references a MoverlayF1Plugin.* property must be edited by
hand to the new name.
The plugin DLL is renamed from MoverlayF1.dll to Moverlay.dll. Setup (or tools\Install.ps1)
removes the old DLL when it installs the new one and carries your plugin activation over (see
below), so SimHub should not ask you to enable the renamed plugin again; if it does, enable it
once, the same way as after any plugin rename.
SimHub's plugin activation entry is migrated: both installers rename the
F1Overlays.MoverlayF1Plugin entry of SimHub's PluginsData\PluginsActivation.json to
Moverlay.MoverlayPlugin, keeping its enabled and menu fields (or add it enabled when neither
exists); a missing or unreadable file is skipped and SimHub then asks once.
Shipped dashboards are renamed from MoverlayF1 - <Name> to Moverlay - <Name>. An existing
installed dashboard is renamed in place (its dashboard and screen IDs, and any custom renderer URL,
survive the rename) rather than duplicated, and a saved overlay window layout that referenced the
old dashboard file by name is rewritten to the new one automatically.
Stored data moves from PluginsData\MoverlayF1 to PluginsData\Moverlay the first time the
renamed plugin starts (configuration, recorded laps, pit stops, start history, learned pit lanes,
dial positions and exports). The move happens once, automatically, and only when the new folder
does not already exist.
Multi-game
Internal groundwork (docs/MULTI-GAME.md phases 0-3): the telemetry engine now reads the game
through an adapter seam - a host frame filled once per SimHub callback, an adapter registry, and
the session-identity, player-selection and 60 Hz sampling decisions behind it. Every measured F1
rule (the Baku reload id keep, the frozen-stream deferral, rewinds, spectator and one-shot
handling, the player-change reset) is unchanged and pinned.
The plugin now knows which game SimHub is feeding it and what that game can tell it. Twenty-one
new Dash Studio properties describe this: Source.GameKey, Source.GameLabel,
Source.ProtocolKey, Source.ProtocolVersion and Source.AdapterVersion, and one
Support.<Capability> string per capability (Roster, LapTiming, WorldPose, Weather,
Forecast, Tyres, Damage, PitService, Cautions, StartLights, RaceControlEvents,
TimeTrialReferences, EnergySystems, Fuel, CarTelemetry, Spotter) reading Supported,
Restricted (the game gives the value for your car only, or only in some sessions) or
Unsupported. Under the EA F1 games every row reads Supported except Spotter, and
Restricted appears where it always did in practice (the other cars' tyres and telemetry in
an online session with restricted telemetry). The same two blocks ride on the local server's
state and settings payloads.
Almost nothing changes for F1 25 (2026 season pack included), F1 24 and F1 23 in any mode:
every overlay, dashboard, setting, property and route works as in 2.28.2, and the shipped
previews render pixel-identical apart from pages whose demo animates on the clock and the two
deliberate exceptions in the Overlays section below (the Race Control Dashboard header and the
Steering Wheel idle page each gain a small "F1"/"F1 25" brand badge that was not there before).
A game the plugin does not support yet still gets nothing visible. With another SimHub game
running (iRacing, ACC, ...) the overlays that need what that game cannot provide stay hidden -
Shown reads false, a Toggle changes nothing visible and a Peek is refused with a log line -
instead of drawing a card full of zeros and dashes, and the common overlays (Track Map, Track
Position Circle, Driver Ahead and Behind, Driver Relative, Leaderboard, Inputs, Proximity Radar,
Delta vs PB, Lap Chart, HUD, Steering Wheel, Race Control Dashboard) know how to drop the
controls the game has no data for (ERS column, gauge and trace, tyre glyphs, DRS pill,
pit-window and strategy gadgets, the flag banner, the rejoin marker, wheel pages and tiles).
Today no second game adapter ships, so what you get with another game is Waiting for <game> telemetry and a source-probe dump under PluginsData\Moverlay\diagnostics (written on its own
for a game without an adapter, at most five per SimHub session, or on demand through the new
ProbeSource action; widened to SessionData four levels deep, every raw Telemetry variable
and the full driver lists) that the next phase reads its facts from. The whole non-F1 path is
exercised by a test-only iRacing stand-in, not by a live game.
Settings profiles per game. The configuration file now keeps one settings profile per game
family (Profiles.eaf1 for the EA F1 games) with the General, Sound Commands and Analysis
sections shared. The settings page gains a Settings profile card on the General page's Plugin
row that lists the profiles the plugin knows and opens on the active one; with the EA F1 games
alone nothing changes and the card stays hidden. A tab the selected profile cannot show is
collapsed, a row that reads an F1-only value is disabled with "(not available for )",
and the Steering Wheel's Pages card names the pages the profile drops.
The Proximity Radar gained a track-distance mode for a game with no world positions (cars on a
strip by distance along the lap, the side rails lit from the sim's own spotter) and the Track
Map reads its outline from that game's SimHub track recording (PluginsData\<game>\MapRecords);
both are fixture-tested only, the F1 radar and map are unchanged.
Performance
Since 2.28.2 the Pit Strategy planner's whole-race search ran from scratch on every
snapshot, for everyone, whether or not anything drew its result: one 22-car snapshot took 0.72 ms
and allocated 1.5 MB instead of the 0.20 ms / 0.13 MB of 2.28.1. The search is now run only while
something shows the plan (the Pit Strategy overlay, the Steering Wheel's Systems page or a Race
Control Dashboard Strategy gadget; the PitStrategy.* Dash Studio properties read Disabled in the
meantime, as DeltaPb.* do while that overlay is hidden), its memo is shared by the tyre ranking,
the immediate choice and the plan and kept from one snapshot to the next while the allocation, pit
loss and rules are unchanged, and an unchanged plan is republished as the same object. Measured on
the same fixture: 0.21 ms and 0.13 MB per snapshot with the plan on or off, 0.46 ms and no extra
allocation on a snapshot whose inputs moved. Every published ranking, immediate call and plan is
unchanged, and the benchmark now asserts the budget. Across the whole multi-game pass
Telemetry.Read finishes at 0.21-0.22 ms and about 130.6 KB per 22-car snapshot, inside budget and
with every 60 Hz sampler byte count unchanged from 2.28.2.
Strategy model
Strategy model repairs (the pit-stop / tyre-strategy review of 2026-09-20; the fixture and
replay evidence is in docs/TIMING-VALIDATION.md 3.0.0). What the advice got wrong, and what it says now:
The dry two-compound rule was claimed in every race session, sprint races included, where the
game has no such rule: a sprint run on one compound read STOP NEEDED · 2-COMPOUND RULE on the
Safety Car Helper, the Pit Window could never say NO STOP and the plan was forced onto a second
compound. It is a Grand Prix rule now and is never claimed in the sprint race of a sprint weekend.
The engine's own pit window subtracted the fitted set's age twice: the game's per-set delta
already prices the worn set on the car, so the ideal lap was pulled earlier by a number of laps
that grew with the stint (five to six laps mid-stint). The window is now the lap on which the
fitted stint plus the cheapest complete plan from that lap costs least - the same search the Pit
Strategy card plans with - and its reason names what decided it (a further stop, the new set's
life, the fitted set's cliff, or the balance).
The Pit Strategy card ignored the Pit Window's decisions: it kept showing "1 STOP - MEDIUM
L20-L51" beside a pill reading NO STOP, or a planned soft beside BOX NOW - FIT HARD under a
safety car. It now reads No stop planned while the pill says NO STOP, publishes the plan from a
stop at the end of this lap while a stop is on the table (a caution, the window open, a set with
nothing left) so its first stint is the compound the pill and the Safety Car Helper name, and the
helper's compound is that same immediate answer instead of a separate rank walk.
A plan that spent two sets of one compound priced the second as a copy of the first: the Baku
allocation's used soft (1.09 s/lap, 17 laps to the cliff) was charged as the fresh set's 1.25 s and
19 laps, so stint ranges ran too long and costs too low. Every physical set is priced on its own and
every stint names the set it spends.
A set of the fitted compound with the rule open was priced as its own pace plus one pit loss, with
no stint of the other compound in the sum; it now carries the stint that discharges the rule.
The Safety Car Helper's net gain was the new set's offset against the stop alone: the wear swing
between the set on the car and the new one over the stint is now in the gain, and a plan that needs
a further stop pays that stop at the green-flag pit loss - the 2 STOPS NEEDED tail used to be free.
A measured tyre life scaled the mean corner's rate as if a set could be worn to 100 % (a set at
47 % read 0.74 of a fresh life instead of 0.33); it now runs from the set's wear to the cliff at the
worst corner's rate, which is the number that decides NO STOP when no set packet is available.
A plan's first stop was always priced at the green-flag loss, so a stop under a safety car or a
wing repair read 10-12 s too dear on the card; it now costs what that stop pays (the SC/VSC-reduced
estimate with the pending stop/go and the repair inside it for a stop now, the green loss plus the
same for the planned lap).
Deliberately unchanged, for the maintainer's decision: the 2.2 s/lap full-life pace loss, the
SC/VSC pit-loss factors and the seconds-per-place price are judgement constants (the replays show a
track-dependent curve, not a line), rain inside the plan's horizon does not shorten a dry plan, and
pit loss is still not learned from stops made under a safety car.
Overlays
Per-game brand mark, deliberate and visible under EA F1 too, not only under another game.
The Race Control Dashboard header and the Steering Wheel idle page each gain a small
badge that was not there before - the game's own label (e.g. F1 25) next to the track name on
the dashboard, and prefixed to the idle page's remembered last-session line - built from the
same Source the plugin's other pages already read. The three analysis pages and the leaderboard
header show the same badge beside the MOVERLAY wordmark (the F1 mark under an EA F1 game, as
before, or the connected game's own label under any other recognised source). This also fixes a
phase-3 bug on the leaderboard: a real EA adapter label such as "F1 25" was compared against the
literal string F1, took the unbranded text path and silently lost the header's RACE session
word - a real F1 25 game read the same as an unbranded source. Every "Waiting for MoverlayF1" /
"Connecting to MoverlayF1" string across every renderer, dashboard and analysis page now reads
Moverlay.
Tooling/tests
Five checked-in contract goldens (docs/DEVELOPMENT.md) pin the property surface, the full HTTP
route table, every settings leaf key, representative projection keys and packaged dashboard/screen
identities, so an accidental public change to any of them fails a test by name; phase 3 extends
each with its Source/Support/profile additions.
tools\Selftest-Renderers.ps1 runs every renderer's ?selftest=1 cases headlessly against
canned Support fixtures and fails on any FAIL line; tests\Floor-Check.ps1 gained twelve
iracing-* rows (the common slice against the iRacing fixtures, held to the same readability
floors as the F1 rows, left out of the Compact baseline). tools\Capture-Previews.ps1 -Fixture iracing and tools\State-Proxy.ps1 -settings=<name> serve and capture the common renderer slice
against canned non-F1 states for review, never shipped or embedded. The full suite passes
5,736 SDK/plugin assertions, tests\Installer.Tests.ps164 checks and
tests\Setup.Tests.ps170 checks, all green.
Docs
Four new documents: docs/CANONICAL-UNITS.md (the units and signs every adapter must agree on),
docs/FEATURE-INVENTORY.md (phase 0's classification of every snapshot field, reader, route,
setting and renderer as common, adapter-assisted or F1-specific), docs/IRACING-SDK.md (direct
iRacing SDK research: transport, variables and licence terms) and docs/IRACING-SLICE.md (the
capabilities measured from the maintainer's own SimHub iRacing replays, which the test-only stub
adapter declares). docs/MULTI-GAME.md phases 0-3 are marked done against their exit criteria and
deviation lists; the recommended first implementation ticket (section 11) is marked shipped.
2.28.2
Corrected the sprint-weekend session names from the latest Baku replay: the timing tower now says
FP1, and both dashboards distinguish Sprint Qualifying, Sprint Race and the full Race
instead of generic FP, Unknown or Race labels.
Added purple session-fastest sector splits to the Steering Wheel, Race Control Dashboard and
Ahead/Behind displays. Each sector is compared with the fastest individual sector in the field,
even when those three best sectors came from different laps.
The Pit Stop Helper now stays open after pit exit while the limiter is still engaged and changes
to a persistent red DISABLE LIMITER alert. It dismisses as soon as the limiter is switched off.
Fixed qualifying tyre advice: Sprint Qualifying and normal qualifying include the fitted set, so a
fitted soft that is quicker than the available medium remains the recommendation. Practice no
longer publishes a tyre recommendation.
Replaced the one-extra-stop tyre shortcut with a complete race-distance planner. It prices every
later pit loss, tyre pace/degradation, usable life, physical set count and the dry two-compound
rule. Severe front-wing damage makes the plan immediate. The new square Pit Strategy overlay,
Steering Wheel and Race Control Dashboard show the compound sequence and number of stops.
2.28.1
Reorganised General into Driver, Plugin, Timing and Display. Driver now contains
only the driver display name; Plugin groups the installation id, update channel and status, local
server address, and recorded-data locations and sizes.
Moved Share usage data to a compact checkbox directly below the Diagnostics log. Because
Diagnostics has no actions bar, this privacy preference now saves immediately when changed.
Fixed the visibly rippled Baku Track Map caused by SimHub preferring a noisy local recorded lap.
MoverlayF1 now keeps the local map normally but selects a complete map from the same game when its
accumulated direction noise is at least 15% lower; the installed Baku cloud copy is 47% lower.
2.28.0
Added a background startup update check against https://api.moverlay.com, with release-channel
selection and an in-settings notice. Updates remain manual: the plugin never downloads or executes
an installer.
Added the Share usage data opt-out switch and a background startup usage report. The hidden,
config-only BackendUrl override supports local backend testing with http://127.0.0.1:8000.
A foreground-guarded sound command now checks the game window before decoding or synthesising its
phrase, so it stays a true no-op even on Windows installations without a speech output device.
Public recording upload is not included in this release; it remains planned for 2.29.0.
2.27.0
Nine reports from one evening of online racing (20260918_180028: a spectated race at Madrid, a
spectated race at Bahrain, a Texas Short Practice joined mid-session, a Texas One-Shot Qualifying and
a 28-lap Texas race stopped by a disqualification) checked frame by frame against the recorded
packets and the real engine. The headline complaint was the Proximity Radar drawing contacts — and
Qualifying Traffic warning about a car — in a session where every other driver is running their own
lap on an empty road: a One-Shot Qualifying spawns all fourteen cars together and the game renders
none of them, but nothing in the packets says so.
Fixed
Ghost cars in a one-shot qualifying (or shootout) no longer register as traffic. The Proximity
Radar, the HUD's proximity rails and Qualifying Traffic all stand down for the length of a One-Shot
Qualifying or One-Shot Sprint Shootout instead of tracking and calling the other cars — the game
draws none of them, so a marker for a car the driver cannot see was pure noise. The Race Control
overtake feed drops the same session's synthetic pack of overtakes too (below). The ghost flag now
survives a stalled or frozen telemetry window too, so a brief data hiccup mid-session can no longer
let the radar un-hide for a callback or two. Qualifying itself is untouched: Tyre Prep, the
qualifying leaderboard pages and lap recording still treat the session as qualifying.
A car with a duplicated race number could vanish from the Proximity Radar. Public online lobbies
hand out duplicate numbers routinely (one recording had five cars wearing #2); the radar now
identifies a car by its grid slot, the same way SimHub itself does, so a duplicate number never
drops a real, nearby car from the feed.
Spectating a car whose race number was shared by another driver could mark more than one car as
"you." The tower's player row, the relative panels' centre and the car-details "Your Telemetry"
gate all matched a spectator override by race number; they now match the spectated grid slot first,
falling back to the race number only when no slot match exists.
Switching which car you were spectating, inside the same session, carried the old car's memory
into the new one. The lap-delta engine, learned tyre wear, Tyre Prep, Tyre Choice's own player
memory, the Start Helper, the Lap Chart, Qualifying Traffic and the 60 Hz input feed all kept
whatever the previously spectated car had produced. A player-index change now resets every one of
those, and the lap-delta engine no longer records or persists a lap while spectating at all — a
spectated car's flying lap can no longer be saved as your own personal best. (The pit-loss learner
and the Safety Car Helper's period memory are deliberately field-wide and are not reset by this —
re-announcing a safety car already in progress would only duplicate it.)
A telemetry-restricted human sitting past the lobby's head-count went unnoticed.m_numActiveCars
counts people, not roster slots, and can undercount a fully named roster badly: a Texas practice with
22 named slots read a count of 8, 12 then 9 across the evening, under half the roster at times — and
the restriction scan used the count as a hard bound. It now scans every named slot instead.
A session's first frame can carry a burst of about twenty synthetic overtake events that never
happened, measured at a One-Shot Qualifying's start as the grid order was established; with the
overtake message enabled (off by default, so nobody has seen this live) it would have posted up to
twenty "CAR X OVERTAKES CAR Y" lines in one go. Race Control now drops that opening burst in every
session, and in a race, drops any overtake before the lights go out too — for up to five minutes
into the session, so a rolling or safety-car start, where the game may never send a lights-out event
at all, still lets real overtakes through once that window passes — and drops overtakes outright in
a one-shot session.
Tyre Choice could flip its recommended compound back and forth on essentially no change in pace.
A crossover between two compounds at Confidence High now needs the challenger to win by a real
margin — half a second over the rest of the stint — or the reason itself to genuinely change, before
the card's headline compound changes. ("1 LAPS SHORT" is also now "1 LAP SHORT.")
An opponent's best or last lap could show a time nobody actually drove. SimHub's own normalized
lap time occasionally reports a partial-sector value instead of the whole lap, which reads as a lap
time no car could physically achieve on the circuit. A lap time is now discarded — the tower, the
relative panels and Driver Ahead/Behind fall back to nothing rather than a number — when it implies
an average speed over 396 km/h, or when it is under 20 seconds and the track's length is not known
for that session.
Changed
Delta vs PB no longer goes blank for an entire lap that has no session-best reference yet — a
One-Shot Qualifying lap, or any first flying lap of a session. When no session personal best exists,
the card falls back to the fastest stored lap on disk for the same car and the same rules era
(so a team's 2025 car and its 2026-pack car never share a reference), never a Time Trial rival
ghost's lap (the store now records whose lap each profile is), and marks it STORED PB; a
session best that arrives later takes over immediately, even if it is slower. Time Trial is
unaffected — it keeps the game's own reference — and the card still goes blank while spectating.
A handful of cosmetic mismatches from the same review are also fixed: the Steering Wheel now
captions its delta BEST · SPECTATING with a dash for the value, and the Race Control Dashboard's
delta tile reads SPECTATING, while watching a car that is not yours (Delta vs PB already said
so); the Lap Chart no longer reports a false "Replay rewind" on the tick a spectator camera switches
cars; Tyre Prep no longer publishes a lap projection or pace figure once the projected lap passes
double the reference lap's pace (an ordinary slow lap on a hidden card still shows its honest
number); a
session's first two seconds no longer misread as "Event Mode" before the game's own mode packet has
arrived; and the radar's directional call and side rails no longer flicker between two states inside
half a second at the approach boundary, clearing at once once no car is left in range.
Validated
Offline, against the recorded packets and a from-scratch engine and radar harness driven over the
fixed build (20260918_180028): every fix above reproduced from the replay and pinned in
tools\Test.ps1's new suites. Nothing here was re-driven live — see
the validation report for exactly what stays open, One-Shot Sprint
Shootout, F1 23/24, the HUD's proximity rails live, a real Event Mode session and a live spectated
session at index 255 among them.
2.26.4
In qualifying and practice the current lap time on the Steering Wheel and the Race Control
Dashboard kept running after the car turned into the pit lane — and with it the live sector, the
delta to the best lap and the Est lap — all the way to the garage, because the game never stops
its lap clock for an in-lap: it runs on through the lane, restarts at 0 where the lane crosses the
start/finish line and keeps counting after the car has stopped. What the game does do is mark the
lap: its driver status flips to in lap on the pit-entry road, 0.2–4.5 s before the pit flag, on
every driven qualifying in-lap in the recordings on this machine (Suzuka, Baku, Silverstone and
the two Abu Dhabi ones from today).
Fixed
A pit in-lap outside a race is not a lap time. From the moment the game reports the in-lap
(or the car is in the pit lane or the garage) in practice or qualifying, the wheel's Timing
page prints IN LAP in place of the running clock, runs no sector and captions the empty delta
DELTA TO BEST · IN LAP (BEST · IN LAP on the Race page); the Race Control Dashboard's Lap
time header cell and Current lap tile say IN LAP, and its Est lap and Delta go to the
dash with them. The sectors already set on the lap stay as they are. In a race nothing changes:
a pit in-lap there is a lap that counts and keeps its clock and delta until the pit lane.
The Delta vs PB card and the relative panels' live lap clocks follow the same rule: Delta vs PB
reads In lap from the pit-entry road (it already went dark in the lane), and a rival on an
in-lap shows its last lap a few seconds sooner than the lane would have said.
New property SteeringWheel.InLap (bool) and the Wheel.InLap field on the wheel and Race
Control Dashboard views carry the verdict; SteeringWheel.DeltaToBestLabel reads IN LAP
(source InLap) while it holds.
2.26.3
The Track Map drew Abu Dhabi as a triangle with every car off the outline. SimHub's own
circuit record for the track (PluginsData\F12025\MapRecords\Abu Dhabi.shtl) is a lap that
stopped after 12 % — 211 points covering the last 11 % of the lap and the first 1 %, kept since
December 2025 — and SimHub never replaces a local record once it has one. The plugin preferred
that file over the complete copy SimHub had downloaded beside it, joined the points in lap order
and fitted the map to their bounding box, so the cars, at their real world positions, landed
outside the drawn shape. Six installed circuits were in that state (Monaco, Abu Dhabi, Montreal,
Madrid and Monza on F1 25, Suzuka on F1 24).
Fixed
A partial circuit recording no longer wins over a complete one. Every file SimHub holds for
the track is now a candidate — the active game's own record, its cloud copy, then the other
games' in the same order — and the first complete one draws the map. A recording is complete
when no two consecutive points are 2 % of the lap or more apart (the wrap from the last point
back to the first included): every healthy record on the maintainer's machine, 100 files across
F1 24 and F1 25, stays under 0.52 %, and every partial one is at 28 % or more. Only when no
complete recording exists at all does the map show Circuit recording incomplete (12 % of the
lap) instead of a misleading shape.
SimHub's cloud circuit copies are readable at last. A MapRecordsCloud file carries no
GameCode, and the reader had rejected it as another game's map since the fallback was added;
the folder it sits in already fixes the game, so only a code naming another game refuses a file
now. Abu Dhabi on F1 25 draws from that copy (2,641 points).
The plugin log names the .shtl file the circuit came from, so a skipped local recording is
visible in the Circuit map line.
2.26.2
A SimHub update stopped on NAudio.Core.dll — "access is denied" — after SimHub had been closed.
The lock turned out not to be the plugin at all but a stray audio test script left running from a
development session; still, the plugin does start a process of its own (the 64-bit recognizer the
Sound Commands Test button uses, because SimHub is 32-bit and the game ships only the x64 speech
runtime), and reviewing what would happen to it when SimHub goes found two things to fix.
Fixed
The recognizer helper can no longer outlive SimHub. Every helper the plugin starts now lives
in a Windows job object that ends whatever is left in it the moment SimHub's process ends — a
normal exit, a crash or a Task Manager kill alike, the ones the plugin's own shutdown never sees —
so nothing the plugin started can hold a file open when the SimHub installer wants to replace it.
The helper's 30-second timeout now actually fires. Since 2.24.2 the plugin read the helper's
output to its end before waiting with the timeout, so a helper that hung after printing blocked
the Test button forever and the kill was never reached; the two streams are now drained as they
arrive, the wait carries the timeout and a stuck helper is killed and reported at 30 seconds
(a hanging helper in the suite is killed at 1.5 s of a 1.5 s limit, its files released before they
are deleted).
2.26.1
Both looks in git, and the README on the Compact ones the maintainer asked for.
Added
The overlay gallery is a gallery again.docs/OVERLAYS.md is one table row per overlay — name, size, route, the Large and the Compact preview, one sentence — and the long descriptions moved verbatim, headings and anchors intact, to the new docs/OVERLAYS-DETAILS.md (with the car classes, game years and data-availability sections).
Compact picker images beside the Large ones.toolsCapture-Previews.ps1 -Layout compact writes
<Name>.compact.png (400 × 400) and <Name>.compact.thumb.png (100 × 100) for every overlay and
dashboard next to the Large pair the packages ship, so every renderer has its two looks and their
thumbnails committed. The README shows the Track Map, the Leaderboard and the Proximity Radar in
Compact.
Changed
?layout=large|compact and ?ts= work on any route, not only under ?demo=1, so the
state-fed map, circle, tower and timing panels can be captured in Compact against the preview host
(no SimHub URL carries the two queries; a saved setting is untouched).
The Proximity Radar's picker icon shows the shipped default marker — concentric circles, not
the crosshair — at 50 % guide opacity through a new ?guide=<10..100> capture query; the saved
default stays 40 %.
2.26.0
A readability-at-speed design review of every overlay, then the fix. The maintainer drives on a 32"
2560 × 1440 monitor at about 75 cm and places most cards well below their packaged canvas — the tyre
cards at 0.63×, the Pit Window and the radar at 0.53×, the circle at 0.59×, the wide relative panel
at 0.61× — so a 9–10 px label rendered at canvas size arrived on screen at 5–6 px and a 13 px value
at 7–8: not read, at any speed. ISO 15008's 20 arcmin for in-vehicle reading is 28 px on that screen
for a value and 18 px for a label; divided by the placement, that is the floor every driving element
now has to clear in canvas units (45 / 29 on the tyre cards, 53 / 34 on the Pit Window, 48 / 31 on the
circle). Seven review reports (five overlay groups, the settings page, the design system) inventoried
every text and graphic against those floors and found most cards failing by two to five times; nine
implementer groups then rebuilt every renderer around one parametric geometry, with the 2.25 look kept
intact as a second layout. Canvases, GUIDs and the saved layout file did not change.
Added
A Large layout on every driving overlay, and it is the default. Large keeps the two to four
things a driver needs at speed at or above the floor and demotes or drops the rest; Compact is
the 2.25 look, pixel-identical at 100 %, for streams and for anyone who scales their windows up.
The General tab's Display row has a Layout & text size card — Default layout (Large /
Compact) and Text size (70–160 % in 5 % steps) — and every driving overlay tab carries the same
card second from the top with its own Layout (General / Large / Compact) and Text size. The
two multiply (100 % and 100 % is the designed ladder; 70 × 70 cannot go under 50 %, 160 × 160 not
over 200 %) and scale values, labels, chips, glyphs, row heights and gaps together: a bigger
font gets a bigger row, and a card that no longer fits reflows in a fixed order — optional text
first, then rows and tiles from the foot, then a name compressed to 85 % and cut with an ellipsis —
and never squeezes a value under its floor; where even that is not enough the text size clamps at
the point where the primary value at floor size fills the width. The plugin only validates the
four values; the renderers resolve them.
Grouped sliders. Where an overlay already had several size sliders, the Large layout reads only
Text size plus the sliders that size something other than text — the Track Map's and the circle's
Marker size and Your car emphasis, the radar's Guide size, Guide opacity and Car
size. Nothing configurable was removed: the sliders only the Compact layout reads (the Track
Map's label size, gap and border width; the circle's label size, gap, centre text size and border
width; the leaderboard's row height and four column sizes; the radar's own-car icon size) sit under
a collapsed Fine tuning (Compact layout) expander at the foot of the card, with their keys
unchanged, so a tuned value is neither lost nor in the way.
Demo overrides for captures and tests. Under ?demo=1 a renderer accepts &layout=large|compact
and &ts=<0.5..2>; ?layout=compact&ts=1 reproduces every 2.25 picker icon exactly. Every driving
text carries a data-role (hero, value, name, label, tag, chip, unit, title) in
both layouts, which is what the floor check reads.
A readability floor check, tests\Floor-Check.ps1. No build, no SimHub: it renders every driving
overlay in its driving state with headless Edge, measures every visible text as canvas px × the
placement, and fails a value or hero under the value floor, a name under 22 effective, a label,
tag, chip, unit or title under the label floor; at -Ts 1.6 it fails anything that leaves the
viewBox or any two values that overlap; at -Layout compact -Ts 1 it fails any size that differs
from the checked-in tests\floors-compact-baseline.csv, the "untouched look" contract.
Changed
Every overlay's Large layout, one line each (canvas px at 100 %, for the placement the card is
designed for; Compact is unchanged unless a fix below says so):
Tyre Life — laps to the wear target in rows of ring and number sharing the card's height
(rows up to 96 tall: glyph 58, letter 35, laps 61), the fitted set as a red bar and a 29 px
sub-row (TO 50% · S · 29% · L9), a 29 px outlined EST; compound names and section bands are
Compact's; the wet pair gives way when five rows would put the number under its floor.
Tyre Delta — a BEST strip under the header (ring 48, name 36), the same row outlined in white
in the list, deltas up to 56 with glyph 60, a 29 px NEW tag; the reason line and set counts are
Compact's.
Pit Window — LAP 20–26 at 84 with a 34 px LAP, a 320 × 66 compound pill (53), a 34 px
caption, three 60 px strips on the foot (label 34 / value 53: PIT TIME with the penalty and wing
named on the label, PENALTY or REJOIN, the fitted set with its wear and laps left); a running
safety car or incoming rain takes the header in amber.
Start Report — a 44 px verdict band at 28, REACTION and 0–100 tiles at 40 with 18 px labels
and units, up to three 18 px coaching lines and the session best; the clutch, grip, throttle and
shift tiles are Compact's.
Tyre Prep — one 44 px verdict band (COLD −14° · FRONTS, IN THE WINDOW, HOT +8°), four
96 × 74 corner tiles with the temperature at 30, the target window at 28 and the mean at 36, the
action alone in an 18 px coaching tile; chips, surface temperatures, wear bar and pace line are
Compact's.
Leaderboard — a 45 px header with an 18 px title, 19 px positions, 20 px three-letter codes,
23 px gaps and lap times, a 25 px tyre glyph, a 20 px flag banner, the ERS store as a 38 × 3 bar
under the code, 30 px rows; as many rows as the height allows, the top three and a block around
your car when the field is longer; it sheds the tyre glyph, then decimals, before squeezing a
value. Compact keeps surnames, the battery column and its five sliders.
Driver Ahead and Behind — per side a 90 × 148 position box (56), the name at 36, the tyre ring
44 with the age at 30, the DRS / AERO pill 84 × 40 at 28, the gap at 56 and the lap delta at 46
with 24 px captions naming the delta's subject and the source; the lap clock, the six sector
cells and the ERS store are Compact's. Standings show the gap alone (the delta was the same
number with the sign flipped); Time Trial names the PB by its lap time.
Driver Relative — codes at 20 and gaps at 28 around P4 at 32, team stripes beside the
codes, chevrons 40 × 24. The card wants a 1.0 placement.
Track Map — markers 1.25 × the Marker size slider (radius 18.75 at the default 15) with a
25 px numeral (31.6 for you), 25 px badges on you and your two road neighbours each side only,
pit-lane cars as bare dots, sector / DET / corner labels dropped while their ticks stay; a badge
that would cover another car or leave the canvas moves to a free side. Compact keeps every
label and its sliders.
Track Position Circle — the centre stack at 38 / 54 / 64 / 54 / 38 (names, gaps, P16),
31 px ring labels on four cars only (you, the leader, the two centre names), sector letters
dropped, REJOIN P4 at 34 over PIT 13.9s at 31; the names give way first when the text grows
past the disc, then the arrows.
Race Control — a message that fits runs as one 40 px line; a longer one splits at the game's
own clause into a 32 px headline and a 20 px detail; the RACE CONTROL: / FIA STEWARDS: prefix
is left to the FIA mark; the lap tag is 20 px and the team bar full height.
Weather Forecast — rain at 32 (36 at three chips), offset 21, condition name 22 and fitted,
icon 52; at five and six chips the name gives way to the icon; with temperatures on, the track
(and at three chips the air) temperature takes the name's row; the strip drops the furthest
forecasts as the text grows, never squeezing the number.
Qualifying Traffic — code and seconds at 36 on one line, PUSH LAP / FAST CAR at 20 in the
warning's colour with the metres under them, the +N as a 34 px circle; the second line goes
first, then the +N, and an unknown gap is an em dash rather than a crowded name.
Pit Stop Helper — three texts: the number at 40, the instruction at 24 beside it after a
column reserved for the phase's widest value, one 19 px line with the limit, the distance and
the one warning in the tone colour; the icon scales 1.16× with the text.
Safety Car Helper — a 44 px state band (title 28, phase 20; a VSC is titled VSC, the period
lap dropped), the delta as a 52 px hero with a 22 px state word beside it in the short forms
(SLOW DOWN 7.0s, GET POSITIVE), the call at 40 with its 20 px reason on its own line and a
38 px glyph, the estimate as a bare 19 / 30 row, no footer; the whole delta block turns amber
under the delta and red once the grace is out, steady, with the border pulse as the second cue;
the panel ends at the last block it shows.
Start Helper — two columns: bars on the left (REVS 19, target line 19, throttle bar with its
value at 24, one shift chip beside the clutch lamp, 19 px condition chips or the launch row on
the foot) and a 200 × 78 verdict box on the right at 36 with the gear at 48 and the revs at 36
under it; at lights out the box itself is the green GO for 0.8 s in both layouts.
HUD — gear 44, speed 28 with its unit at 14, a 126 × 30 DRS pill (label 16, metres 18), fuel
laps 24 with a 14 px mix tag, ERS store 24 with the mode as OFF / MED / HOT / OVT in a 14 px
tag, rev lights on a 15 px pitch, the track-limit count as a WARN n chip under the speed only
while it is above zero; the RPM numeral, the temperatures and every word in the trace popup are
dropped; the dials scale to 1.15× at most and the HUD stops growing at 1.6×.
Proximity Radar — contacts and the own car as 22 × 52 shapes with a 3.5–4 px stroke and an
8 px halo, the crosshair at 5 px, the circles at 2.5, a contact alongside pushed out past the
centre marker so an overlap reads beside the car; contacts are never dimmed by the overall
opacity; full mode keeps the call at 56, the rails at 44 wide, the pit tag at 34, and drops the
header, side words and lane guide. The glyphs follow Car size, Own car size and Guide size, not
the text size.
Inputs — the graph without a word (a NOW edge at its right end), 44 px pedal bars with a 28 px
value and an 18 px label that double as the legend, the wheel at full size, the gear at 80 over
the speed at 48; the DRS chip and rev dots dropped; the wheel hides from 1.4×.
Delta vs PB — the hero at 64 (capped at 96, orange halo while estimated), a 28 px bar, a 20 px
EST tag, the reference in a 24 px band (PB 1:30.988); the title, the direction word and the
FASTER / SLOWER / SCALE captions are Compact's.
Damage & Power Unit — the summary as a 72 px fault band at 32 over six 222 × 150 tiles (label
20, value 64), the constant WORST lines and the developer footer dropped; the damage page's
corner tiles at 36 / 28 with 18 px labels and the schematic shrinking to its well; the power-unit
page's split at 40, temperature at 56 and eight 222 × 60 wear tiles at 28.
Lap Chart — focused mode zooms the position axis to the cars on the chart in both layouts (one
position of headroom, at least six tall; lapchart-normal spans P1–P8 at 43 px per position
instead of 14); Large names each car at 26 (the player 30) with its position in an 18 px chip,
the player's in a filled pill, axis labels 18, an outlined EST in the header only when sampled.
The Steering Wheel is one ladder, scaled by a Text size of its own (70–130 %). Labels and
units 22, names 26, the lap counter, gaps, last and best 44, secondary values 40, tile values 42
stepping 36 → 32 → 26 before any squeeze, the flag title 44 left-anchored, the pit-limiter
over-speed 56 as the red band's own hero; the head row 48, a tile 100, the damage row 90, the small
gear 40 in a 96 × 48 well; the middle of each page takes what is left and gives way before the head
or the foot. The dial tile's ring lost the 14 px number inside it (the number is on the chip and in
the popup); the dial chip is value-only (detent number 22, label 26, no ring) on Timing and Systems,
and on Tyres a dial rides on the foot as a tile instead; the Systems foot gives its double-width
tile to the pit window and loses AIR, ENGINE and BRAKE BIAS (Tyres foot tiles); the MGU-K bar
carries no word; the session tag reads Q2 · 8:42 and is dropped on the Race page in a race. The
Time Trial fixtures now carry the plugin's real shape (a null wheel delta, the PB under
Reference).
The Race Control Dashboard has one Text size (70–160 %) in place of its three text scales.UiScale, GadgetScale and ClassificationScale fold into TextScale once on the first load
(a value you had pushed keeps its push as the largest ratio to its old default, rounded to 5 %:
the maintainer's 1.3 classification reads 115; untouched factors read 100), CircleRadiusScale
is dropped (the ring follows Map size at the ratio it had), and the four old keys leave the
file on the next save; Map size now runs 60–100 % (the default 95 % is already the largest
ring that keeps the rejoin cue in its box, so the old 100–135 % did nothing and a saved value
above 100 reads 100) and Marker size keeps its meaning. The dashboard is drawn on one Large
ladder — 18 px labels, 28–34 px values, a classification with 28 px positions, 22 px names and
24 px gaps in 34 px rows, the ring's initials and the rejoin cue always 18 px on screen — and
reflows instead of shrinking: a gadget shows the tiles its zone can hold at the value floor in
priority order, the classification drops columns from the right and windows its rows around you,
rival cards step down to a bare gap, headers and timing-bar cells that duplicate a gadget leave as
the text grows. The Tyres gadget colours the temperature by the compound's carcass window (the
dashboard state now carries the wheel's TyreWindow) and the wear and brakes by the wheel's
thresholds; a penalty is red, an interval is a gap, a dash never carries a colour, the sectors in
the Lap timing gadget read three decimals coloured against the best, LIVE chrome and the map
caption are gone.
Defaults reviewed with the layouts (fresh installs and Reset; a saved file keeps its values,
except that a value still sitting exactly on its old default is lifted once by configuration
revision 3): the circle's centre text 100 → 115 % and its overall / marker / label opacities
50 / 80 / 80 → 80 / 100 / 100; the Track Map's marker opacity 80 → 100; the radar's guide size
100 → 120 (over 20–240), guide opacity 100 → 40 and overall opacity 65 → 100; full overall opacity
for the Start Helper (was 60), Qualifying Traffic (70), Pit Stop Helper, Safety Car Helper, Tyre
Life and Tyre Delta (80) — the cards in the direct sight line; the two timing panels' background
and the leaderboard's row and header colours move from the 1.x navy (#143946, #182030 /
#0B111C) to the design system's #15151E / #1F1F2B. Clamps raised so a Compact user can still
reach the floors by hand: Track Map marker size 8–30 and label size 9–40, leaderboard row height
18–44 and its three text columns 7–26, radar guide size 20–240.
Settings page. Slider readouts are spaced one way (25 px, 2.00 s, 95%, 0°); the words
are colour and centre throughout, in the save messages too; the two wing settings read Front
wing change time and Change the front wing from damage of; Marker size and Your car emphasis
on both map tabs, Guide size, Guide opacity and Car size on the radar; the long labels
shortened (Delta grace period, moved into the Safety Car Content card with its explanation;
Only with fuel for this many more laps; Forward reach (share of the range); Rev strip blinks
from); the Track Map's Status card folded into Appearance; the Race Control tab's rows a plain
field list; the Sound Commands pickers, the Analysis sample-rate and archive filters and the
Diagnostics level picker drawn as dark combo boxes with white items like every other picker; the
sample-rate hint's disk figures corrected to the documented 0.57 / 0.29 / 0.10 MB per 100-second
lap.
The Safety Car Helper's must-stop reason reads STOP NEEDED · 2-COMPOUND RULE (was STOP NEEDED ANYWAY · …), which fits the 20 px reason line.
Fixed
The Track Position Circle cut its ring labels off at the maintainer's own Label size of 24 — a
label at three or nine o'clock left the canvas (MA|), and one under the rejoin pill vanished
behind it. A label that would run off the canvas or under the pill now moves inside the ring on the
same radial, or slides into view, in both layouts.
Damage & Power Unit painted every percentage white. A stylesheet fill on the value classes
overrode the colour the script set (the text{fill} trap from the project notes); the default fill
is on the <svg> root now, so a non-zero percentage is amber and 0% is grey, as documented since
2.17.
Tyre Prep had the same bug: the temperatures, the mean, the verdict, the chips, DO THIS, the
wear and the pace value were all white although the code coloured them. They go through the same
css() path as Tyre Life's now, in both layouts, so the Compact icon gains its intended colours.
The HUD's proximity rails sat over the two gauges. They now hang above the body on either side
of the rev tab, where neither the dials nor the open trace popup reach, and THREE WIDE sits
centred above the tab.
The Safety Car Helper's green-flag state left a hole where the call gadget had been, printed
SC LAP 1 under RACE RESUMED, and kept its full 262 px panel with nothing in the lower half. The
tiles move up when the gadget hides, no period lap is shown under a green flag, the panel ends at
the last block it shows, and the red-flag band carries white ink.
Delta vs PB flashed its clip rails, EST tag and trace on the first paint before the first
snapshot hid them; they start hidden in the markup, so the "session changed" state shows the dimmed
hero and bar alone.
A name that did not fit was squeezed without a floor — fit() compressed glyphs indefinitely,
so a long surname on the tower, a relative card, the wheel or the circle could become an unreadable
smear. The shared helper now compresses to no less than 85 % of the natural width and then cuts
with an ellipsis (the tower and the relative cards fall back to the three-letter code instead of a
cut); the Start Report verdict and the Start Helper verdict shrink to their band before a cut.
The Lap Chart's focused mode plotted five cars on a fixed P1–P24 axis, a quarter of the plot;
the axis now follows the cars on the chart.
Renderer fallbacks disagreed with the C# defaults — the Track Map's DotSize 12 / LabelSize 13 / LabelGap 2 against 15 / 15 / 3, the circle's 9 / 14 against 12 / 24, the tower's 11.5 / 10.5 / 9.5
fonts against 12 / 12 / 9, several OverallOpacity 100 against 80 or 90, the radar's demo values
against the new guide defaults — so a page rendered before its settings arrived, and every demo
capture, showed a card that did not exist. Every fallback and every demoSettings() now mirrors
the C# default.
Qualifying Traffic's gap sat 37 px in from the gutter when no +N was shown; it anchors at the
gutter now.
The Pit Window showed a PENALTY NONE tile taking a row from CURRENT TYRES; a penalty tile
appears only while something is pending, and a condition tag reads amber.
Tyre Prep printed 74 without a degree sign and showed the pace line on an out lap; both
fixed.
Validated
Renderer evidence only — no reader or packet rule moved. Every group measured its Large layout at
1.0 with a computed-style probe against the brief's floors and at 1.6 with an ink-box probe for
overflow and overlap, and pixel-diffed its Compact layout against the committed 2.25 renderer; the
C# side passes 4,344 assertions (the revision-3 carry, every clamp and control, the dashboard's
TyreWindow), the installer and setup suites 48 and 56, and the 24 picker icons and three dashboard
stills were captured from the simulated preview host. tests\Floor-Check.ps1 on the final tree: Large
1.0 — 969 driving texts at or above their floors, 38 accepted with a written reason (the HUD DRS
distance at 18, the dashboard classification gaps at 24 and its map-page wear at 22); Large 1.6 — 683
texts, nothing outside a viewBox, no two values overlapping; Compact 1.0 — 587 sizes identical to the
2.25 baseline. Not validated: any Large card in SimHub's
own CEF window (every number is headless Edge with the Bahnschrift fallback; the Formula1 face is
wider, so the reflow thresholds will sit slightly lower), the settings page inside SimHub (the Layout
& text size cards, the Compact expanders and the restyled Analysis / Diagnostics combo boxes were only
opened in the test host), the live TyreWindow colouring on the dashboard, the Peek fade over a
reflowing card and the HTA host's IE11 rendering of the relative cards' Large geometry. See
TIMING-VALIDATION.md.
2.25.1
Thirteen reports from one online race weekend (20260917_201745, Baku in the 2026 car through a
practice, a qualifying and a race, then Silverstone in the 2025 car through a qualifying and a race —
five sessions, two hours, the first red flag ever recorded here) checked against the recorded packets,
the game's screen capture and the live SimHub log from the same night, then re-driven through a
from-scratch reader harness against the fixed build.
Fixed
Every card went dark for the first 2.5 s of the Baku race, and 0.9 s of the Silverstone one.
The lights-out clock rewind (4.68 s → 0.06 s) left the 5-second participants packet still reading
the old, higher clock value; the freshness check only ever tolerated a packet up to 2 s behind the
lap clock, so a packet now reading ahead of a just-rewound clock was refused until the next roster
packet arrived. A session or participants packet carrying the same non-zero session UID as the lap
clock now has no bound at all on how far ahead it may read — that can only be a rewind of the same
session, never a different one, and a lap packet that has genuinely stalled is still caught
separately — so the snapshot stays ready through the restart; this also quietly closes the much
larger, previously unbounded gaps at each formation lap's end (175.0 s / 147.7 s). A packet from a
different UID stamped ahead still fails.
A SimHub reconnection mid-race wiped the whole race's memory. After the Baku red flag's ~30 s
packet silence, SimHub minted a new SessionId while the raw F1 session UID and the lap packet's
own frame counter never stopped — the game's own bookkeeping says this was one continuous race, but
the plugin read any changed SimHub key as a brand-new session and reset everything: the lap-profile
PB reference went dark for about 15 minutes, the Start Report emptied, measured tyre-wear rates
reverted to estimates, and the Race Control feed sat empty for roughly two minutes. A SimHub
session-key change is now read as a continuation, not a reset, when the raw UID, the track and the
session type are unchanged and the frame counter is still counting up (a restarted replay or game,
where the counter goes backward, still resets as before); a SimHub id seen while the packet stream
itself is frozen is held pending rather than decided on the spot, and only confirmed as a keep once
a later, genuinely advancing frame arrives — deciding on the frozen tick alone risked reading an
ordinary reader restart as a real reset.
A televised camera cut could attribute another driver's pedals, position and lap data to the
player. Whenever the game spectates — a retirement, a qualifying disqualification, a mid-session
broadcast cut, the post-race podium camera — SimHub's convenience packet fields quietly followed the
spectated car instead of the player's own, even though the game's own header still named the
player's car; measured five separate times in one recording. The 60 Hz input feed, the analysis
recorder and the Start Helper now read the player's own car from the per-car array whenever the
session reports spectating, instead of trusting the convenience fields.
The Leaderboard's FASTEST LAP page showed a qualifying best in the first seconds of a race.
SimHub's normalized best-lap value survives the game's own session change. The tower's own rows now
blank a race car's best and last lap while its Lap is 1 or less; the underlying value is untouched
everywhere else, on purpose — the Safety Car Helper, Tyre Choice, Pit Loss and the Ahead/Behind road
estimate all still use the qualifying pace as their reference for the opening lap rather than
falling back to a flat default, and the Race Control Dashboard's own classification gadget keeps
showing it too, since its field payload also feeds a pace median.
Delta vs PB reported a runaway negative delta on every out lap, and again for two minutes after
the chequered flag. With the lap clock reading zero while the car was already rolling down the pit
lane, the wheel's own delta correctly stood down but the standalone Delta vs PB card kept comparing
against the lap fraction anyway, reaching −104.5 s at one point; the same thing happened again after
the flag, where the game freezes the lap clock at 19 ms but the car keeps driving on. The card now
reads Out lap while the clock genuinely is not running, Waiting for the lap clock when it has
held the same value for a full second while the car keeps moving, and Finished once the result
status says so — Live only while the clock is both positive and actually advancing.
A pending time penalty added seconds to the pit hold it was never served in. The game classifies
accumulated time penalties at the chequered flag; it never serves them in the pit box the way a
stop/go or a drive-through is. The plugin was adding them to the flat 10-second stop/go hold whenever
the serve flag was up, reading 16 s against a measured 12.9 s stop — the extra seconds were never
served and became classification time on top. The pit hold is now the flat 10 s whenever a stop/go is
pending, null otherwise; accumulated time penalties are never folded into it.
Baku never got its own pit-loss table entry."Baku (Azerbaijan)" resolved to a key that
matched neither the Baku row nor the Azerbaijan alias, so every stop fell back to the 22-second
global default all night — including a user's own per-track edits for Baku, which were silently
ignored the same way. Track-name resolution now also tries the name before a parenthesis and each
parenthesised part in turn, so SimHub's real spelling reaches the right row.
The Lap Chart could never leave "Waiting for fresh lap-position telemetry" on this feed. The
native lap-position packet was never received in any of five sessions of a two-hour online weekend,
and the sampled fallback that should have covered it was gated to formats older than F1 25. The chart
now samples lap boundaries in every format whenever the native packet has not been fresh this
session — on every snapshot the overlay is enabled for, not only while it is on screen, so a boundary
crossed while it is toggled off or peeked is still charted — and switches to the packet the moment
one actually arrives. A rewind or flashback now trims the chart back to the lap rewound to instead of
clearing it outright.
The Safety Car Helper ignored the red flag entirely. It read "SAFETY CAR ENDING · KEEP TRACK
POSITION" after the red flag was already shown, then "RACE RESUMED" in green straight through the
standing restart — the same message a genuine green-flag safety-car ending would show. A red flag now
overrides every safety-car phase with a plain RED FLAG and no pit advice (the game handles the
cars itself), ends the period's own memory, and drops straight to no card once the flag lifts —
a standing restart is a start, not something to greet with a green hold.
The Start Helper and Start Report never armed for a red-flag standing restart past lap one. Both
only ever armed at (player.Lap ?? 1) <= 1, so a lap-9 restart after Baku's red flag produced no
lights, no launch coaching and no journal entry, contradicting the documented behaviour. Arming now
also triggers whenever this race has had a red-flag period and the car is stationary on the grid,
whatever the lap, running the normal lights/launch/verdict cycle and adding a second entry to the
start journal.
Changed
The Safety Car Helper's net-gain call for a stop made the lap before a safety car now prices in
the stop's own cost, on every rung that can call a fresh set away. "BOX BOX" one lap after a stop,
on a set with zero laps of age, quoted a net gain that never accounted for the pit-loss seconds
already paid under that same safety car — the card priced the stint gain against the positions lost
only, as if the stop itself had been free, on the main pace call and on the two calls beside it
("rivals stopped" and "a free stop right now"). The stop's cost is now the larger of the pit loss
already paid this period and the seconds-per-position price of the positions lost — a full safety
car erases most of the lane time once the train forms, but the call still prices something, because
the gain side is only the game's own per-lap set-delta estimate and a wrong BOX call still costs a
place for nothing; under a VSC, with no bunching, the seconds are real either way — and a set younger
than the fresh-set threshold needs a larger margin before any of the three rungs recommends a stop.
Race Control messages now carry a priority. Deployment and red-flag messages, restarts, the
chequered flag and the player's own penalties or disqualification are Critical; everything else is
Normal, including the player's own black-and-white flag warnings (by design — a warning is not
urgent the way a penalty is). The player's own message is resolved by matching the event's own car
index against the player, never a race number, since two cars shared #2 all night. A Critical
message jumps the queue and can replace an on-screen Normal message after 1.5 s; the queue drops the
oldest Normal message first when it is full, never a Critical one. Before this, a six-second hold and
a five-message cap let ordinary warnings for other cars push safety-critical messages back far enough
that SAFETY CAR DEPLOYED and RED FLAG never reached the band at all for one sequence, and a second
safety car's own deployment message arrived 19 seconds late.
Ahead/Behind gaps in a race are now bounded by the plugin's own road-distance estimate. Passed
through unchanged, SimHub's on-track gap read +2.5…+8.7 s for cars under 10 metres apart on a
stationary grid and +45/+48 s for cars a few hundred metres apart right at the chequered flag — its
estimator does not cope with a stationary field or a finish-line slowdown. The panel now compares
that value against its own road-fraction × lap-time estimate and switches to the estimate when the
two disagree by more than double and by more than a second; the two panels and the two dashboards
read the source under IntervalSource/GapSource, and the wide Driver Ahead and Behind panel marks
an estimated gap with a small EST tag (the compact Driver Relative stack does not yet).
Validated
Offline, against the recorded packets, the game's screen capture and a from-scratch reader harness
driven over the fixed build (20260917_201745): all thirteen fixes confirmed landed, including a
second harness run across the SimHub reconnection itself with zero differing columns for the rest of
the race. Still pending a live session: the ordering of a real SimHub id change against the first
post-reload packet, a SimHub id change occurring inside a flashback, the Race Control ticker's 1.5 s
pre-emption and the Start Helper's lights-only (no counter) restart path in a browser, and the
Start Report's reaction time, which reads a consistent ~0.14 s longer than the game's own
m_startReactionTime across all three starts checked. See
TIMING-VALIDATION.md for the full evidence and the harness tables.
2.25.0
Added
Show an overlay for a moment. Every overlay's Show / hide card has a second bindable control,
Show for a moment (Peek<Name> in SimHub's Controls and events, beside Toggle<Name>):
the overlay fades in over 250 ms, stays for Seconds it stays (7 s by default, 1–60 s, set per
overlay) and fades out again over 250 ms. Made for an overlay whose Visible when SimHub starts is
off — a glance at the forecast or the tyre cards without leaving them on screen. The fade is
SimHub's own: the plugin publishes Overlay.<Name>.Opacity (0–100) and every packaged overlay item
binds its Opacity to it next to the existing Shown binding, so the ramp runs at the dashboard's
33 ms refresh and no renderer changed. A peek overrides Hide while you are in the garage (it is an
explicit request) but never a disabled overlay; pressed again during the hold it restarts the timer,
pressed during the fade-out it resumes the fade-in from the opacity on screen, and the Show / hide
action always takes over (a toggle cancels the peek). An overlay that is already shown ignores the
peek rather than dipping to transparent.
Changed
Shared settings moved to the General tab. A setting that meant the same thing on more than one
overlay now lives once, on General, instead of on each overlay: Speed unit and the rev-strip
blink threshold (HUD and Steering Wheel), Show the intermediate and wet compounds (Tyre Delta
and Tyre Life), Motion smoothing with its frame rate (Track Map and Track Position Circle) and
Pit indicators (Track Map, Track Position Circle and Leaderboard). An existing configuration keeps
its values: the first load after the update carries the per-overlay values into General once (where
two copies disagreed the HUD, Tyre Delta and Track Map values win) and the old keys leave the file on
the next save. Settings whose defaults differ by design — Hide while you are in the garage, the rev
lights on or off, the temperatures on the Weather card and the HUD — stay per overlay. The Dash
Studio properties Overlay.TrackMap.ShowPitIndicators, .MotionSmoothing, .SmoothingFps, the
Overlay.PositionCircle trio and Overlay.Leaderboard.ShowPitIndicators keep their names and now
read the General values.
The General tab is a strip of three pages, like Overlays, Dashboards and Analysis: Driver
(driver identity, local server, data), Timing (who to compare against, sector clocks) and
Display (speed & rev lights, tyres, maps & field). One Save and apply / Reset to defaults bar
serves all three.
2.24.15
Added
Time Trial classifications with the personal best and the rival. In a Time Trial the
Leaderboard tower and the Race Control dashboard's Classification gadget used to show one row,
because the game's ghost cars and parked reference slots are kept out of the field on purpose.
Both now classify the same three things the Ahead / Behind panels compare against: your session
best, your personal best and the rival loaded from the leaderboard, ranked by lap time by
the plugin (fastest first, a row without a lap last, and your own row ahead of an identical
personal best set this session). The tower names the reference rows PERSONAL BEST and
RIVAL · <gamertag> (the gamertag steps down a size to fit, then falls back to RIVAL), draws no
tyre glyph or battery for them, and gives the fastest of the three the purple position box; the
dashboard names them PB / RIVAL in its status column, shows their lap under BEST, and gaps the
rows by best-lap difference under GAP and INT, with the grid-delta column left empty. The tower's
INTERVAL and GAP TO LEADER pages, which had no meaning in a Time Trial before, join its rotation
as soon as a reference row is present (best-lap gaps, as in qualifying); FASTEST LAP stays the
first page. The rows follow the General tab's Time Trial: your personal best and the rival
switch, and a session best standing in for a missing personal best is not repeated as a row of
its own — it is your row. F1 23 has no reference packet, so there the tower stays as it was.
The dashboard's Classification keeps table-height rows at the top when the field is far smaller
than the box (a Time Trial's three rows, a two-car practice) instead of stretching each row into a
band.
Fixed
The tower re-finds its current page by name when the page list changes mid-session, so the two gap
pages appearing with the first Time Trial reference no longer move it from FASTEST LAP to INTERVAL.
2.24.14
Eleven reports from one Baku race weekend (20260917_123129, Red Bull Racing '26, practice through
retirement under a second safety car), each checked against the recorded packets and, where the
plugin's own overlay could appear in it, the game's screen capture.
Fixed
The Tyre Prep card could latch on a genuinely quick lap. The player's first qualifying push lap
(102.080 s) was judged against another driver's freshly-posted, unrelated first lap of the session
(102.594 s, then 102.162 s) the moment it appeared at lap fraction 0.68 — a lap nobody had beaten yet
became "the best" mid-lap, and the card's naive current / fraction projection read 10–12 % slow
against it until fraction 0.90, even though the player's lap ended up faster than both numbers it was
compared with. Confirmed on screen: the card showed "TIRE PREP" for 18 s, frames 45600–46530. The pace
reference is now frozen at the start of each lap, and without a personal reference trace the live
projection can only release an existing latch, never set one.
A pending stop/go penalty was charged twice. The game serves one stop/go per pit stop — counters
2→1 (frame 78715, 159.29 s) then 1→0 (frame 85635, 301.33 s), each with its own SGSV — not both at
once, but the plugin summed the count into the displayed penalty (+10 +10). Driver.PitPenaltySeconds
is now a flat 10 s whenever at least one stop/go is unserved, never count × 10. The SC card's reason
line reads SERVE STOP/GO · 1 MORE NEXT STOP once a second one is pending (its narrow PENALTY tile
the same fact as STOP/GO · 1 MORE), the Pit Window's wider penalty tile reads STOP/GO · 1 MORE NEXT STOP, and the circle names it on its own rejoin-position line, REJOIN P18 · 1 MORE, with the
seconds alone on the line below (PIT 18.5s · +10s PEN).
The measured hold really is close to 10 s — m_pitStopTimerInMS
stayed at 0 for 10.917 s and 10.763 s at the two stops before any tyre work started — what made the
stop feel longer was the tyre change and, at stop 1, a front-wing repair stacked on top.
A drive-through was never served by a pit stop, but the cards suggested it might be. The DT
penalty (m_numUnservedDriveThroughPens 0→1 at frame 107257, 826.34 s) stayed 1 through the player's
next stop (t = 887.95–896.67 s), with no DTSV anywhere in the race and the counter still 1 at
retirement. The Pit Window now carries its own UnservedDriveThroughPenalties, so its penalty tile
agrees with the Safety Car card instead of reading NONE (DT / DRIVE-THROUGH · NOT SERVED BY A STOP in full; the SC card's own narrow penalty tile fits the same fact as DT / NOT SERVED BY A STOP); the SC card's reason line says the full thing too (DRIVE-THROUGH FIRST · BOX A LAP LATER
when a stop is also owed for another reason), and a pending DT is never masked by a simultaneous
stop/go. Under green flag racing, the card's big call also gained its own DRIVE THRU in amber for
this case, instead of the green STAY OUT it used to share with "already stopped this period" — a
drive-through is served by driving through the lane, not by staying out or by boxing. A drive-through
cannot be served while a safety car or VSC is deployed at all (FIA Sporting Regulations Art. 54.4, and
consistent with F1 2018/22 player reports — not directly confirmed on F1 25), so while a period is
active the card withholds DRIVE THRU. When the ladder's own call is otherwise a hold-position
line (nothing more urgent to say), that line is replaced outright with DRIVE-THROUGH · SERVE AFTER THE RESTART (Deployed) or DRIVE-THROUGH · SERVE AT THE RESTART (Ending); when the ladder is
already calling a genuine stop (a pending stop/go, say), the reason line stays with that call instead
(SERVE STOP/GO · REJOIN P18) and the drive-through reminder rides beside it on the penalty chip, since
a driver already being sent to the pits does not need a second line telling it. Either way the card
reverts to DRIVE THRU itself once the restart's green-flag hold begins. A stop/go penalty is not
held back the same way — measured on a Melbourne recording to serve normally during a pit stop made
entirely under a live full safety car — because F1 25 does not apply the same real-world restriction to
both penalty types.
A front-wing change added several seconds to a stop that the pit-time estimate never counted.
Comparing the player's own wing-repair stops with plain tyre-only stops (stop 2: 2.514 s, stop 4:
3.335 s) against wing-repair stops (stop 1: 7.708 s, stop 3: 7.731 s, stop 5: 6.445 s), and cross-checked
against the AI field at the mass SC2 stop (15 no-wing cars at 2.06–3.36 s, Pérez's wing repair at
7.106 s; two AI cars left 25 % wing damage unrepaired at no time cost), a wing change costs about
4.0–4.5 s of m_pitStopTimerInMS on top of a plain tyre change — the same number the game's own
"Estimated stop time" HUD line shows. The pit-loss estimate now adds a configurable Front wing
change (s) (default 4.5 s) whenever Driver.Damage.FrontWingPercent is at or above a configurable
Front wing change threshold (%) (default 20 %; not itself measured — the AI's own repair/no-repair
split only brackets it between 25 % and 49 %) on the Track Position Circle tab, added after the SC/VSC
neutralisation like the penalty term. The SC card gains a +4.5s WING sub-line, the Pit Window's pit
line carries the same addition and the circle's rejoin label adds +4.5s WING, and an AI stop with
damage past the threshold is rejected from the clean-baseline pit-loss learner.
Pausing under a safety car turned a "stay out" call into a fresh "box box." Five real pauses,
all under the second safety car (one of 26 wall-clock gaps over 3 s across the whole recording — see
the packet reference for the rest), froze the session clock for 24–67 s of real time (e.g. frame
109741→109742, a 66.6 s gap) while m_gamePaused stayed 0 throughout — only the pause at retirement
itself raised the flag.
The plugin's 3 s continuity check plus a 2 s reset timer treated every one of those five as a stalled
session and reset the readers, which made the Safety Car Helper forget a stop already served this
period. A data gap no longer resets session state by itself: readers reset only on a genuinely new
session identity (SimHub's own key changing, or the game issuing a new raw session UID), and a clock
rewind (a flashback or the lights-out clock restart) still resets only the push/prep detectors it
always did, never the safety-car or pit-loss readers. StopDone now survives a frozen gap of any
length with GamePaused or GameRunning false.
A player one lap down showed +1 LAP one moment and a seconds gap the next, and a backmarker
lapping the player looked greyed out like a car behind. The player fell to P22 in the opening-lap
incident (frame ~70300–70440, ten positions in under three seconds) and became officially one lap down
at the start of lap 4 (frame 92580, 460.4 s), pitting under the first safety car while the leader's
lap counter ticked over — from there the gap never returned to zero, staying at least one full lap
(6.0–6.7 km) behind the leader for the rest of the race even while passing cars at the SC2 restart.
The timing tower and the leader-gap logic now ground "laps down" in a new Driver.TotalDistanceMeters
property (from m_totalDistance; adds 52 SimHub properties across the Player/Drivers.*/Standings.*/
Ahead/Behind views, like any other scalar driver field) through a shared LapProgress helper,
instead of SimHub's opaque LapsToLeader and a lap-fraction fallback that could flip to a seconds gap
around the moment either car crossed the line. The Track Map, Track Position Circle and the Race
Control Dashboard's lap ring now dim a car only when it is a genuine backmarker (a whole lap behind
the player); a car lapping the player — Hamilton passed the player twice, at frames ~93000 and 110220,
staying exactly one lap ahead throughout — draws at full colour like everyone else on the road.
The BOX call for hards during the first safety car was correct but never said why, and the Pit
Window's "fastest to the flag" soft recommendation ignored its own life number. At the first SC
(engine horizon 15 laps) two fresh softs, a lightly-used medium and a used hard were all available,
and only the hard's own life reached that horizon — the engine's call was right, it just never
explained itself. At the second SC (engine horizon 12 laps, matching the "about 13 to go" report —
the difference is the lap already in progress), the fresh soft's own life fell 2 laps short of the
horizon, so it could not have reached the flag on one stop, while the strategy call and the Pit
Window disagreed about it because only one of the two paths re-checked against an immediate stop.
Both paths now share one ImmediateChoice check fed by the engine's own laps-remaining figure and
its own set-life numbers (from m_lifeSpan, not the raw m_usableLife field), and a reason
vocabulary that distinguishes ONLY SET TO REACH THE FLAG (the hards case, SC1) from an unqualified
FASTEST TO THE FLAG (the medium at SC2, where softs and hards both remain physically available but
only the medium is both immediate-finishing and fastest) or a FASTEST · BOX LAP N qualifier when
the immediate winner would need the stop moved later. The Pit Window pill now prints the recommended
set's own laps-to-the-cliff figure beside its reason (N L TO 70%, or the configured cliff), a
different measure from the Tyre Life card's existing TOTAL LAPS TO 50% WEAR header line, so the two
numbers are never mistaken for one measure. The Tyre Delta BEST tag now follows this same resolved
answer instead of a plain ranking, so the delta tag, the Pit Window pill and the Safety Car Helper's
recommended compound cannot disagree.
The overlays kept advising a car that had already retired. After m_resultStatus settled at 4
(frames 112989→112990, RTMT then SEND), the Safety Car Helper, Tyre Choice engine and the tyre strategy
cards had no rule to stand down. CarDetailsReader.ApplyPlayerState now sets Driver.Retired, and the
Safety Car Helper shows a neutral RETIRED band instead of BOX BOX or STAY OUT; the tyre cards keep
their frame with no recommendation. Driving the fix through the real engine over the recording caught
a second bug in the first cut: the relative panel's early-out for a retired player skipped setting the
session mode it reports, which made the Safety Car Helper's own race-only gate fire first and blank the
card instead of showing RETIRED; the gate no longer depends on that.
A safety-car restart could trigger a false "track going wet" call. For about 8 seconds right
after the second safety car deployed (frames 106830–107140), the game's own per-set lap-time delta
for intermediate tyres briefly compressed (5666 ms → 3983 ms) while the weather stayed dry
(m_weather 1, forecast rain 11–12%, byte-identical throughout) — the game rescaling its delta model
at safety-car pace, not real rain. The tyre-choice engine read the collapsed spread as the track
going wet and briefly recommended an intermediate. Evidence from that spread is now held while a
safety car or VSC neutralisation is active.
The no-stop payback test compared the wrong kind of delta. An earlier cut of the "no stop
needed" check (see Added, below) used the game's instantaneous per-lap delta between two tyre sets
as they stand right now, which knows nothing about the fitted set continuing to wear — a gap that
only widens with age — so the test could flip back to recommending a stop mid-stint with no real
event behind it. It now integrates the fitted set's own degradation over the laps remaining (the
same slope the predicted pit window already uses) against the pit loss, and only counts a candidate
set that satisfies the two-compound rule without needing a stop of its own — a set that would break
the rule, or that would need a further stop to finish, is no justification for making this one. The
two-compound rule now outranks the near-the-flag exception unconditionally: it is checked as still
owed rather than merely open, so it keeps vetoing a no-stop call on the last lap of a race even
though there is no longer a window left to serve it in, since owing it is still a disqualification.
The wet-tyre crossover guard now compares the full three-way family (dry/inter/wet), not just
wet-vs-dry, so an intermediate-to-wet change is caught the same way a dry-to-wet one already was.
Added
Front wing change (s) (0–15 s, default 4.5) and Front wing change threshold (%) (5–100,
default 20) on the Track Position Circle tab's pit-loss card.
The Pit Window and Race Control Dashboard now say when no stop is needed at all. When the fitted
tyre set can reach the flag and nothing hard-vetoes a stop — the dry two-compound rule, a pending
stop/go or drive-through, a wet/dry crossover, a safety car/VSC period live, or (under green only) a
front-wing repair at or above 50 % damage (TyreStrategyReader.ForcedWingRepairPercent; below
that the wing does not force a stop, though under a caution the SC card's own 20 % damage threshold
still drives its own free-stop call independently) — and the pit loss itself would not be won back
inside the laps remaining, the Pit Window pill reads NO STOP in green with CURRENT TYRE TO THE FLAG · N LAPS LEFT, naming instead the tyre a free stop under a caution would take (IF SAFETY CAR); the Race Control Dashboard's strategy gadget mirrors it (NO STOP / IF SC: SOFT) and the
Steering Wheel dashboard's Systems page PIT WINDOW tile joins them (NO STOP in green with the
free-stop compound ring and an IF SC label, replacing the game's own lap-range readout). A pending
penalty and the two-compound rule are hard vetoes on every lap, including the last, since a stop that
cannot be avoided is never waved off; fewer laps remaining than a minimum useful stint
(MinimumUsefulStintLaps, 2) only outranks the two soft vetoes — the wing threshold and the pace
test — because a stop with nowhere left to pay itself back is never worth recommending even when
those alone would otherwise force one. Measured on the Melbourne recording: NoStopPlanned was true
only on laps 3–5 before a front-wing knock (m_frontRightWingDamage 0→40 %) forced a stop from lap 6
under the old any-damage rule, even though the payback test agreed with no-stop all the way to the
flag (lap 14: a 1.84 s pace gain against an 18.0 s pit loss). New PitWindowState.NoStopPlanned,
SafetyCarCompound, SafetyCarCompoundName, SafetyCarCompoundReason fields.
Changed
The unidentified-field colour palette is darker and reordered. Measured on the
20260917_153124 Melbourne recording (another generic-car field), the 2.22.3 palette read as a
rainbow above the grid — average brightness 158 against the fourteen team colours' 144, and
consecutive car indices took adjacent hues, so an unidentified field drawn in order looked like a
spectrum rather than twenty-two separate cars. FieldColors.Palette is now darker and less
saturated (HSL 36 %/50 % and 36 %/42 %, average brightness 117, dimmest entry still 80 so nothing
disappears into a panel) and walks its eleven-hue wheel in coprime steps of nine across the
twenty-two entries, so consecutive seats are at least 147° apart in hue and never the palette's
closest pair (49.6 redmean apart, down from 73 — the trade for pulling every entry further from the
team and semantic colours that carry meaning, 46 → 56 at the closest approach). Five entries were
then nudged lighter for numeral contrast (worst-case swatch/numeral contrast ratio 2.70 → 3.52):
#AD5252 #459268 #A552AD #769245 #5262AD #925A45 #56B69B #924584 #76B254 #4C4592 #BB8F59 #459292 #AD5284 #4C9245 #7352AD #928445 #5DA9C5 #92455A #59BD6B #764592 #A5AD52 #456892.
2.24.13
Fixed
Sound Commands through the Steam cable sounded slow, deep and crackly — the game could not
understand them. Two causes, both on the cable's microphone side and both now handled by the
plugin. Speakers (Steam Streaming Microphone) runs at 48 kHz stereo and Microphone (Steam
Streaming Microphone) at 44.1 kHz mono, and Steam's driver copies frames from one to the other
without converting either: a 1 kHz tone played the ordinary (shared-mode) way came out at 460 Hz
with every second sample belonging to the other channel, i.e. every phrase at 46 % speed, an
octave down. The phrases are now played into the Steam pair in exclusive mode at exactly the
microphone side's rate, which comes out at 999.9 Hz for 1000 (2.000 s stays 1.998 s, no
glitches). Separately, the microphone side's Windows Input volume of 100 % is +30 dB on this
device — a 0.5 tone came out at 15.7, clipped into crackle — so every phrase is now played as many
dB quieter as the cable's microphone is boosted (and never louder than the clip has headroom
for). Nothing needs changing in Windows. The headset ("Also play on") path was never affected,
which is why it sounded fine there.
Test now tests what the game hears. A row's Test button used to run the clip itself
through the recognizer, so it passed while the cable was turning the phrase into a growl. With a
cable selected under Play into, Test now plays the phrase exactly as Play does, records what
comes out of the cable's microphone side, and recognises that — reporting the peak level it
arrived at, with "clipping" when it hit full scale. On this PC: box this lap recognised at
100 % through the cable at 78 % peak.
Changed
The Play into verdict on the Sound Commands tab now also states the cable's microphone-side
format, whether the exclusive route is in use, and any Input-volume boost being compensated. A
Play result ends with the route it took (exclusive 44100 Hz for Microphone (Steam Streaming Microphone), 30 dB under its +30 dB boost).
docs/CONFIGURATION.md: the Audio output row of the Sound Commands table had been sitting above
the page title since 2.24.4 while the 2.24.0 row stayed in the table; it is back in place and
brought up to date.
2.24.12
Added
Steering Wheel: the dials on every page. A configured rotary dial used to show only on the
Race page's foot (and the idle page). The Timing, Tyres and Systems pages now carry a small
dial chip for each configured dial — the accent bar (red left, blue right), the ring of
detents with the position inside, the dial's name over its current label — in the room each
page has: beside the lap counter and the position on Timing, beside the title and the gear box
on Systems (the session tag centres between them), and in the outer columns of the Tyres page
level with the gap between the corner rows, the corner tiles narrowing from 300 to 246 px to
make the columns. A new per-dial switch, Show the small dial chip on the Timing, Tyres and
Systems pages (ShowOnOtherPages, on), hides them; the Race tile keeps its own switch.
Nothing draws for an unconfigured dial, so a wheel without dials looks exactly as before.
2.24.11
Fixed
No more No overlay route exists for /favicon.ico in the debug log. Every Chromium host —
SimHub's own overlay windows as much as a browser preview — asks for /favicon.ico beside the
page it opens. The server had no such route, so each renderer produced a 404 and a rate-limited
debug line. /favicon.ico now serves a small MoverlayF1 tab icon (an SVG in the design
vocabulary's colours), and the log line is reserved for a path that really is unknown.
2.24.10
Changed
One Analysis tab. The Start Analysis, Time Trial Analysis and Pit Stop Analysis
tabs are now the three rows — Start, Time Trial, Pit Stop — of a single Analysis
page, with the same left-hand menu the Overlays and Dashboards pages use. Each tool is unchanged
inside: its viewer card, Recording card, filters, archive and buttons are exactly where they were.
Sound Commands moved up. The top menu now reads General, Overlays, Dashboards, Sound
Commands, Analysis, Diagnostics — six tabs instead of eight.
2.24.9
Added
Proximity Radar sees ahead less far than behind. You can see the car in front through the
windscreen; it is the ones beside and behind you that the radar is for. A new Forward reach
slider (30–100 % of the radar range, default 50 %) cuts the top of the range circle flat: a car
inside the circle but further ahead than that is not a contact in any presentation, while the
sides and the rear keep the full range. The Full spatial radar draws the cut shape — a flat edge
across the top of the dark well and the range rings — and the settings preview follows the
slider before you save. 100 % is the old full circle. The plugin applies the same cut in its
sampler, so the side rails, the HOLD / CLOSING calls and the HUD's compact rails agree with the
picture; /api/v1/radar-state carries the reach as Radar.ForwardRangeMeters.
Crosshair / circle opacity (10–100 %, default 100 %) dims the Minimal Centre guide on its
own: the crosshair or the concentric circles fade, the nearby cars and the own-car shape do not.
2.24.8
Fixed
Telemetry traces start at full width. The plugin keeps three seconds of pedal and ERS
history, so a freshly opened Inputs overlay, HUD input popup or Race Control Dashboard inputs
gadget used to show a trace that only spanned those three seconds and then grew — or, on the
dashboard, stretched — until the configured window had filled. The renderers now extend the
first window they receive backwards with its oldest sample held flat, so the time axis and the
trace's proportions are right from the first frame, and the same happens when the trace history
setting is raised while the dashboard is open.
2.24.7
Changed
One save bar on every page. The General and Sound Commands tabs now carry the same
always-visible bar as the Overlays and Dashboards pages, docked at the bottom of the tab: the
primary Save and apply (writes the whole configuration, whichever page you press it on) and
Reset to defaults (stages that page's defaults; nothing is written until you save), with the
shared status line beside them. The Save general settings and Save sound commands buttons at
the bottom of the cards are gone, so nothing needs scrolling to before it can be saved. A General
reset clears the driver name and the session-comparison card but keeps the installation id.
The grammar every settings page follows — page, bar, reset scope, cards, verdicts, tables — is
written down in the design guide.
2.24.6
Added
The Audio output card judges itself. A summary line at the top says Ready in green — or
Not ready in amber with the field to fix — and each of the three fields carries its own
verdict under it: your own speakers picked as Play into ("the game cannot hear them"), a real
microphone as the Windows default ("the game will hear you, not the phrases"), the phrases going
into one cable while Windows hands the game another cable's microphone, or a monitor device
that is the cable itself. The verdicts follow the page as you change it, before you save.
2.24.5
Fixed
The microphone verdict wanted too much. Windows keeps two default microphones — the plain
default, which games and speech recognition record, and the default for communications, which
calling apps use. The card stayed amber while the cable was the plain default but the headset was
still the communications default, which is the normal state while playing. The verdict now
follows the plain default alone and mentions the communications role only as the thing to try if
the game turns out not to listen.
2.24.4
The tab's Audio output card only listed playback devices and left the reader to work out why. It
now says how the game hears the phrase and adds the two things that were missing.
Added
Also play on (what you hear). A second playback device — the headset — on which the same
phrase is played at the same time as it goes into the cable, so you hear what was said. Off by
default; measured: the cable's microphone side still receives the full phrase while the headset
plays it.
Windows default microphone now. The card shows the recording device the game will use, with a
green verdict when its name says it is a virtual cable's microphone (Steam Streaming Microphone,
CABLE Output, Voicemod) and an amber one when it is a real microphone — the game would then hear
you, not the phrases. Open Windows sound settings jumps to the page where the default is set.
Changed
The card's text spells out the mechanism in three steps: play into the cable's playback side,
make the cable's microphone the Windows default while you play, and leave the game itself alone
apart from the Talk key and the English audio language. The playback picker is now titled
Play into (what the game hears). The configuration guide
has the same steps.
2.24.3
Changed
A tighter Commands table. The action name and its phrase share one cell (the phrase as a
subline), which gives the binding, audio-file and result columns the width. The binding editor
had been wrapping its own label into three lines in the narrow column and making every row
that tall; it now carries a one-word label in a wider column, and the file box and buttons no
longer stretch to the row height.
2.24.2
Two things the first hour with the Sound Commands tab inside SimHub showed.
Fixed
Test said "Class not registered". SimHub is a 32-bit program and the game installs only the
64-bit speech runtime, so the recognizer could never load inside SimHub — the suite, which runs
64-bit, had not noticed. From a 32-bit host the test now runs in Windows' own 64-bit PowerShell
and reports the same sentence; it takes about a second. Measured from an x86 process: "set soft
tyres" recognised at 55 %, as before.
Added
Bind a button on the same page. Every command row has an Input cell — SimHub's own
binding editor, the same one the overlay tabs use for their Toggle actions — so a wheel button
or key is assigned where the phrase is, without a trip to Controls and events. The
SaySetRecommendedTyre action has a row of its own at the bottom of the table.
2.24.1
Two fixes to the Steering Wheel dashboard's rotary dials.
Fixed
The dials no longer forget where they are. A wheel plugin only learns a dial's position when
the dial moves, so after a SimHub or plugin restart the Ascher Racing property reads 0 — the
wrapped top detent — until the first click, and both tiles showed 12 whatever the dials said.
The plugin now remembers the last detent of each dial in
PluginsData\MoverlayF1\dial-positions.json and shows it after a restart until the property is
seen to change; from that first click on, the property is the truth again and every new detent
is saved. The memory is keyed on the property name, so pointing a dial at another property drops
it, and a saved detent beyond the configured count is ignored. What this cannot know: a dial
turned while SimHub was closed shows its old detent until its first click. The state JSON and the
SteeringWheel.Dial1.Position / Dial2.Position properties carry the remembered detent; the
state marks it Remembered: true until the property has confirmed it.
The detent ring goes all the way round. The ring of dots on the dial tiles and in the
rotary popup covered 270° with an empty bottom quarter. It is now a full circle laid out like the
dial face itself — detent 12 at twelve o'clock, detent 3 at three o'clock — the same layout the
settings page's label editor already used.
2.24.0
F1 23, 24 and 25 let you talk to the race engineer: tap the Talk key, say "box this lap" or "set
soft tyres", and the game does it. None of that can be bound to a wheel button inside the game. This
release gives every phrase the game understands a SimHub action, so a button on the wheel can ask
for a pit stop, change the next compound, adjust the wing or tell the engineer to be quiet.
Added — the Sound Commands tab and the Say actions
One action per phrase, 37 in all.SayBoxThisLap, SaySetSoftTyres, SayWeatherReport,
SayEngineerQuiet and every other phrase of the game's own grammar file
(audio\2025\speech_recognition.xml), grouped on the new Sound Commands settings tab as
information, tyres, wing, engineer, practice-and-qualifying and strategy-reply commands. Each
taps the game's Talk key, waits for the radio to open and plays the phrase into the
playback device you choose. Bind them under Controls and events like a Toggle… action.
SaySetRecommendedTyre. Speaks whatever compound the tyre-recommendation engine currently
ranks best — set medium tyres, set intermediates — and stays silent when there is no
recommendation, so a wrong compound can never be ordered by a button.
Windows speaks the phrases, or your own files do. Every command is synthesised by an installed
Windows voice (an en-GB voice by default: the game's recognizer understood every test phrase from
Microsoft Hazel and misheard one from the en-US Zira), and any command can be pointed at an MP3
or WAV instead, absolute or by name inside a shared folder.
Play and Test without the game.Play sends a phrase to the playback device with the values
on the page, before you save. Test runs it through the same Microsoft Speech Platform
recognizer the game ships with, with the game's own phrase list as the grammar, and reports what
it heard and how sure it was; the game accepts 40 % and up. Two of the maintainer's own MP3s said
"set intermediate tyres" and "set wet tyres", which the game does not know — Test is what catches
that.
The game side is a setting, because it cannot be read. The game keeps custom bindings inside
its encrypted save, so the tab asks for the Talk key (T by default, the game's own default) and
whether to tap it or hold it, plus the delay before speaking and the tap length.
A button on the desktop types nothing. The key goes to the foreground window, so by default
nothing is sent unless that window belongs to an F1 game.
What you need once
The game has no microphone picker — it records Windows' default recording device — so the phrase
has to arrive on a virtual microphone: pick the playback side of a virtual audio cable on the tab
and make its recording side the default microphone while you play. The Steam Streaming
Microphone pair Steam installs and VB-CABLE both work; the plugin depends on no third-party
product and never changes your default device itself. The details, and what a plain cable does to
the game's own voice chat, are in the configuration guide.
Evidence
Everything below the game window was measured — the cables, the synthesised phrases through the
game's recognizer, and the whole plugin playback path onto the virtual microphone — and the first
live playback caught a real defect (silence reported as success) that the suite now pins. No
session with the game running has been driven yet; the validation report
lists exactly what that leaves open.
2.23.0
The F1 titles do not all speak the same language. Each game sends the year of the wire format you
picked in its UDP menu, and the meaning of a team id, a session type and a game mode moves between
those years; each game mode hands you a different subset of the data; and each car class can do
different things with it. This release reads all three — the packet format, the session mode and
the car class — and keeps one table per format instead of one flat guess. The whole picture is
written down in the telemetry matrix, with every fact marked as
official, measured here, community-sourced or unknown.
Added — the packet format is read, and every table is keyed on it
The plugin knows which of the four formats it is being sent. The game's own m_packetFormat decides, then the packet year, then the reader type, and only last the name SimHub gives the game — which is not reliable, because the 2026 Season Pack still calls itself F1 25. Every table below is looked up per format, so leaving the UDP Format selector on an older year no longer quietly changes what the overlays mean — including the car-class tables, which used to read the game's name while everything else read the packets. In a lobby or a menu, before any lap data has arrived, the session packet answers instead of the reader type.
F1 World is not offered on F1 23. The class arrived with F1 24, and on the older format an ordinary Grand Prix uses the same game-mode number an event does — so a Konnersport career or story car driven in a plain F1 23 Grand Prix was labelled an F1 World car. The words no longer claim a mode that game does not have.
An F1 23 race is a race again. F1 24 renumbered the session types: what F1 23 calls Race 1, 2 and 3 is Sprint Shootout 1, 2 and 3 from F1 24 on, and Time Trial moved from 13 to 18. Read with the newer numbering, every F1 23 race looked like a qualifying session — which silently switched off pit-stop recording, the Safety Car Helper, Tyre Choice, the Pit Window and the Start Helper for that whole game, and let lap recording run in races it should not. Each format now uses its own numbering.
Team names and colours per format. Team id 6 is Alpha Tauri on F1 23 and RB from F1 24; id 9 is Alfa Romeo and then Sauber. The 2026 grid — Audi and Cadillac included — the F2 grids of 2021 through 2026, the 2020 and 2022 liveries, the 2023 road and safety cars, the two APXGP model years and the Konnersport liveries all have entries of their own, on the formats that actually have them.
More cars get named instead of guessed at. An F1 23 road, safety or Supercars car, an F2 2021 car and a 2020 or 2022 livery are recorded as what they are rather than being filed as that season's Formula 1 car, so they keep their own folder, retention pool and personal best. The F1 23 road cars and the Supercars mode are one class, so the same car cannot change folders depending on which packet has arrived. Alpha Tauri, Alfa Romeo, Racing Point and Renault get their own colours back instead of the unknown-team grey, and a livery the game already names — including a My Team car you designed yourself — keeps its own name, so a team colour you saved for it keeps applying.
Tyre compounds cannot be confused between classes any more. F2's visual compounds 19-22 are the same numbers as Formula 1's actual C2, C1, C0 and C6, and one shared table had to be wrong about one of them. The compound ladder is now chosen by the car's class and the packet format together, and C6 is only recognised on the formats that document it.
Thunderstorm has a name. Fully dynamic weather can report a sixth weather value that no specification lists; it now reads "Thunderstorm" instead of falling off the end of the table.
Added — the session mode is read: online, spectator, splitscreen and restricted telemetry
A withheld value is a dash, never a zero. Every driver in an online lobby chooses whether to publish their telemetry, and "Restricted" is the game's own default. A restricted opponent's tyres, wear, temperatures, ERS, speed, DRS, damage, fuel, brake bias and engine power arrive as zeros, which used to be drawn as real readings — a car apparently sitting on 0 % wear with a flat battery. They are now published as nothing at all and every display prints an em dash for them. The overlays also know that the whole session has such cars in it, so they can say so once instead of leaving you to guess row by row.
Only a lobby that really holds a restricted car says so. The check counts the cars the session says are active, not every slot in the array: an online lobby that is not completely full leaves the rest of its twenty-two seats zeroed, and a zeroed seat reads exactly like a human who is withholding everything. Without that bound every under-full lobby would have explained em dashes that are not there.
Spectating shows the car you are watching — and only when you really are watching. When the game hands the plugin no car of its own, the spectated car becomes "your" car for every display, the overlays and the timing tower, relative and track map together. The game also raises its spectating flag for the post-race camera at the end of every online race while still naming your own car; that never moves anything, so the Start Helper, the Pit Stop Helper, Delta vs PB, the HUD and both recorders stay on your car for the whole race.
A splitscreen second player can take the overlays over. The game reports player two's car separately and the plugin never read it, so P2 saw P1's car on every overlay. Setting SecondaryPlayer in the General section of config.json now follows your car instead. It is deliberately config-only: nobody can reach the SimHub window from the second seat, and splitscreen has never been recorded here to test a switch against.
A build reporting F1 26 would have gone completely dark. The supported-game check knew F12023 through F12025 and had no 2026 branch, so a game calling itself F12026 would have made every overlay blank. It was invisible only because the 2026 Season Pack still reports itself as F1 25.
Changed — cards that know the car class and the game mode
Tyre compounds are named by the car's own ladder. F2's tyres were printed with Formula 1's C-numbers because both fields share one table: the F2 car's actual compound 12 read as "C4". F2 now reads SS/S/M/H/W, the classic cars read their own two compounds, and the F1 C-numbers are only used on formats that document them — C6 from F1 25 on.
The Start Helper stops inventing a tyre verdict. On a car whose compounds the carcass-window table does not describe — F2, the classic cars — it now shows no tyre window at all instead of a cold/hot verdict borrowed from a Pirelli table, and the shift prompt's top gear follows the car's own gearbox. The Tyre Prep card says the same thing the same way: it draws the four temperatures it has and says it has no window for them, where it used to print "no temperature data" directly under four live readings.
F2 keeps its DRS pill. Reading back every recording there is showed the F2 car's DRS opening and closing after all; the earlier "no DRS on F2" came from a Time Trial, where no zone arms for anybody. Only the classic cars have no pill now. F2 still loses the ERS disc, which really is empty in every frame.
The shift prompt no longer asks for a gear that does not exist. The game's gear-count field turns out to be one more than the gears the car has — nine on every Formula 1 car, seven on F2 — so the prompt could fire in top gear. It now stops one gear earlier, and the gear readouts on the HUD and the wheel clamp to the real top gear.
An unknown race-control code is written to the log, once per code, instead of only being counted where nobody could see it.
A tyre allocation the game sends without its visual compounds still names the tyres. When only the Pirelli construction numbers arrive, the softest construction in the allocation is this weekend's soft, the hardest is the hard and the rest are the medium — ranked correctly, so a C6 reads as the soft it is and not as the hardest tyre in the box.
Race Control says "No race-control messages" again after a session change. It is a per-session fact, and an always-on dashboard that saw one message in the first race kept quiet about it for the rest of the evening.
Weather can be a thunderstorm. Fully dynamic weather can report a sixth value that no specification lists. It used to be clamped away and read as "no weather"; the Weather card now names and draws it.
Race Control settles instead of waiting. A race that has genuinely sent no message — an F1 World event sends none at all — used to leave the ticker waiting for ever. It now says "No race-control messages", while still telling an unreachable plugin apart from a stale feed. The 2026 pack's new overtake and partial-mode messages are shown if they arrive and never assumed, a code no specification lists is logged once instead of throwing, and the penalty and infringement wording now covers all four game years, whose tables are identical.
A collision message carries its severity on the 2026 pack, where the game sends one.
Changed — documentation and version
The telemetry matrix is part of the documentation.docs/TELEMETRY-MATRIX.md records, per packet format, what the four F1 games send; per game mode, which groups of telemetry are trustworthy, partial, zeroed or absent; and per car class, what the car can do — with the recording or the specification behind each line, and a list of the questions a five-minute recording would still settle.
A matrix-driven test suite.tests/FormatMatrixTests.cs builds one synthetic session per packet format × game mode × car class and asserts the format, the session kind, the car class and its wording, the team name, the capabilities, the compound letters and the degradation the matrix promises, so a table and the document cannot drift apart. It also pins the 37 distinct session states found by reading every replay on the author's machine, so a table edit cannot quietly change what one of those recordings means.
The release was signed off against every recording there is. All 42 SimHub replays on the author's machine were read back offline and pushed through the new resolvers: 72 distinct session states, every one of them resolving to a known format, session kind, session type, game mode, rule set, formula, team and car class, with no exception and no fallback. It checks the tables, not the cards: no overlay and no reader was run over a replay frame for it. Three recordings had never been opened before — the only F1 25 base-game file, which turned out to be the one feed here that is not the 2026 format; the F2 2024 car; and a full multiplayer weekend.
2.22.3
Added
Every car in an unidentified field gets its own colour. In an F1 World event all twenty cars carry the same generic team, so the timing tower, the Track Map and the Position Circle drew twenty identical grey dots and there was no way to tell anyone apart. A car whose team the plugin cannot name now takes a colour from a fixed 22-entry palette, chosen by the seat it holds, so it keeps that colour for as long as it keeps its seat and a full grid has no two cars alike (a 23rd and 24th car would share with the first two). A team the plugin does know, and any colour you set yourself under Team colours, still wins. Your own car is coloured too: only your leaderboard row has a colour of its own, so leaving your car out left exactly one grey dot on the map and it was yours — the white border and the bigger marker are what say "you".
Changed
F1 World is a car class of its own. A race in an F1 World event in the generic car is recorded as an F1 World car instead of being filed as "F1 Generic". The team name is untouched and still names the car in the pages' Car filter. Laps, pit stops and starts already recorded under the old name keep their folders, their retention pools and their personal bests: nothing is moved or rewritten, and both names stay selectable. If the event puts you in the Konnersport livery instead, the recording stays with your My Team car — that is the same livery a My Team career uses, and a career car must not lose its folder, its retention pool and its personal best because the game happened to report a one-off session. In an event the page simply says "F1 World / My Team car" where it would otherwise say "My Team".
The DRS pill is there from the first frame. On any modern Formula 1 car the pill now exists as soon as the session starts, greyed until the game says otherwise, rather than waiting for the first packet that mentions DRS — a car sitting on the grid reports none. Only a car that genuinely has no DRS (F2, the classic cars) or one running the 2026 active-aero regulations hides it.
The DRS pill turns amber on the countdown, not only on the flag. F1 World cars report "DRS allowed" as 0 for an entire race even while DRS is actually deployed, so the amber "approaching" state could never appear. The HUD and the Steering Wheel now treat either the flag or a live activation distance as the approach, which is the countdown that works on every car.
The Pit Window card no longer needs the game's own window. An F1 World race sends no ideal or latest pit lap at all, so the card fell back on the strategy engine's own prediction — which it already computes from the tyre model and never from those two fields — but could still be hidden before your compound resolved. It is now shown whenever there is a predicted window.
A modern car with no tyre-set data says so. Tyre Delta used to sit on "Waiting for tyre data" for a whole session when the game never filled the tyre-set packet. After ten seconds it now prints one line — "No tyre-set data for this car." — and leaves Tyre Life and the Pit Window, which work from your fitted compound and wear, alone.
Fixed — the first real pit stops and race starts you recorded
Everything below came out of reading your own two recorded stops and five starts against the replays they were driven in. The lane, stop, entry, exit, limiter and release times and the reaction, 0-100 and peak-slip numbers were all correct to the millisecond and are untouched.
The time a stop actually cost you was measured against the wrong lap. The "vs a normal lap" figure compared the out-lap with the in-lap, because the in-lap itself was being used as the best clean lap — so a Jeddah stop that really cost about 31 seconds was reported as 14.9. The reference is now the best clean racing lap of the whole session: every lap that was not neutralized, not invalidated, not driven through the pit lane and not the standing start. A stop waits one extra lap for it rather than printing a number it cannot stand behind, and the row on the page is tagged SESSION, so the lap it names is the one you can see in the game.
A fresh set of the same compound counts as a tyre change. The page said "NO TYRE CHANGE" for a stop that fitted a brand-new set of the same tyre (age 1 → 0, wear 5 % → 0 %). Compound or a set reset now counts, the age before and after the stop is recorded, and the card reads "NEW SOFT SET".
The expected pit loss says where it came from. A stop under a virtual safety car printed "13.0s TRACKDEFAULT" on a 20-second track with nothing to explain the difference. The stop now keeps the green-flag prediction, the neutralization and the pit-limit scale factor, and the page prints "13.0s · VSC · 20.0s GREEN".
"Settle" could never be measured, so it is now the roll-in. The game starts its stop timer about 0.12 s before the car is actually stationary, which made the old metric structurally empty. The row is now ROLL-IN: how much of the game's own stop timer you spent still rolling into the box.
The stationary part of a stop is one block again. It was recomputed from the speed of every sample, so a stop broke into seven flickering blocks; it now latches and needs 0.3 s of real movement to end.
No negative speeds anywhere. The pit trace dipped below zero at the stop; the recorded speed is clamped at zero in the pit and lap channels, the pit-lane speed chart starts at zero, the red over-the-limit band is drawn only where you were actually over it, and the entry/exit chart shows the two speeds instead of stubs under a "-0.0" axis.
Wheelspin is not every launch any more. The threshold was half the slip any clutch drop produces, so all five of your starts — including the best one — were marked as wheelspin. The default is now 22 m/s, which separates them; if you had set your own value it is kept. A configuration still holding the old 10 is moved to 22 once, on the first start after this upgrade — after that the whole 1–40 range, 10 included, is yours to set and is never rewritten.
A second stop within a lap or two of the first is not lost. Only one stop could be waiting for its out-lap at a time, so a stacked double-stop under a safety car, or an early puncture followed by a strategy stop, silently discarded the first one: no file, no row on the page, no warning. The first stop is now written out — with whatever laps it has — before the second takes its place.
The pit-lane speed chart rescales when you zoom into it. The axis was fixed at zero to the fastest point of the whole lane, so zooming into the stationary part of the stop, which is the reason to zoom at all, drew a flat line along the bottom. The floor stays at zero and the top follows what you are looking at.
A shift at the limiter is not a short shift. Upshifts at 12,997 and 13,119 rpm were labelled SHORT; a shift at or above 98 % of the car's maximum revs never is.
"COLD · 100 °C" made sense to nobody. The tyre status was captured at lights out and the temperature six seconds later. Both are now read at the same instant (71 °C and Cold, in that start).
0-200 km/h is recorded again. The start record used to close when you reached fifth gear, a quarter of a second before 200 km/h arrived; it now waits for the speed, up to ten seconds after lights out.
throttleAtLightsOut is rounded like every other percentage.
2.22.2
Added
The plugin now knows what kind of car you are driving, and the displays follow. F2, the classic grids and the generic cars are not hybrid Formula 1 cars, but MoverlayF1 drew them as if they were: an ERS disc that could only ever read 0 %, a DRS pill that could only ever stay grey, and a tyre-strategy model tuned on F1 compounds. Every snapshot now carries a small set of car capabilities read from the game's own data — whether the car has ERS, DRS and 2026 active aero, how many gears and what rev range it has, its pit-lane speed limit, and whether the F1 tyre ladder applies — and the overlays use them.
Changed
The HUD drops what the car does not have. Driving a car without ERS hides the ERS disc and the two ERS tiles on the Steering Wheel dashboard rather than drawing an empty battery, a car without DRS hides the DRS pill, and the 2026 active-aero pill appears only on a car running the 2026 regulations. The row gives the space back instead of leaving a hole. The ERS disc also stops assuming 4 MJ of store and 2 MJ of harvest for every car: it reads the car's own store and harvest limit from the game and only falls back to 4 MJ on a modern F1 car. (The F1 2026 Mercedes reports a 7 MJ harvest limit, so the old 2 MJ constant was wrong even there.)
Tyre Delta, Tyre Life, Pit Window and the tyre-strategy advice hide themselves on a car the model was never built for. The compound ladder and the wear model are tuned for modern Formula 1 tyres, and the F2 car's tyre-set packet is empty, so instead of printing a confident number from nothing those cards now show a single line: "Tyre strategy is modelled for modern F1 cars." Only F2 and the classic cars lose them: the APXGP car, the F1 Generic car and the F1 World, Esports, Elimination and beta modes are current Formula 1 machinery and keep every card, and so does any car the game has not named yet. If a car the plugin demoted turns out to report a real tyre life anyway, the cards come back for the rest of the session. A modelled tyre life is also withheld, on any car, until the game actually reports a life span.
The expected pit loss adapts to the pit-lane limit. The built-in per-track table was measured with an 80 km/h limit; where the game reports a different limit — 60 km/h for the F2 car at Suzuka — the built-in value is scaled accordingly and still tagged EST. A pit loss you typed in yourself is never scaled, per track or as the global fallback: it is a measurement, not a table entry. A loss the plugin has measured for you stays authoritative as before.
Game names are printed the way you write them. The analysis pages, their filters and the live header now read F1 25 instead of the internal F12025.
Time-only references are filtered and capped. The list the analysis pages offer now carries each reference's car and its source, and at most eight per source are returned instead of everything on file.
Recorded laps and pit stops keep the precision the game sends. The world positions in a recorded lap were written as whole metres, which put a 60 Hz trace on a one-metre grid: in a slow corner half the samples landed on the same point and the map line zig-zagged in 45-degree steps down a straight. Positions are now written to the centimetre, the pedals to a tenth of a percent, the g-forces to a thousandth and the distance to the centimetre — every channel at least as fine as the packet it came from. A recorded lap grows by roughly a fifth (about 0.1 MB on a 0.5 MB lap). Laps recorded before this release are unchanged and still draw as they did.
The analysis pages are bigger to read. All three pages — Time Trial, Pit Stop and Start Analysis — were drawn on a type scale that was too small on a 1920 screen: every label, legend, table cell, axis tick, launch tile and header now comes off one raised scale, and the rows, buttons, tags and read-out columns grew with it. The layouts are unchanged at 1920 and at 1280.
The track map zooms and pans. Roll the wheel over the Time Trial map to zoom about the pointer, drag to pan, and double-click or press FIT to see the whole circuit again. The driven lines, sector ticks, pit box and the hover dot follow the zoom and keep the size they were drawn at, so a zoomed corner shows the line rather than a thicker smear.
A sector bar under the map.LAP, S1, S2, S3 — one button per sector the data actually has. Selecting a sector zooms the map onto that stretch of track and every distance chart — the line chart, the time delta and all the channel charts — to the same range, because they share one zoom. Selecting it again, LAP, RESET ZOOM, 0 or zooming a chart yourself returns control; the keys 1–3 select a sector, and lap visibility moved to Shift+1–4. Add ?sector=2 to the address to open on one.
The analysis pages pick a scope before anything else. Game, then track, then car type, at the top of the left column on all three pages and as a chip in the header. They are required, they have no ALL, and each one offers only what the choice above it has recordings for. One track map, one distance axis and one set of sector boundaries cannot describe two circuits, and until now the lap list happily let a Suzuka lap and a Spa lap be compared on top of each other; nothing outside the scope can now be listed or selected. Car, session, valid laps only, serviced only, safety car, surface and verdict stay as optional filters underneath, counted inside the scope so a car that never raced on that track is not offered. Changing a scope select starts a fresh comparison from the newest recording in it; the scope is remembered for as long as the window stays open, and a new window starts from whatever session is running.
The racing line on the map is drawn as a line, not a staircase. Laps recorded before this release stored positions to the whole metre and the feed holds a position when a packet is late, so a 300 km/h straight was a 1 m lattice that looked kinked as soon as the map was zoomed — on the Spa laps the heading swung a median of 27 degrees along the dead-straight Kemmel. Held samples are now dropped and the rest averaged over three points before the line is drawn, so an old lap draws as smoothly as a new one (which is recorded to the centimetre). Nothing else changes: every delta, every read-out and the hover cursor still come from the samples themselves.
Time-only references are yours to ask for. An F2 lap at Suzuka came up behind eight blue STORED lines from Formula 1 laps it had nothing to do with. The Time Trial page now has a REFS switch in its header and a Time-only references card: one tickable row per profile with its source, lap time and car, at most four drawn at once, and only profiles recorded in the same car as your reference lap. A Time Trial lap still starts with its own ghost ticked, and nothing else is ever on unless you tick it. Lap profiles carry no car type, so for a car that is not a modern F1 car the card says so instead of offering a comparison that would mean nothing.
Fixed
The HUD stayed on screen in the Time Trial garage. This is the one that was reported, and the cause was that the plugin could not see the garage at all there. "In the garage" is read from your car's own entry in the game's lap data, but the plugin looked that entry up by race number — and in Time Trial the game gives your car race number 255 while SimHub reports a number of its own, so the two never matched and In garage stayed false for the whole session. The same was true in any solo session where the plugin builds your car from SimHub's normalized data alone. Your car's entry is now found by the index the game itself marks as the player, so Hide in the garage finally hides in the garage — and the pit-lane and pit-box flags it carries are right there too.
Hide in the garage also covers the states where there is no car at all — the pause menu, a session's loading screen, the drive back into the box, a telemetry stall — but only once that session has had your car in it. With SimHub running and no game, nothing hides: that is when you place and colour the overlay windows. An overlay is never hidden once the game reports a car that is out of the garage.
A time delta that steps at the end of the lap is telling the truth. A Spa reference lap read flat against two comparison laps all the way round and then dropped 2.3 s in the last 100 m, which looked like a resampling bug. It was not: the reference car crawled at 27 km/h for five seconds in the final corner complex, and that single incident was the entire lap gap. The delta chart now marks where the reference lap itself slowed below about 35 km/h, with a tooltip naming the speed and the distance, so the step explains itself instead of looking like an error.
The Start Analysis page named the car twice. A start recorded without a team name fell back to its car type and then printed it a second time — "F1 2026 CAR · F1 2026 CAR" above the launch tiles. It is named once.
2.22.1
Added
A recording switch on every analysis tab. Each of the three analysis tabs now carries its own Recording card for its own recorder, so laps, pit stops and starts are switched on and off separately. Time Trial Analysis keeps Record laps and the sample rate, Pit Stop Analysis gains Record pit stops, and Start Analysis gains a new Record starts switch. Turning start recording off stops nothing you can see while you drive: the Start Helper and Start Report overlays still coach the launch exactly as before, the launch is simply not written to the journal. Every card shows what its store currently holds and how much of its capacity is used, and each has its own Save recording settings button. All three defaults are on.
A General tab, first in the settings window. Everything the plugin shares across more than one display now lives in one place instead of on an unrelated tab: the Driver display name and the read-only installation id (with a Copy installation id button), the session-comparison card that chooses who the timing panels compare against, a read-only view of the plugin's local server address and port, and a read-only Data table with the folder, count and size of the lap, pit-stop, start and export stores.
Laps and pit stops know which car you drove. The F1 titles let you drive very different cars under the same team name — the F1 2026 and the F1 2025 Mercedes, F2, My Team, the classic grids — and MoverlayF1 was filing them all together, so three Suzuka Time Trial laps in the 2026 car and two in the 2025 car shared one list, one retention pool and one personal best. Every recorded lap and pit stop now carries a car type read from the game's own session and participant data — the F1 grids by model year, F2 by model year, My Team, the classic and generic cars and both APXGP model years — and it is a filter on both settings tabs and on both browser pages, a column in the stored file and a facet on the list routes. Car still means the team; car type means the car. Laps are kept, pruned and marked PB per car type, so a lap in the 2025 car can no longer evict or out-rank a lap in the 2026 car. The Pit Stop Analysis tab and page also gained the plain car filter they never had.
On the Time Trial page each row names its own car type when the filter is on ALL, the header names the reference lap's, and a comparison lap driven in a different car carries an outlined OTHER CAR tag on its row, its legend entry and its sector column. Comparing two cars is never blocked, only labelled. Both page headers now print the car type of the live session beside the team.
Changed
The MoverlayF1 settings window now has seven top-level tabs, with General first: General, Overlays, Dashboards, Start Analysis, Time Trial Analysis, Pit Stop Analysis, Diagnostics. Opening the settings page shows General.
Who to compare against and Sector clocks moved from the Ahead / Behind overlay tab to General. They were never that overlay's settings: they also drive the Driver Relative panel, the Track Position Circle centre and the Relative.* properties. The saved values are untouched.
Driver display name and Installation id moved from the Time Trial Recording card to General. An existing config.json is migrated on the first load and keeps its installation id — which is minted exactly once per installation — and its driver name; the file is rewritten in the new shape the next time you save.
A recorded lap is now stored under Laps\<game>\<track>\<car type>\<car>\. Laps recorded before this release are not moved, renamed or rewritten: they keep working, and list, open, export and delete exactly as they did — but they carry no car type, so they appear as Unknown car with a retention pool and a personal best of their own. The car of a lap whose stored data never said which car it was would be a guess. If you have the five Suzuka laps from 2026-09-16, delete them from the Time Trial Analysis tab and drive them again to have the two Mercedes separated. Pit-stop files and their identifiers did not change.
A recorded race start now names its car the same way as a lap and a stop, so the Start Analysis filter reads F1 2026 car rather than F1 2026. Your existing start-analysis.json is untouched, and records written by earlier releases share a filter entry with new ones instead of splitting into two.
Fixed
Selecting a lap or a stop on an analysis page returned "404". The pages build every detail address with the standard URL encoding, so a lap id's slashes arrive as %2F; the server did no percent decoding and answered 404 for a lap it was holding, leaving the Time Trial page without traces. Analysis query values are now decoded before they are validated, so the encoded and the plain form return the same bytes and the same validator. The id grammar still runs after decoding, so an encoded .. or \ is refused exactly as a plain one always was.
2.22.0
Added
Time Trial Analysis. Every lap you drive in Time Trial, Practice and Qualifying is now recorded channel by channel and kept on disk, and a new Time Trial Analysis tab in MoverlayF1 Settings lists that archive with filters for game, track, car, session and validity, sortable columns, and per-lap sectors, tyre, conditions and file size. Open in browser opens the full viewer on the plugin's own local server: the lap list and sector gap table, the track map, a line-distance chart and a time-delta chart against your chosen reference, and stacked speed, throttle/brake, gear, RPM, steering, g, ERS and tyre-temperature charts that share one distance axis and one cursor. Up to four laps are compared at once, each in its own colour, and your Time Trial ghost and personal-best references can be added as time-only delta lines.
Pit Stop Analysis. Every pit stop you make in a race is recorded from the approach to the exit, with the lane and stationary times, entry and exit speeds against the pit limit, how far before the line the limiter came on, any overspeed, the settle and release delays, the tyre change, penalties served, and the measured lap loss against the plugin's own expected loss. The new Pit Stop Analysis tab lists them; its browser page draws the trends across stops and the selected stop's pit-lane speed trace with the limiter line and the approach/lane/stationary/release/exit phases. The box overshoot is learned from your earlier stops at the same track and car, so it appears only after two of them and always carries an EST tag.
Recording settings. A Recording card on the Time Trial Analysis tab switches each recorder on or off and sets the sample rate: 60 Hz by default, or 30, 20, 10 or off. The rate decimates the plugin's existing 60 Hz input grid, so lower rates cost proportionally less disk and less time in the telemetry callback; Off returns before a single packet is read. A Driver display name and a read-only installation id are stamped into every recorded file so an exported lap stays attributable.
Start Analysis in the browser. The launch journal the Start Analysis tab has kept since 2.5.0 now has a page of its own at /analysis/starts, opened with the tab's new Open in browser button: filters for game, track, car, session, surface and verdict, a sortable start list, trends for reaction, 0–100 against 0–200, peak rear slip, launch rpm against its target band and clutch release, the verdict spread across the filtered starts, and the selected start's launch tiles, shift-by-shift table and coaching note. The tab also gained an Export button, which writes that start's JSON beside the exported laps and stops. Your existing start-analysis.json is untouched and keeps loading as before.
Export and a documented format. Each tab's Export button copies the selected recording's JSON to PluginsData\MoverlayF1\Exports\ and opens Explorer on it. The files are self-describing — every channel carries its unit, precision and kind — and the format is documented as version 1 in the analysis schema reference, including the forward-compatibility rules a future reader may rely on. Nothing is uploaded; the analysis pages are served on 127.0.0.1 like every other MoverlayF1 renderer.
Changed
The MoverlayF1 settings window now has six top-level tabs: the two analysis tabs sit between Start Analysis and Diagnostics.
The recorded archive prunes itself: per game, track and car MoverlayF1 keeps the 20 fastest valid laps plus the 10 most recent (invalid included), and the pit-stop store keeps the 500 newest stops. A 100-second lap is about 0.48 MB at 60 Hz and about 0.09 MB at 10 Hz; each tab shows what the archive currently occupies, and Delete and Clear all remove recordings from disk. See Lap and pit stop analysis.
Validation
The recorder was benchmarked before and after on the same tree. Recording at 60 Hz costs
0.552 µs and 152 bytes per sample on the telemetry callback — about 33 µs of CPU per second of
driving and roughly 0.9 MB of short-lived allocation per recorded lap — plus 1.05 µs per 10 Hz
snapshot for the slow row and the session context. With the sample rate set to Off the
recorder costs 0.001 µs and no allocation at all, because it returns before a packet is read.
The whole-snapshot Telemetry.Read is 0.184 ms before and 0.186 ms after: unchanged within
noise. A recorded lap file is about 478 KB for 100 seconds at 60 Hz, and writing it costs
22 ms — on a background worker, never on the telemetry thread, which is also where the learned
pit box is persisted. The complete suite passes 2,798 SDK/plugin assertions, plus
installer/update preservation and setup-package tests. Figures and their context are in the
validation report.
2.21.0
Fixed
Multiplayer identity and timing. Drivers who share a race number are now matched by their fresh participant name, so Mart and RemonV76 no longer steal each other's raw row. This restores allowed ERS, tyre temperatures, penalties, pit counts and lap history. Ambiguous identity stays blank rather than guessing. Practice and qualifying also reject the game's invalid minute-part sentinels instead of showing intervals such as +15190.90.
Qualifying push/prep detection. Lap changes now survive a skipped start/finish sample, a missing lap counter or LastLap, and brief flying/on-track status jitter. A lap following a confirmed push starts as prep while pace evidence can still identify consecutive push laps. Tyre Prep retains valid best-lap references through short packet gaps; temperatures remain nullable and are never fabricated.
Garage visibility. The raw driver status now fills the player's garage state when SimHub leaves it empty, so the HUD and Pit Stop Helper stay hidden in the garage as configured.
Safety Car delta and strategy. A missing game delta is identified as GAME DELTA UNAVAILABLE instead of an unexplained dash. A serviced stop is remembered from the public pit count or tyre-service evidence, clearing a stale BOX BOX; lane-only transit does not count. An immediate tyre call must cover the remaining laps, unless a priced extra stop is explicitly shown.
Race-control identity. FIA messages that only identify a vehicle slot are enriched from the fresh participant roster as initials plus car number; duplicate-number ambiguity remains CAR n instead of naming the wrong driver.
Added
Backmarker context. Lap status now changes at the physical on-track pass, not when only one car has crossed start/finish. Cars on another lap remain visible but are muted grey on the Track Map, Track Position Circle and Race Control dashboard's outer lap ring, with no lap text beside their names. The timing tower's leader page shows the broadcast-style +1 LAP or +n LAPS instead.
Validation
The 15 September Baku full-weekend replay confirms duplicate human car #2 rows, real ERS/temperature data for both drivers, RemonV76's 3-second penalty, a Safety Car stop, invalid 253/255 interval minute parts, and the physical Mart/RemonV76 lapping pass at frame 203833. The complete suite passes 2,609 SDK/plugin assertions, plus installer/update preservation and setup-package tests.
2.20.0
Added
Time Trial ghost tracing. With the game's ghost display on, the personal-best ghost (and the rival ghost when it is shown) drives its lap in the telemetry, and MoverlayF1 now traces that lap exactly as it records your own. A personal best you set before the plugin was installed, or on another day without it, is therefore an exact reference after one lap behind the ghost - and already during that lap wherever the ghost has been - instead of an EST estimate until you beat it. The traced lap is remembered with the track's recorded laps, so it stays exact after a restart and in later sessions, and a new personal best switches to the new ghost by itself. Each ghost is traced strictly from its own data set's car and checked against that set's sector and lap times before it counts; a ghost that stands still (display off) is ignored. On the Baku and Austria replays the traced reference reads within about 0.012-0.016 s of the game's own delta where the estimate had been 0.1-0.5 s off. Tip: enable the ghost display in the game's Time Trial settings.
Changed
Delta vs PB now runs on the same lap profile engine as the Time Trial references and the Steering Wheel's delta to best - one recorded lap, one delta everywhere - instead of its own packet-rate recorder. Its reference is still the fastest valid lap you completed this session in the current car and rules, and it still never estimates; three rules follow the shared engine now: a flashback or replay rewind keeps the reference and drops only the lap in progress, a lap through the pit lane is recorded like any other, and the current lap's own invalidation no longer blanks the number. DeltaPb.Source reads Profile instead of RecordedProfile, and the number updates ten times a second with the plugin's snapshot.
The Time Trial reference's DeltaSource gains Ghost (exact, from the ghost car's traced lap); DeltaEstimated is false for it, and the EST tag disappears with it.
2.19.1
Race Control's lap-position ring is slightly larger by default and now has an independent Lap circle size setting. Close driver initials share one radius and can overlap naturally, matching the central Track Map; the car ahead is painted on top, while the pit-rejoin leader points outward toward REJOIN P#.
Fresh installs and Reset defaults now use the maintainer's tuned overlay profile: quieter waiting states, the blue timing-panel palette, revised opacity, the concentric-circle proximity view and the updated Race Control layout. Weather, Tyre Delta, Tyre Life and Pit Window start visible; the HUD input popup starts closed; relative clocks remain automatic. Personal SimHub key bindings and hardware-specific steering-wheel dial properties are deliberately not packaged.
2.19.0
A performance-only release: no new overlay, no new setting, no changed property, JSON shape or dashboard identity, and nothing looks different on screen. The plugin, the telemetry readers, the overlay pages, the two dashboards and the settings page all do less repeated work per update.
Changed
The local server now answers an unchanged poll with a short "nothing changed" reply instead of resending the full data, and the overlay pages recognise that reply and skip re-reading and repainting a screen that already shows the right thing. On an unchanged Leaderboard poll this drops the reply from about 22 KB to 160 bytes.
Any overlay that SimHub backgrounds or hides (another screen brought to front, the window minimised or occluded) now backs off to the same one-request-a-second idle rate it already used when paused or unavailable, instead of continuing to poll at full speed, and returns to full speed the instant it is shown again. The worst case if a host ever misreports visibility is now "runs at the idle rate", not "stops".
The plugin's per-snapshot telemetry read is measurably cheaper: about 14% faster and 57% less memory per 22-car snapshot (0.221 ms/326 KB down to 0.190 ms/139 KB) from a smaller locked section in the proximity-radar sampler, field-reading shortcuts that no longer rebuild themselves on every call, a single pass to sort out which opponents are shown, and less throwaway work when a driver's inputs haven't moved between samples.
The readers behind lap history, the lap chart, the weather forecast, pit-loss estimates, qualifying-traffic gaps, tyre-choice candidates, track features and flag-sector state now reuse their previous answer when the packet data behind it hasn't moved, instead of recomputing it every snapshot; the weather forecast (about 89% cheaper) and the qualifying-traffic lookup (about 84% cheaper) see the largest wins, with the lap history, lap chart and pit-loss readers 25–75% cheaper too.
The full-screen Race Control dashboard now reuses its classification rows when the same cars are still on track instead of tearing every row down and rebuilding it on each position change, measures its own panel size only when the layout actually changes rather than on every update, and skips its redraw completely when nothing changed. The Race Control message ticker skips its own message-list work the same way.
The HUD's rolling throttle/brake/ERS trace is now drawn from one point per pixel column instead of one point per sample, which roughly halves the line it rebuilds three times every tick without losing the throttle ripple or a short brake stab.
Safety Car Helper, Start Helper, Start Report, Tyre Prep, Weather, Pit Window, Tyre Delta, Tyre Life, the Race Control ticker, Qualifying Traffic, Pit Stop Helper, Damage & Power Unit, Lap Chart, Track Map and Track Position Circle all now skip their repaint when the plugin reports nothing changed, and their fast poll also honours the overlay being hidden the same way the rest of the suite already does.
Start Helper's RPM/throttle bars and its needle, and Delta vs PB's centre bar, now animate through a GPU-friendly slide-and-stretch instead of resizing their shape on every frame, matching how Safety Car Helper's and Race Control's bars already move. Same speed, same easing, nothing looks different.
Leaderboard now builds its team-logo artwork only the first time a page actually needs to show one, and only re-measures its cached name widths when a setting that can actually change them — name size, name mode, the position column, or logos on/off — changes, instead of on every settings edit.
The plugin's Settings page is now built once per SimHub session and reopened instantly afterwards: reopening the page dropped from a roughly 470 ms rebuild to about 2 ms. The Steering Wheel dial ring's live-highlight timer now runs only while that tab is open instead of the whole time the settings page is, and editing one section (dragging a slider, ticking a box) republishes just that section's configuration instead of rebuilding every section, over ten times faster per edit (0.156 ms down to 0.011 ms).
Compatibility and validation
Every overlay, dashboard, setting, property, JSON shape and dashboard/screen identity is unchanged; existing configurations, custom renderer URLs and saved layouts carry over untouched.
This pass was verified with the automated suites, a headless-browser visual comparison against the previous release, and manual checks in the in-app browser; it has not yet been exercised inside a live SimHub/CEF host. In particular, whether SimHub's renderer reports a backgrounded overlay as hidden has not been confirmed live — a hidden overlay can now only slow down to its idle rate, never freeze, so a misreport is not expected to be visible, but this still wants a live check.
2.18.1
Changed
Race Control now defaults to larger shared UI, gadget and classification text, a larger circuit workspace and circular driver markers. Its native editor exposes bounded readability controls, dot or radial-line circular markers, a pit-rejoin cue and an 18-second visible telemetry trace window; changing that history does not raise telemetry polling.
Reworked Race Control around dense structural anchors: Overview now keeps the expanded classification and circuit view visible, Map focus gives the circuit most of the canvas, and Telemetry & strategy keeps its live traces prominent. Four configurable supplementary gadget zones remain on every page, but no longer create large empty areas.
The dashboard now embeds the exact MoverlayF1 Track Map renderer, including its saved circuit appearance and geometry, inside a true circular field-position ring. There is no separate Race Control circuit renderer to drift visually or repeat map work.
Expanded the classification with position change, tyre and age, average and clean-average pace, last/best laps, gap, interval, lap, stops, penalties and ERS, with responsive column priorities for narrower screens.
Added the full-width lower timing ribbon from the race-control reference: position, race time, lap, last/best/estimated lap, delta and sectors remain visible on the main page.
Rebuilt Dashboards → Race Control as a visual configurator with selectable page, layout, map-side and header cards, a live page preview and thumbnail-backed A–D gadget choices. Header placement is now top or bottom in normal document flow; older centre selections migrate to top instead of overlapping gadgets.
Refined every native overlay and dashboard editor with a smaller preview that remains pinned on the right even in a narrow SimHub window, leaving the settings form its full height. Clicking the preview or Open large preview opens one resizable live view; the compact renderer pauses until it closes, so there is never a second WebView or telemetry loop. Packaged artwork remains the fallback.
Fixed the enlarged Race Control preview cropping its lower timing ribbon. The preview now preserves the complete canvas even when window chrome makes the live viewport slightly shorter than 16:9, and the Lap Timing delta plus every selectable gadget reflow into their smallest Layout B and Map-rail zones.
Native settings no longer need a left/right scrollbar: visual cards reflow vertically at narrow widths while the compact preview stays on the right.
Fixed the Proximity Radar live preview so unsaved Default presentation, Centre marker and range changes appear immediately. The concentric-centre option is larger and uses finer rings, closer to the Full spatial radar guides.
Proximity Radar now hard-hides every presentation during active Start Helper coaching, Pit Stop Helper and Safety Car states, and while the player is in pit, pit lane or garage; ordinary contact fade behavior is restored afterward.
Made 100 px the default Crosshair / Circles guide size and added a separate 60–220% Own-car icon size. Enlarging the guide no longer enlarges the car inside it; explicit saved guide values remain intact and older configurations receive a neutral 100% own-car size.
Replaced the orange Race Control configurator selection gradient, borders, zone badges and thumbnail accents with MoverlayF1 red. Telemetry warning amber remains semantic and unchanged.
Race Control's outer lap ring now defaults to compact team-colour dots with white driver initials in a reserved outside gutter. Initials, race positions or no labels can be selected, close labels are staggered, dot/radial-line size has a wider 60–200% range, and the pit-rejoin cue also sits outside the ring.
Performance and compatibility
The dashboard still uses the shared immutable snapshot and three page-aware serialization caches. The outer circle uses the already-projected compact driver field, the Track Map keeps its own bounded cached route, hidden maps are removed, input history is requested only when shown, and unchanged DOM values are retained. Gadget density is recalculated only when the page layout or viewport size changes, not in the telemetry render loop.
Package, dashboard and screen identities stay stable for update installs. The SimHub item remains MoverlayF1 - Race Control Dashboard, MoverlayF1's own settings tab remains Race Control, and the compact MoverlayF1 - Race Control ticker is unchanged.
2.18.0
Added
MoverlayF1 - Race Control Dashboard, a dedicated fourth-screen view packaged separately from the existing message ticker. One responsive renderer supports a 1920 × 1080 Standard layout and a 2580 × 1080 Ultrawide layout.
Three focused pages: Overview, Map focus and Telemetry & strategy (route keys overview, map and telemetry). Use all three or keep a two-page setup. Each page offers Layout A/B templates and configurable named gadget zones; the zones are stable slots rather than a freeform drag-and-drop canvas.
Native dashboard settings and the RaceControlDashboardNextPage, RaceControlDashboardPreviousPage and RaceControlDashboardHomePage actions. Advanced layouts can pin /racecontroldashboard?page=overview|map|telemetry and override one instance with layout, mapside or variant query parameters.
Performance and compatibility
The dashboard reuses the plugin's immutable telemetry snapshot, participant lookups, incremental input feed and existing map geometry. Compact page-aware projections are cached independently so two pinned screens do not invalidate each other; the 60 Hz input history is requested only while its gadget is visible, and no second UDP listener or duplicate telemetry reader/calculation path was added.
The existing 72 px MoverlayF1 - Race Control ticker, its route, settings and identity are unchanged. The full-screen dashboard is a separate package, with Standard and Ultrawide handled by the same renderer and a stable dashboard identity.
Automated, browser and packaging results for 2.18.0 are recorded in the validation report; live SimHub installation remains a separate validation step.
2.17.3
Changed
Proximity Radar Minimal Centre can use a crosshair, two concentric circles, the own-car shape, or no centre marker. The existing centre-marker size control applies to all three drawn styles, ?marker=crosshair|circles|car|none can override one custom URL, and the older optional own-car switch remains additive so saved 2.17.2 configurations keep their appearance.
Delta vs PB is slimmer again at 820 × 120. The signed 42 px value and wider centre-zero bar keep the one-glance hierarchy, while the 26 px trace remains optional and off by default.
The telemetry feeds, dashboard IDs, screen IDs, routes, actions and property names are unchanged. Updates continue to preserve existing saved layouts, custom URLs, bindings and configuration bytes; the new Delta dimensions apply only to fresh placements/packages.
Compatibility and validation
Radar and Delta telemetry semantics and game support are unchanged. Automated and visual results are recorded in the validation report; no live SimHub installation was changed.
2.17.2
Changed
Proximity Radar keeps its 480 × 480 package identity and now has Full Radar, Minimal Centre and Blindspot presentations. Minimal Centre is the new default for direct-centre placement: only the crosshair and heading-relative car shapes appear, the complete group fades in when a fresh car enters range and fades out after the last one leaves, and stale/paused/unsupported input hides it immediately rather than producing a false clear. Range, clear delay, fade time, car size, movement smoothing, crosshair size, optional player marker and the Full Radar's header/rings/side warnings/call/pit layers are independently configurable. Existing saved radar and blindspot choices remain valid.
Delta vs PB is now a wider, lower 720 × 152 display. The signed measured value and centre-zero bar remain the heroes; the trace is a slim optional foot strip and is off by default. Explicitly saved trace choices and scale settings are preserved.
Damage & Power Unit is now a narrow portrait 480 × 640 display. Summary uses two columns by three rows; the detailed damage schematic and PU page were reflowed vertically without changing telemetry meaning or page routes.
Dashboard IDs, screen IDs, routes, visibility actions/properties and installer preservation behavior are unchanged. Existing saved layouts, custom URLs, bindings and configuration bytes remain untouched by an update; the new dimensions apply to fresh placements/packages.
Compatibility and validation
Built as assembly/package/setup 2.17.2 with 23 packaged dashboards. The core suite passes 2,381 assertions; the hidden x86 WebView2 integration pass passes 2,403; installer preservation passes 42 and setup passes 54. Final Edge captures cover packaged size, 75%, opaque/transparent backgrounds, normal/dense states, Minimal Centre populated/clear states and a representative 1920 × 1080 layout. No live SimHub installation was changed.
Telemetry readers and their compatibility did not change: Radar, Delta and player damage remain available on F1 23/24/25 and the 2026 Season Pack with their existing field-level degradation; native Lap Chart history remains F1 25/2026 with the labelled sampled fallback for F1 23/24.
2.17.1
Changed
The estimated lap delta (a Time Trial personal best or rival the plugin has never recorded, or a best lap SimHub reports from before the plugin ran) is closer to the game's own number. 2.16.0 spread the reference's sector times along the nearest recorded lap in proportion to that lap's clock; a faster lap does not gain its time that way, so the estimate was 0.1–0.2 s off on average. The reference is now placed along the nearest recorded lap by where the track's recorded laps actually gain and lose time — a per-distance fit across every lap the plugin holds for the track, leaning on the slow corners (1/v²) when the laps are too few or too alike to tell; a lap far slower than the rest in a sector (coasted to the line, a spin, a safety-car lap) is left out of the fit so its one big loss cannot decide where the reference's time goes. Measured against the game's delta read from the screen capture inside two Time Trial replays: Suzuka (PB 2–3.5 s faster than every recorded lap) 0.115 → 0.075 s mean error, most of it from the slow-corner weighting; COTA (PB inside the range of the recorded laps) 0.126 → 0.121 s, a change inside the screen-reading noise; no lap worse than 0.004 s. The exact path for a recorded reference, the EST tag and the Shape source name are unchanged. Details and the tables in the validation report.
2.17.0
Added
Proximity Radar (480 × 480) uses the motion packet's world position, velocity and forward/right basis for a player-centred heading-relative view out to 30 m by default. Car-length shapes retain relative heading; physical side, chevrons and HOLD / THREE WIDE / APPROACHING / CLEAR text make warnings independent of colour. Entry/exit and closing-speed hysteresis keep it calm. ?mode=blindspot produces a 480 × 120 side-rail variant, and the same rails can be enabled inside the existing HUD without changing its default appearance.
Delta vs PB (560 × 240) records the player's fastest valid completed lap in the current session as a bounded distance-indexed reference and compares the current lap at the same track position. It combines a signed 40 px value, fixed ±0.5/1/2/5 s centre-zero bar and optional 240-point trace. The reference is guarded by session UID, game, track, length, car, packet format and formula/rules identity; invalid laps, pits, clock gaps and rewinds cannot replace or mix it. This overlay deliberately has no estimate: without an exact session reference it shows —.
Damage & Power Unit (640 × 480) has stable summary, schematic damage and PU pages. It covers front-wing halves, rear wing, floor, diffuser, sidepod, four tyre/brake corners, F1 25+ blisters, gearbox/engine damage, six PU wear values, DRS/ERS faults, blown/seized flags, engine temperature, ICE/MGU-K live power and deploy mode. It is player-only and presents EA's raw percentages without invented safe thresholds; red is reserved for explicit fault flags.
Lap Chart (720 × 420) plots position against lap with P1 at the top. F1 25 and the 2026 Season Pack use PacketLapPositionsData; the installed SDK's 50 × 22 and 50 × 24 layouts are handled from runtime bounds and participant race-number identity rather than assuming array index is a stable driver. Focused mode labels the player and up to four relevant rivals directly. Full-field mode is intended for broadcast/post-race use; pre-F1-25 fallback samples lap boundaries and is visibly labelled SAMPLED · EST.
Four native settings tabs, four Toggle<Name> actions, URL/enabled/visible/shown properties, focused state properties, purpose-specific local API routes, 28 normal/critical/missing/stale/paused/unsupported/dense preview fixtures and packaged picker images.
Changed
The release now contains twenty-two overlays plus the Steering Wheel dashboard. Driver and standings slots are bounded for the installed 2026 SDK's 24-car arrays while preserving every existing property name and dashboard identity.
Hidden or disabled racing-glance overlays stop their state polling; radar and delta capture are also visibility-gated. The lap chart processes each 1 Hz history packet once and only refreshes current labels/classification between packets.
The shared design contract now pins one-second-glance type sizes, tabular numerals, colour redundancy, calm motion and explicit unavailable/stale/paused/unsupported/session-change/rewind states.
Compatibility and validation
Built as assembly/package/setup 2.17.0. The core suite passes 2,357 assertions; the x86 WebView2 integration pass passes 2,379; installer preservation passes 39 and setup passes 54. Browser captures cover native size, 75%, opaque/transparent backgrounds, dense states and a 1920 × 1080 layout. No live SimHub installation was changed.
The installed SDK shapes are fixture-tested for F1 23/24/25 and the 2026 Season Pack. No stored replay in the repository contained an actual PacketLapPositionsData payload, so native lap-history values still need recorded/live-game confirmation; the exact installed type/container/dimensions and synthetic packet decoding are verified.
2.16.0
Fixed
The live lap delta. The Time Trial reference delta (Driver Ahead/Behind, Driver Relative, the Steering Wheel's Timing page and the Relative.*.Reference.DeltaSeconds properties) and the wheel's delta to the best lap were 0.1–0.4 s from the game's own number with a shape lap and 1–3 s without one (COTA Time Trial, 2026-09-14: +1.936 shown against the game's +0.955, −0.415 against −0.001). The estimate scaled a sector's time by the player's fastest lap, but a reference lap wins and loses its time in other places than the shape lap, and nothing survived a session. The delta is now running time minus the reference lap's own recorded clock at this point of the road: the plugin records every completed player lap as a lap profile (its clock against its lap distance, at the snapshot rate), matches a reference by its lap time to the millisecond, and reads the delta from that profile. The best lap of a session is always a recorded lap, so the wheel's delta to best is exact from the next lap on (Suzuka qualifying replay: within 1 ms of the recorded lap where 2.15.1 was 1.1 s off on average); a Time Trial session best is exact the same way; a personal best or rival is exact once the plugin has seen that lap, in this session or an earlier one on this track.
Until the reference lap has been seen, the delta is estimated from the nearest recorded lap of the track (persisted or this session) rather than linearly by distance, and the timing panels' EST tag and the wheel's estimated flag now mean exactly that: a shape estimate was flagged exact before. On the COTA and Suzuka replays that takes the first lap of a session from 0.85–0.97 s mean error (2.3–2.5 s worst) to 0.12 s mean (0.29 s worst); a personal best the plugin never recorded stays a ±0.1–0.4 s estimate, and the validation report has the frame-by-frame table against the game's overlay.
Added
Lap profiles (src/F1OverlayData/LapProfileReader.cs): the player's completed laps as time-at-distance profiles, keyed by the game's lap time with the sector parts as a guard, kept for the session (valid or not) and persisted per game and track under PluginsData\MoverlayF1\LapProfiles\<game>-<track>.json — the track's eight fastest valid laps, written off the telemetry thread after a lap, loaded when the track changes and carried across a session restart on the same track. A flashback, a replay seek, a reverse or a lost position drops the lap being recorded (a lap whose number jumps or whose distance wraps away from the line is never keyed with another lap's time); a damaged file is reported in the diagnostics and ignored. /api/v1/state carries a LapProfiles block (profiles held, the lap being traced, the store status); the Time Trial reference and the wheel view carry DeltaSource / DeltaToBestSource (Profile, Shape, Linear, Lap, Split) beside the estimated flags, and SteeringWheel.DeltaToBestSource is a new property.
2.15.1
Fixed
Rotary dial detent mapping. The Ascher Racing wheels report 1..11 for detents 1..11 and 0 for detent 12 at the top - 1-based with a wrap, not 0-based as 2.15.0 assumed after Detect saw 0..11 (the user's ring highlight showed physical position 1 lighting detent 2). The reader now maps a value one below the first-detent value to the last detent and treats any other out-of-range value as no position (the tile shows the dash, the ring lights nothing) instead of clamping to an end; the Ascher import and the load-time prefill use first detent 1 again; Detect no longer changes the first-detent value on its own and, when it saw a 0, says how to tell a zero-based dial from a wrapped one.
2.15.0
Added
Interactive dial setup on the Steering Wheel tab's Rotary dials card. Detect beside the property box samples every SimHub property for twelve seconds while you turn the dial and fills in the one that steps to new whole numbers (tie-break on names containing Dial, Rotary, Position or Encoder), sets the first-detent value to 0 when a 0 was seen and hints when the dial reaches beyond the Detents slider; it says so honestly when the dial reports as joystick buttons (not supported yet), when nothing changed, or when the page runs outside SimHub. The one-per-line label box is replaced by a radial label editor: a numbered ring with one box per detent (detent N at twelve o'clock, k at 360·k/N clockwise), re-laid live when Detents changes, that follows the physical dial four times a second with a red (Dial 1) or blue (Dial 2) highlight so a mapping can be verified by turning the dial. Import from… fills a dial from a wheel plugin's own file through an extensible provider list; the first provider reads the Ascher Racing plugin's AscherPlugin.RotaryDials.json (Dial 1 from LeftDial, Dial 2 from RightDial, twelve detents; first detent 0 in 2.15.0, corrected to 1 in 2.15.1). An import keeps a property Detect has already found, and flags a property the running SimHub does not list.
Changed
The Ascher Racing dial properties are AscherPlugin.Status.RotarySwitchLeft.Position / AscherPlugin.Status.RotarySwitchRight.Position, reporting 0..11 (verified with Detect on an Artura); the load-time prefill, the import provider and the documentation use them. 2.15.0 read that as a zero-based dial; 2.15.1 corrects it (1..11 then 0 at the top, first detent 1).
The Steering Wheel's flag bands are steady: the yellow band's 240 ms blink is gone (the marshal data behind it is constant between 2 Hz session packets, so the blink read as a fault); the 250 ms fade-in is the only cue and the rev limiter is the only thing that blinks.
The Steering Wheel polls at 33 ms while live (matching the dashboard's MinimumRefreshIntervalMS), the server keys the wheel and HUD payloads on the feed's latest-only sample (InputFeed.ReadLatest(), no sample-window copy per poll) so an unchanged poll returns the cached bytes, and the running lap clock and session countdown advance client-side between the 10 Hz snapshots (clamped to 1.5 s, frozen while paused, reset by every snapshot). Deltas, sectors, last / best and gaps stay snapshot-driven.
Bigger tile numbers. The foot row of tiles on every page and the Systems damage row now carry 42 px values with 13.5 px labels and 12 px units in 88 px (foot) and 78 px (damage) tiles, the height taken from the page body above, because the wheel screen sits below the eye line. With both rotary dials configured the Race foot shows dial, speed, fuel, dial (the ERS tile is dropped rather than shrunk; the store stays on the Systems page). The pit-limiter band grew to cover the taller foot.
A proper idle page between sessions, in the game's menu or with the game closed: a header band with the MOVERLAYF1 title and the STEERING WHEEL tag, a large local clock with the date, a state line (WAITING FOR SESSION, IN MENU, SESSION ENDED, WAITING FOR MOVERLAYF1), the last live session's track, session and best lap once there is one, and the configured dial tiles on the foot. Only the clock and a slow breathing of the red rule move; Brightness applies. ?demo=1&idle=1 (or ended, menu, error, with &clock=HH:MM) renders it for captures.
The client-side lap clock and session countdown are monotonic: they never run backwards on snapshot jitter (a lap or sector reset still snaps) and hold instead of saw-toothing while the packets are frozen (a paused replay, the Esc menu).
Fixed
The Systems page's ERS card on a 2026-regulation car no longer prints N/A 2026 over the DEPLOYED and HARVESTED labels: the DEPLOYED item is removed and HARVESTED is centred; no value slot prints a placeholder string.
The dial card's property and import pickers fill their row (they were fixed at 160 px), pressing Detect on the other dial cancels the running detection and starts the new one instead of doing nothing, and the ring's live highlight lights nothing for a property value outside the ring (it used to light the clamped end box, which could make a wrong first-detent choice look right).
tools/Dashboard-Update.ps1 retries a briefly locked dashboard file before replacing it (a transient Defender / indexer lock seen once in the installer suite).
2.14.0
Added
A Dashboards tab on the plugin settings page, between Overlays and Start Analysis, for the screens that are not overlay windows. It has the same left tab strip and its own Save and apply / Reset to defaults bar; both bars save the whole configuration.
The first dashboard: MoverlayF1 - Steering Wheel, an opaque 800 × 480 Formula 1 steering-wheel screen for a wheel-mounted display (VoCore, Simagic MagicDash, Asetek Invicta, Cube CSX3) or a phone. Four pages: Race (huge gear with a bidirectional MGU-K bar, lap and position, the two road neighbours with gaps, last / best lap and a live delta, the DRS state as a head-row pill, the fitted tyre beside the lap counter, and speed, ERS and fuel tiles between the optional dial tiles), Timing (current lap, delta to the best lap, three sector boxes coloured against the player's best sectors, last / best, session clock or laps left), Tyres (four corner tiles with surface or carcass temperature coloured by the compound's window, wear, brake temperature and pressure; engine temperature, brake bias, air and track) and Systems (ERS store, deployed and harvested, fuel laps, mix and kilograms, engine temperature, brake bias, five damage tiles (both front-wing halves in one), penalties, the predicted pit window and next tyre, air and track).
Three bindable actions, SteeringWheelNextPage, SteeringWheelPreviousPage and SteeringWheelHomePage, with pickers on the tab; the page wraps around over the enabled pages only and the home page follows the session (Race in races, Timing otherwise) unless a fixed page is configured. ?page=race|timing|tyres|systems on the dashboard URL pins one page for a multi-screen layout.
Takeover bands instead of full-screen strobes: a flag band under the rev strip (blue from the per-car marshal flag, yellow with the sector and a 240 ms steps(1,end) blink, red, safety car and VSC with the delta, green for six seconds, chequered) and a pit-limiter band over the tile row with the lane limit and the live speed delta (cyan under the limit, red over it). When brake bias, ERS mode or fuel mix changes, the new value takes over the centre of the screen for 1.5 s, like a real wheel.
An optional fifteen-light rev strip along the top edge (off by default because most wheels carry their own LEDs; the pages reclaim the height when it is off), a speed unit, a choice of surface or carcass temperature for the Tyres page and a brightness setting for night use. No row holds more than five tiles and no tile value is under 26 px, so the screen reads at speed: the Race page keeps speed, ERS and fuel tiles, moves the DRS state into a head-row pill and the tyre beside the lap counter, shows penalties and warnings only when non-zero, and leaves brake bias to the rotary overlay and the Tyres / Systems pages.
Two generic rotary dials on the Race page: each reads a numeric detent from any SimHub property you name (the Ascher Racing wheel publishes its dial positions as SimHub properties, see 2.15.0 for the names; the tab lists every property mentioning a dial, rotary or encoder), with a detent count, the value at the first detent, one label per line, a corner tile with a ring of detents, the position and the label (red accent left, blue right), and the same transient popup as brake bias when the position changes. Nothing draws for an unconfigured dial. SteeringWheel.Dial1.Position / .Label and Dial2 mirror them.
New properties SteeringWheel.Page, PageName, PageCount, Available, FrontBrakeBiasPercent, EngineTemperatureC, FuelInTankKg, DeltaToBestSeconds, DeltaToBestLabel and DeltaToBestEstimated, plus Overlay.SteeringWheelUrl; the /api/v1/steeringwheel-state projection and the SteeringWheel settings block.
Internal
tools/Overlays.ps1 rows can carry Kind = 'Dashboard': Package-Overlay.ps1 then writes an opaque, non-click-through dashboard package with IsOverlay false, CategoryDashboard and no Visible binding (there is no Overlay.SteeringWheel.Shown; the dashboard is not a visibility key).
SteeringWheelReader adds the player's brake temperatures, tyre pressures, engine temperature, brake bias, fuel mass, the per-car marshal flag (spelled m_vehicleFiaFlags on F1 23/24 and m_vehicleFIAFlags on F1 25/26) and a delta to the player's best lap that is exact at every sector boundary and estimated by distance in between. CarDamageDetails carries both front-wing halves.
The settings descriptor engine has a Dashboard flag (no visibility card, no colour card) and a second DashboardTabs table, so the generated overlay tabs keep their order.
2.13.2
Fixed
The Pit Stop Helper no longer pops up mid-track during the first half of a lap when a pit request is on but the car is not yet near the pit entry. On circuits whose pit entry sits just before the start/finish line (Suzuka), the entry marker is more than half a lap ahead for that half-lap; the card wrongly fell back to a straight-line distance to the entry point and showed nonsense distances and braking cues near the pit straight and first corner. The approach distance is now always the along-track distance when the lane file carries an entry fraction; the straight-line fallback is used only for lane files without one.
2.13.1
Added
The native plugin page now has a Diagnostics tab with the latest plugin Debug, Info, Warning and Error events. It supports level and text filtering, pause, copy and clear.
Important lifecycle, configuration, session, action, packet-reader, circuit-map, pit-lane persistence, HTTP server and performance transitions now produce contextual diagnostics. Repeating telemetry and server faults are rate-limited.
Every event sent to SimHub starts with [MoverlayF1][Category]; uncategorized events use [General], so the plugin and subsystem are easy to filter in the central log.
Internal
Logging now passes through a host-neutral abstraction and a bounded asynchronous queue. The SimHub build forwards events to SimHub's central log for durable support history while retaining the latest 1,000 events in memory for the plugin tab; telemetry producers never wait for log I/O. A future standalone host can supply its own console or rotating-file sink without changing the telemetry readers.
2.12.8
Added
Pit Stop Helper now counts down to the learned pit-exit line on out laps and after a timed race stop, telling the driver when to disable the pit limiter. The live estimate uses remaining distance and current speed, crosses start/finish correctly, and stays unavailable for older pit-lane files whose exit marker is only inferred.
Internal
Rebuilding a release now replaces an existing same-version setup executable before compilation, keeping repeated packaging tied to the latest verified DLL.
2.12.7
Changed
Track Position Circle now hides automatically in Time Trial and returns with the user's existing visibility setting when another session type begins.
2.12.6
Added
Start Analysis now records and filters by car type. F1 2023, F1 2024, F1 2025, F1 2026 and F2 launches remain separate by default; All car types is available for archive browsing and warns that vehicle-performance statistics are mixed.
Internal
Added installed-SDK, durable-history and native WPF fixtures for car classification, persistence, default filtering and mixed archive browsing, bringing the core suite to 1,971 assertions.
2.12.5
Added
Added EA SPORTS F1 23 support through SimHub, including packet freshness and session continuity, circuit-map discovery, race gaps, lap history, tyres, weather, starts, strategy telemetry, HUD data and the overlay suite.
Compatibility
F1 23's older race-gap and sector-time field names are translated into the same public seconds values as later games. Its missing formation-lap option is handled from the live formation state instead.
F1 23 has no Time Trial reference packet or structured Safety Car event payload. Time Trial still exports only the real player but leaves PB/rival comparison empty, and the Safety Car Helper follows the session status while the Race Control ticker cannot announce the later structured Safety Car event messages.
Internal
Expanded the installed-SDK fixtures to run F1 23 alongside F1 24, F1 25 and the 2026 Season Pack across 1,967 telemetry, renderer and API assertions.
2.12.4
Changed
The HUD input-telemetry popup now has its own Visible when SimHub starts switch. The one-shot settings-page button is gone; the bindable show/hide action remains available while driving.
Fixed
Tyre Life no longer learns a degradation rate from a lap touched by the safety car, virtual safety car or formation lap. Slow neutralized laps had made the 50%-wear projection jump to implausible values across every compound; the last valid green-flag estimate is now preserved until another wholly green lap completes.
Safety Car Helper strategy reversals caused by a moving rejoin threshold must remain stable for one second before BOX BOX changes to STAY OUT or back. Urgent calls still apply immediately, supporting text can update live, and the tile now blinks only when the main call actually changes.
2.12.3
Added
The timing tower now names the full qualifying round as Q1, Q2 or Q3, and the matching sprint-qualifying rounds as SQ1, SQ2 or SQ3. In Q1/Q2 and SQ1/SQ2, the positions which will not advance sit inside a red boundary below a labelled BOTTOM 5/6 · KNOCKOUT RISK divider; 20- and 22-car fields use their matching cut.
Fixed
Aborting the first push lap no longer leaves the player marked as PUSHING for most of a slow lap. Before anyone has completed a time, sustained same-position pace against other confirmed pushes can clear the push state and immediately restore approaching-traffic warnings; the field's session best remains a later fallback.
2.12.2
Fixed
The HUD now follows the car's actual regulations inside the F1 26 Season Pack. A 2025 car shows DRS and the green per-lap ERS deployment-remaining arc; only a 2026-regulation car shows active aero and omits that legacy deployment allowance.
2.12.1
Added
Added EA SPORTS F1 24 support through SimHub, including F1 24 packet freshness and session continuity, circuit-map discovery, Time Trial references, race-control events, strategy telemetry, HUD data and the full overlay suite.
Internal
Expanded the installed-SDK fixtures to exercise F1 24 alongside F1 25 and the 2026 Season Pack, including participant privacy, stale packets, session changes, maps, flags, lap history, tyre sets, HUD/ERS data and renderer/API contracts.
2.12.0
Added
MoverlayF1 now recommends a tyre for your next stint and shares it between the Pit Window and Tyre Delta cards. It ranks the sets still in your allocation from the game's per-set lap-time delta and remaining set life, the wear this session has measured, the laps left after the stop, the dry two-compound rule, the weather and its forecast, and the pace the field is running on each compound. It also watches the game's own wet-tyre pricing, which is condition-aware: when the lap-time penalty of a fresh intermediate against your slicks starts collapsing, the card calls TRACK GOING WET and the Safety Car Helper raises a TRACK WETTING chip, well before the weather flag itself changes. F1 still does not export the tyre selected in the pit MFD, so this remains a transparent estimate of the best set rather than the game's own choice.
The Pit Window caption now says why that tyre was picked (FASTEST TO THE FLAG, ONLY SET THAT FINISHES, 2-COMPOUND RULE, RAIN 70% IN 8 MIN, TRACK DRYING), the header shows a RAIN {percent}% IN {minutes} MIN tag while rain is forecast inside the coming stint, and the CURRENT TYRES tile adds the laps the fitted set still has. All three follow the new Show why that tyre is recommended switch.
The Pit Window now also predicts when to stop. Its big lap range is MoverlayF1's own prediction, with the game's window kept as a small GAME LAP 20-26 note when the two differ; one switch swaps which of the two is big. The model balances the wear of the two stints, is fenced by the lap from which the new set can still reach the flag, by the fitted set's cliff and by the two-compound rule, names its reason (BALANCED WEAR, TYRE LIFE LIMIT, NEW SET MUST FINISH, TWO STOPS NEEDED, 2-COMPOUND RULE), and reads NOW under a safety car when the strategy call says box. Both laps are estimates; the prediction assumes a fully worn set costs about 2.2 s per lap.
The tyre recommendation now runs in every session, not only races: practice and qualifying get a pace-only ranking inside the current weather family (FASTEST AVAILABLE), so the Tyre Delta's BEST tag is useful all weekend. In races the Pit Window and Tyre Delta strategy information is on the cards the whole time, not only during a safety car period.
Tyre Delta marks the recommended compound with an outlined BEST tag next to FITTED and NEW SET, and adds a one-line footer with the compound and its reason. New Mark the recommended compound and show why switch, on by default.
New Safety Car Helper settings for the strategy call: the pace offset needed to regain one place after the restart, the projected net gain from which a stop is called on pace alone, the number of positions either side that counts as a rival, and switches for the weather and field inputs. New Pit Window settings for the recommendation: the forecast rain percentage that counts as rain coming (80% by default, because the game reports a probability rather than an intensity and the forecast's own condition code leads), the wear level treated as the end of a set's useful life (70% by default), the penalty per lap run past that cliff, and whether the field's pace may nudge the game's tyre deltas.
Changed
The Safety Car Helper's strategy call now weighs far more than track position. On top of the existing rejoin, wear, damage, window, laps and penalty rules it knows that you already stopped in this period, that rain is coming or the track is drying, that rain arriving later in the stint makes a dry stop now a wasted one, that a stop is needed anyway (the dry two-compound rule still open, or tyres that cannot reach the flag), what the rivals around you are doing (stopped under this period, in the lane right now, or on clearly fresher tyres), and what the recommended compound would gain in seconds over the laps it covers — netted against the places lost at the rejoin, at double cost on circuits where overtaking is known to be hard.
The call now also names the tyre to fit, with a compound glyph beside the advice, up to three evidence chips (rejoin, tyre life, rule, rain, rivals, HARD TO PASS, laps left) and a confidence that drops to LOW when the underlying data is thin. It still blinks only when the decision or its material reason changes, and it remains assistance, not a guarantee: the pit MFD choice, the VSC time remaining, the safety-car grace period and the FIA safety-car lines are all still absent from the game's telemetry.
The Tyre Life card's EST rows — the compounds not yet measured this session — now read the game's usable life correctly: it counts laps to about 70% wear rather than to a completely destroyed tyre. Those estimates are therefore roughly 40% longer than in 2.11.3 and much closer to what the game itself shows. Measured rows are unchanged.
The pit call is now printed as BOX BOX, the word a pit board uses, with STAY OUT unchanged; the Pit Window caption reads PREDICTED NEXT TYRE so a modelled answer is labelled as one. The SafetyCar.Advice property keeps its Pit / StayOut values.
Internal
Each car's stint history is now read from the session-history packet, giving every driver a stint start lap, a median of their recent clean laps on the current stint and the compounds they have run this race. That is what feeds the per-compound field pace behind the recommendation.
Added fixture coverage for the weather families, the two-compound rule, set life and cliff shortfalls, the field-pace nudge and its cap, every new strategy-call branch, and the renderer, property, settings and configuration contracts of all three cards.
2.11.3
Added
Added Show corner numbers to the Track Map, disabled by default, with compact outside-the-circuit labels for the bundled current F1 layouts and a ?corners=0|1 dashboard override.
Changed
The learned pit lane now has a solid light-green centre line and connects close legacy endpoints to the main circuit so the entry and exit are not left visibly incomplete.
Sector boundaries are slightly larger, and the S1/start-finish boundary is now a black-and-white checkered line.
Fixed
Sector, detection, start-finish and pit-lane markings now render above yellow SC/VSC track highlighting instead of disappearing behind it.
Internal
Added a full-course-yellow Melbourne preview fixture and renderer/property/settings regression coverage for the new Track Map layers.
2.11.2
Added
The Safety Car Helper now makes a live PIT or STAY OUT strategy call from the projected rejoin, positions lost, tyre wear, repairable front-wing damage, pit window, laps remaining and serviceable penalties. The call is reconsidered throughout the SC/VSC and its tile blinks briefly only when the decision or material reason changes.
A VSC-ending phase now includes an explicitly estimated configurable countdown. Because the game exports the ending event but not its time to green, the real resume event still ends the estimate immediately.
Optional EST SC LINE 1/2 guidance uses each track's learned pit entry and exit, with configurable display range and per-line offsets. It identifies cars ahead currently in the pits only while the player's safety-car delta is safe; the F1 telemetry does not provide the official FIA line coordinates, so these cues are always labelled estimates.
Changed
The Safety Car Helper is now 420 × 262 to make room for the strategy call. When the full-SC train has formed and the safety car is coming in, its bottom pit-loss / penalty / rejoin row fades and shrinks so restart information takes priority; this treatment can be disabled.
Player car-damage detail now includes front-wing and wider aero percentages in the compact HTTP snapshot used by the strategy helper. Opponent privacy restrictions remain unchanged, and non-repairable aero damage is context rather than a false pit recommendation.
Internal
Added F1 25/F1 26 fixtures for damage normalization and privacy, every advice priority, stable advice revisions, ending-row compaction, VSC countdown behavior, learned-line offsets, safe-delta pit traffic and the expanded renderer/settings contract.
2.11.1
Changed
Reworked the Pit Window's small three-gadget strip into a larger 2×2 grid for PIT TIME, PENALTY, REJOIN and CURRENT TYRES. The card is now 500 × 500 so the gadgets are deeper and closer to square, and the fourth shows the fitted compound with its live four-tyre average wear underneath.
2.11.0
Added
Added Pit Stop Helper, an automatic 420 × 72 lower-third in the same format as Qualifying Traffic. On the game's in-lap it uses the learned pit-entry marker to show distance, current speed, the pit limit, required braking urgency and limiter state; inside the lane it warns immediately if the limiter is off or the car is over the limit. Race and sprint stops continue through BOX, serviceable PENALTY, timed PIT STOP and RELEASE phases, while practice and qualifying retain only entry and lane-speed guidance. Tracks learned from 2.11.0 store exact entry/exit positions and lap fractions; older pit-lane files remain compatible with an explicitly estimated entry.
The HUD can now unfold and fade a compact 226 × 90 throttle, brake and ERS history graph upward from the rev-light tab. Its outer border replaces the rev tab's top edge while open, so no seam crosses above the lights. It starts closed, can be toggled directly from the HUD settings or with its own ToggleHudInputs SimHub binding, reuses the Inputs overlay's trace duration and ERS switch, and only requests history while open.
Internal
Added F1 25/F1 26 packet coverage for every pit-helper phase, stale session/status packets, learned and fallback entry distance, visibility/settings, the compact HTTP projection, renderer route and persisted pit-entry metadata.
Fixed
The HUD rev strip now follows the game's car-calibrated rev-light percentage, so all fifteen lamps illuminate in order instead of inheriting missing low bits from the optional lamp mask; the strip blinks from that same indicator at the configured high-rev threshold.
The HUD no longer duplicates brake and throttle in bottom-edge bars; the red brake and green throttle arcs remain around the gear gauge.
The ERS ring now follows the ruleset: F1 25 shows harvest used and deployment allowance left, while F1 26 removes the inapplicable deployment arc and uses the full ring for its dynamic harvest limit. F1 26 no longer publishes a percentage against an invented 4 MJ deployment limit, and the tiny captions have been removed from the dial.
The ERS deploy-mode name is optically centred in its tag for every mode instead of sitting a few pixels high.
2.10.2
Added
The native MoverlayF1 settings page now has two top-level tabs: Overlays keeps the existing sixteen overlay pages, and Start Analysis adds a persistent launch journal with summary bests, clean rate, recent trends, recurring coaching priorities, reaction consistency, four telemetry graphs, a filterable and paginated start log, safe per-start/full-history removal and a complete selected-start debrief.
Completed starts now retain the context needed for that debrief: track, session, local date/time, dry/wet and tyre conditions, lights-out RPM and throttle, target band, minimum launch RPM, rear slip, clutch/reaction/0–100/0–200/full-throttle times, verdict and advice, and the shift-by-shift RPM, timing, quality and slip state. Up to 5,000 starts survive SimHub restarts in PluginsData/MoverlayF1/start-analysis.json; writing happens away from the telemetry callback, the log renders only 25 rows per page, and each graph samples at most 240 points.
Internal
Added focused coverage for persistent start-journal deduplication, isolation, reload, removal and damaged-file handling, for the richer completed-start record on both F1 25 and F1 26 packets, and for the two-level native settings UI, filters, pagination, trend graphs and calculated summary.
2.10.1
Changed
Tyre Life now matches Tyre Delta's row layout: every row names the compound, the lap range is right-aligned, and the FITTED / EST tags sit below the compound name where Tyre Delta shows its spare-set count.
The HUD panel now wraps around the gear and ERS gauges with semicircular end caps, so its outer border follows both round gauges instead of ending at two straight vertical sides.
Tyre Prep now presents coaching in a dedicated DO THIS gadget with a condition-coloured accent and explicit actions for cold fronts, cold rears, all-cold, hot and ready tyres.
2.10.0
An optimisation and consolidation release: no new overlay, no new setting, and no changed property name, JSON shape or dashboard identity. The plugin does less work per snapshot, the overlays render more smoothly and back off consistently, one shared script replaces fifteen copies of the same helpers, the settings page is generated from descriptors, and the seventeen overlays follow one written design vocabulary.
Fixed
An overlay no longer stays frozen for the rest of the session after its renderer trips over one bad value. Weather, Tyre Delta, Tyre Life, Pit Window and the Leaderboard scheduled their next update only after drawing, so a single failed draw left them with no pending update at all; every renderer now schedules the next one whatever happens and keeps polling.
The HUD accepted the car-status packet on session-UID equality alone, with no age check, so if the game stopped sending car status while lap data kept arriving the HUD kept showing a frozen fuel level, ERS store, deploy/harvest and warning count as if live, and the Tyre Prep card's fuel decision with it. The status packet now has the same two-second bound as the weather and track-feature packets.
A car on the Track Position Circle that was between two updates when the session paused no longer sits up to a tenth of a second of travel away from where it actually is: markers snap to their last reported position when the smooth-motion loop stops.
The Tyre Life card no longer slides up into place the first time it appears, and a Qualifying Traffic row no longer stops mid-slide before it vanishes.
The pit-lane store's first read for a track ran inside the lock that the 10 Hz telemetry callback also takes; it now loads outside the lock and publishes under it.
Changed
Telemetry snapshot work is about 2.4× cheaper on a benchmark that now covers a real session: the player's tyre-set allocation is read once per snapshot instead of once per card, the marshal zones are scanned once instead of twice, each car's session-history laps are parsed only when that car completes one, the packet container and the raw session type are fetched once, and packet fields are read through compiled accessors instead of reflection. The benchmark fixture previously carried no session history, tyre sets, car damage, marshal zones or event log and never ran the per-frame tick, so the published 0.13 ms figure understated a live session; with those in place the unoptimised code measures 0.45 ms per snapshot and this release measures 0.18 ms. The higher starting number is a more honest baseline, not a regression.
Sprint races count as races everywhere: the Start Helper, Pit Window and Tyre Prep cards decide the session kind through one rule that reads the game's own session type first and the normalised session name second. The Start Helper therefore also arms on a sprint race whose session name lacks "race" when the packets carry no session type.
The settings page's tab strip is a single vertical column. With sixteen overlays the previous strip wrapped into four rows and moved the selected tab's row to the bottom, so choosing a tab reshuffled every other one. Twelve of the sixteen tabs are generated from one descriptor each; every control name, slider range, drop-down entry and tab header is unchanged.
config/config.json lists every setting at its default value instead of six of the eighteen sections, so it doubles as a reference for hand-editing. No shipped value changed, and a partial file still loads.
tools/Install.ps1 refuses to run only while a SimHub started from the folder being updated is running, matching the setup executable, and both it and tools/Dashboard-Update.ps1 report an unreadable configuration file or installed dashboard with the same "nothing was changed" message the setup executable already used.
The HUD's throttle and brake arcs, ERS store and pedal bars and the Safety Car Helper's grace countdown now finish each step exactly as the next reading arrives instead of trailing it by a fraction of a step, and the bars are scaled rather than resized, so they no longer re-lay out on every frame.
The Inputs trace is rebuilt only when new samples arrive and slid across the plot in between, instead of being rebuilt point by point sixty times a second: a few thousand fewer coordinates per frame on the twenty-second window.
The Race Control banner drains its progress bar as one animation instead of about 185 redraws per message, and its timer now runs only while a message fades in and out.
Every overlay now backs off to one request a second when the plugin is unreachable, the data is stale or the page is hidden. Race Control and Qualifying Traffic used to keep asking four times a second indefinitely, and the Inputs page kept polling twenty times a second in a hidden browser source. Start Helper, Start Report and Tyre Prep idle at one request a second instead of two and speed up as soon as a start approaches, and the HUD and Safety Car Helper check their settings once a second like every other overlay.
The fifteen Chromium overlay pages now share one small script instead of each carrying its own copy of the same helpers; the two timing panels keep theirs, so the standalone HTA files are unaffected.
All seventeen overlays now follow one written design vocabulary (docs/DESIGN.md): the same colour tokens, type ladder, 14 px gutter, header grammar, components, motion durations and number glyphs. Nothing new was invented — where two values competed, the one most of the overlays already used won.
One card header. The Pit Window, Tyre Delta and Tyre Life cards now carry the same 40 px header band as the rest of the set: the title, a red rule under it and a context tag on the right that names the conditions (DRY / DRY & WET) or the race state (RACE, UNDER SAFETY CAR, UNDER VSC). The two tyre cards keep their centred red titles. The Safety Car Helper's coloured state band is two pixels taller so it lines up with them.
One gadget tile. The Pit Window's pit time / penalty / rejoin tiles were half again as large as the identical trio on the Safety Car Helper; the two are now the same component, and the Start Report's six result tiles join them.
One set of number glyphs. An unknown value is a single em dash everywhere (the Pit Window, Tyre Delta, Tyre Life and the fuel and delta readouts used to print -- or a doubled dash), a lap or temperature range uses an en dash without spaces (20–26, 75–100 °C), a negative number uses a real minus sign on the two timing panels as it already did on the cards, and the Qualifying Traffic gap reads 2.8s · 150M.
One status chip and one demo badge. The Driver Relative panel's status was 6.5 px text inside the panel and the Driver Ahead and Behind panel's competed with the timing grid; both now use the same chip over the panel as every card, in sentence case. The Track Map's separate PAUSED chip is gone — Paused is a status like any other — and the Leaderboard, Track Position Circle and both timing panels gained the demo badge they lacked.
Full-bleed cards. The Start Report, Tyre Prep, Start Helper and Pit Window panels no longer leave a 4 px transparent margin inside their window; their content keeps the standard 14 px gutter and sits where it did.
The Start Report, Tyre Prep, Race Control and Qualifying Traffic panels fade in and out over the same quarter second as the rest, the Leaderboard and Inputs panels cross-fade instead of cutting, and every panel corner has the same radius.
The Weather strip gained the red accent and floor bar that already framed Race Control and Qualifying Traffic, so the three lower thirds read as one family.
The HUD's smallest labels, the Leaderboard's page title and its battery percentages are a little larger, and the Track Position Circle's rejoin estimate no longer turns green or amber by how confident the estimate is — those colours mean faster and slower everywhere else. It stays orange and carries an EST tag until the pit loss has been learned.
The tyre glyph is now drawn from one shared definition instead of six copy-pasted ones.
Internal
Packet reading and the small numeric guards live in one place each: PacketAccess (Member, Number, Flag, Code, Byte, Count, LiveHeader, Header, Fresh) and the new Num (FiniteOrNull, FiniteOrZero, IsFinite, PositiveOrNull, IsPositive, NonNegativeRounded1, ValidFraction, Difference, Percent0To100Rounded1, Clamp). Seventeen readers lost private copies that shared a name without sharing a meaning. A packet field whose type stops converting now yields a null field instead of an exception that blanked the whole snapshot.
The local server keeps one route table and one cache per view instead of seventeen lock/snapshot/buffer triplets and a forty-branch dispatch; lock granularity, route paths and payload bytes are unchanged.
Settings validation is shared (one clamp, one colour check and one whitelist helper replace six copies) and OverlayConfiguration.Normalized() validates every overlay section in one place for both the configuration loader and the settings page's save path.
The eighteen Overlay.<Name>Url properties are computed once when the overlay server starts instead of on every property read, the seventeen .Shown properties no longer take a lock on a cache hit, the three Map.PitLane* properties share one lookup per snapshot, the leaderboard page list, flag sectors and leader lap are derived once per generation, and plugin start-up no longer instantiates the same generic registration method 3,168 times.
One overlay inventory, tools/Overlays.ps1, replaces the three hand-maintained overlay lists in Package-Overlay.ps1, Capture-Previews.ps1 and Dashboard-Update.ps1, and tools/Build.ps1 embeds every renderer and script it finds in overlays/.
New tests: tests/PropertySurfaceTests.cs pins all 3,475 registered SimHub property names and declared types, the eighteen renderer routes and the legacy leaderboard aliases; the HUD suite covers the two-second status bound; the benchmark asserts its own coverage. The build passes 1120 SDK/plugin assertions, 36 installer-preservation assertions and 54 setup-executable assertions.
2.9.0
Added
Added the pit lane to the Track Map. SimHub's circuit records hold one clean flying lap and no pit road, so MoverlayF1 now learns the lane from the cars that drive through it: a car's world positions from about a second before the game flags it as pitting until about a second after the flag drops become the entry road, the lane and the exit road, drawn as a grey road with a dashed centre line under the circuit outline at the circuit's opacity. One clean pass by any car is enough; a longer pass later replaces a shorter one, and a car that stops in its box or jumps (flashback, replay seek) never spoils a lane. The result is remembered per track under PluginsData\MoverlayF1\PitLanes, so it is there again after a restart. Cars in the pit lane already sit at their world position and now ride on the lane instead of beside the circuit.
Added the Show the pit lane switch on the Track Map tab (on by default), the ?pitlane=0|1 URL override, the Map.PitLaneStatus, Map.PitLanePoints and Map.PitLaneLengthMeters properties and the PitLane block of the /api/v1/map payload.
Not covered: the lane is only drawn once some car has driven through it while MoverlayF1 was running; a track nobody has pitted on yet shows the circuit alone, as before. Learning runs in races, practice and qualifying, not in Time Trial. Deleting a track's file under PluginsData\MoverlayF1\PitLanes forgets that lane.
2.8.0
Added
Added HUD, a 480 × 120 driver card inspired by the Pits n' Giggles HUD overlay and drawn in MoverlayF1's own broadcast style. A tab on top holds fifteen rev lights (green, red, blue) lit from the game's rev-light bit mask; the whole strip blinks from a configurable share of maximum RPM. The body carries a gear circle whose ring shows the brake (left, red) and throttle (right, green) as arcs, a speed / RPM column in km/h or mph, a row with the track-limit warning count (amber, then red) and the air and track temperature, a DRS pill (LIMITER, DRS ON, amber DRS with the metres to the activation point and a distance fill, grey otherwise; OVERTAKE, STRAIGHT and AERO on the 2026 packets), the laps of fuel beyond the end with a sign and an optional mix tag, an ERS gauge whose ring shows this lap's harvest (left, red) and deployment (right, green) around a disc that fills with the store percentage in a light tint of the deploy mode's colour and names the mode in a small tag under the percentage (NONE grey, MEDIUM amber, HOTLAP blue, OVERTAKE red), and brake and throttle bars.
Pedals, gear, revs, speed, pit limiter, DRS and the 2026 active-aero and overtake flags come from the 60 Hz input feed, sampled when the card polls at 20 Hz; warnings, temperatures, fuel and the ERS energy budget come from the 10 Hz snapshot. The card hides while the player sits in the garage by default.
Added its HUD settings tab (a switch per element group, speed unit, rev blink threshold, colour and opacity), startup visibility, the ToggleHud action, the Hud.* properties and the /hud page with its /api/v1/hud-state endpoint, which pairs the snapshot's Hud block with a Live block holding the newest 60 Hz feed sample and no sample arrays.
2.7.0
Added
Added Safety Car Helper, a 420 × 200 card for safety car and virtual safety car periods in races. It fades in when either is deployed, follows the period through deployed, in this lap/ending, returned and race resumed, holds a green-flag state for a configurable time and fades out again.
The card shows the player's live safety-car delta (green with a margin bar when slower than the required pace, red when under it, IN SC TRAIN once the car has closed up behind a full safety car), a countdown bar that drains over a configurable grace period (default 15 s, the countdown players have timed in the game before its drive-through) while the player is under the delta and ends in PENALTY RISK, skipped while a VSC is ending because the game gives no grace there, and, as three gadget tiles, the current pit estimate: the safety-car-reduced pit-loss time, the pending stop/go or time penalty inside it and the projected rejoin position, with position, lap and the gap ahead in the footer.
Added its settings tab (delta and pit-estimate rows, grace period, green-flag hold, fade time, colour and opacity), startup visibility, the ToggleSafetyCar action, the SafetyCar.* properties and the /api/v1/safetycar-state endpoint.
Fixed
Counted pending stop/go penalties in the pit rejoin estimate before the stop. The game raises m_pitStopShouldServePen only once the car is already in the pit lane, while m_numUnservedStopGoPens is set the moment the penalty is issued, so a Melbourne replay with a stop/go under the safety car showed PIT 8.5s instead of 18.5s until pit entry. Each pending stop/go now adds 10 s on top of the safety-car or VSC reduction, the circle shows the addition as (+10s PEN), and reference cars with unserved penalties are no longer used for pit-loss learning.
Changed
The Pit Window card now carries the same stop estimate as the Track Position Circle as three gadget tiles under the tyre: PIT TIME (amber under a safety car or VSC), PENALTY (a pending stop/go or serviceable time penalty in red, NONE otherwise) and REJOIN (MoverlayF1's projected position; the game's own prediction, when enabled, reads GAME PREDICTS Pn underneath). Each tile has its own switch on the Pit Window tab, and the circle's (+10s PEN) suffix has one too; the PitWindow.* state and properties gain PitLossSeconds, PitPenaltySeconds, Neutralization, EstimatedRejoinPosition and UnservedStopGoPenalties, and PitLoss.RejoinPosition is new.
Tyre Delta no longer writes FITTED · NEW SET under the compound name, where it ran into the delta value; the fitted row now shows its spare-set count like the others and carries outlined FITTED (red) and NEW SET (green) tags under the value, in the style of Tyre Life's EST tag. Tyre Life marks its fitted row with the same FITTED tag.
2.6.9
Changed
Changed Pit Window to lead with a projected next tyre from the fresh race allocation, remaining set life, weather, stint history and the dry two-compound rule; the fitted tyre now appears as context below it. F1 25 does not transmit the tyre selected in the pit MFD, so the card labels the result as projected rather than exact.
2.6.8
Fixed
Made adaptive pit-loss learning fall back to relative race progress when F1 leaves every leader-gap field at zero, while still requiring at least two continuously running reference cars and a confirmed clean stop.
Read DNF, DSQ, not-classified and retired states from the fresh public lap packet when SimHub's normalized retirement flag is missing; retired cars no longer keep a highlighted pit marker or count toward the predicted rejoin position.
Adjusted the predicted pit time and rejoin position for full safety car and VSC running, then added only penalties the game explicitly marks for service at the stop. Classification-only time penalties remain excluded.
2.6.7
Fixed
Suppressed a qualifying traffic warning when the player has already crossed start/finish and a trailing car is still completing its current push lap. That car reaches the timing line before it could reach the player, so it is reconsidered only from its new lap state after crossing.
2.6.6
Fixed
Kept Qualifying Traffic catch prediction on continuous course movement during the first timed laps, before a completed reference lap exists. Noisy normalized time gaps remain available for display but can no longer create an early warning that drops out before the distance trigger takes over.
2.6.5
Added
Added a configurable course-distance safety trigger to Qualifying Traffic. It always warns for an eligible approaching car inside 300 m by default, alongside the predicted-catch and time-gap triggers.
Fixed
Stabilized the qualifying warning and +N count around alert thresholds by calculating approach from continuous road motion and delaying release through brief reversals, while still clearing a car immediately after it passes or leaves its push lap.
Preserved push-lap observations and warning latches while the game is paused, so resuming does not attach mid-lap and forget which cars were pushing.
Documentation
Replaced the implementation-heavy root README with a screenshot-led project overview and quick start.
Added focused installation, overlay, configuration and development guides under docs/.
Moved historical release notes into this changelog.
2.6.4
Changed
Rebuilt qualifying push-lap detection around each car's out/push/prep/in sequence and learned same-position push pace. The game can report “flying lap” across all of those laps, so that status is no longer treated as proof of a push.
Applied the corrected push state consistently to Qualifying Traffic, player-push suppression, the Leaderboard, Track Map and Track Position Circle.
Kept the detector on public lap timing and validity data so it does not require restricted opponent inputs.
2.6.3
Changed
Practice, qualifying and shootout pit/garage cars retain the selected timing-tower value and use a muted row plus a small secondary marker.
The Leaderboard now starts on a session-aware page: Interval for races, Fastest Lap for practice and Time Trial, and Gap to Leader for qualifying and shootouts.
Session identity/type changes reset the tower to that default; disabled or irrelevant pages fall back cleanly.
2.6.2
Added
Qualifying Traffic now shows the live course distance after the time gap, including start/finish-wrapped threats. The seconds value remains when circuit length is unavailable.
2.6.1
Changed
Added consistent, session-aware pit and garage cues to the Leaderboard, Track Map and Track Position Circle.
Added the Leaderboard Show pit indicators setting.
Retained active garage cars on the circle when a valid lap fraction is available.
2.6.0
Added
Added Qualifying Traffic, a 420 × 72 warning for push-lap or fast cars approaching from behind in qualifying and sprint shootouts.
Added catch-time and near-gap thresholds, course-order wrap handling, sticky threat handoff, player-push suppression, invalid-lap behavior and an optional uncertain FAST CAR tier.
Added confirmed push-lap outlines to the timing tower and both maps.
Added a complete settings tab, startup visibility and the ToggleQualifyingTraffic action.
2.5.1
Added
The native MoverlayF1 settings header now displays the version of the loaded assembly.
2.5.0
Added
Extended Start Helper with an optional Getaway phase after clutch release or first movement.
Added dry/wet/cold throttle guides, a shift zone and point, wheelspin-aware coaching, limiter/short-shift cues and graded upshifts.
Added new launch verdicts for late shifts, early shifts and timid throttle, plus time to full throttle and 0–200 km/h.
Expanded Start Report to six tiles and a per-shift strip.
Fixed
Restored verdict-specific text colours that were being overridden by the shared SVG stylesheet.
2.4.0
Added
Added per-session driver selection for both relative panels and the circle centre.
Race mode can use physical road neighbors with lap differences; practice and qualifying can use standings neighbors with best-lap gaps.
Time Trial can compare against personal-best and rival references, including assists, live split boundaries, a learned running-delta shape and a completed-lap hold.
Added selectable Automatic, Live, Last Lap and Fastest Lap sector clocks.
Added configurable fading for an empty side and the fully empty panel.
Changed
Tyre Prep now checks that enough fuel remains for a push lap and return lap before appearing automatically.
Leaderboard automatic/manual page selection skips pages that are irrelevant to the current session.
2.3.0
Added
Added Tyre Prep, with compound-specific carcass windows, four-corner temperatures, formation/out/prep-lap modes, pace and fuel rules, coaching and manual showing until the line.
Added Start Report, with reaction, clutch release, 0–100 km/h, grip, verdict, advice and recent session history.
Expanded Start Helper with clutch state, condition-aware dry/wet/cold rev bands, tyre/assist/ERS chips, release timing, bog-down detection and post-lights coaching.
Added dashboard picker images for every overlay and tooling to regenerate them.
Added optional garage hiding to Inputs, Track Map, Track Position Circle and Leaderboard.
Changed
Tyre Delta now shows the best spare-set delta on the fitted compound's row when another set is available.
2.2.0
Added
Added Tyre Delta for available-set pace comparisons and spare-set counts.
Added Tyre Life for measured or estimated laps to a configurable wear target.
Added Pit Window for the game's ideal/latest strategy lap, current compound and optional rejoin prediction.
Added native settings, properties, local routes and visibility actions for all three overlays.
2.1.0
Added
Added Weather Forecast with current/upcoming condition and rain-probability chips.
Added Race Control with a filtered queue for penalties, flags, retirements, safety car/VSC, DRS, fastest lap, speed trap, overtakes and other game events.
Added Inputs with a dedicated 60 Hz incremental trace feed plus pedals, steering, rev lights, DRS, gear and speed.
Added the original Start Helper with grid detection, start lights, launch rev target, reaction, jump-start and wheelspin feedback.
Added a startup visibility switch and bindable show/hide action for every overlay.
Replaced plain tyre rings in timing panels with compound glyphs.
2.0.0
Changed
Restyled the original map, circle, relative panels and Leaderboard around a consistent broadcast-inspired theme.
Added independently configurable map/circle marker interpolation at 15–60 fps and animated Leaderboard position changes.
Added optional team logos and clarified team-colour-bar settings.
Raised populated relative-panel polling to 10 Hz and the generated dashboard refresh cap to roughly 30 fps.
Split projection caches by view, streamed renderer JSON and reduced circuit, server and per-driver allocation work.
1.9.0
Added
Added the Leaderboard timing tower with twelve information pages, flag banners, row animation, tyre/ERS details, results and penalties.
Added grid/result status, leader/interval timing, penalties, warnings, pit stops, lap history averages, tyre summaries and flag/session properties.
1.8.1
Changed
Reduced renderer work by moving map markers and circle lines with grouped transforms and caching every written value.
Reduced projection precision where safe, reused server connections and metadata, and compiled property getters once.