Skip to content

v0.11.0: One unified TrueForce stream, one-command setup, honest names

Choose a tag to compare

@mescon mescon released this 08 Jul 13:01

The headline for newcomers: installation is now one command.

git clone https://github.com/mescon/logitech-trueforce-linux-driver.git
cd logitech-trueforce-linux-driver
sudo ./tools/setup.sh

That handles the DKMS module, the in-tree driver blacklist, udev
permissions, module load, and (with the SDK DLLs staged) the TrueForce
shim for every Steam prefix, then finishes with a doctor that checks
every layer and names the fix for anything that is off. Re-run it after
a kernel update and it converges. ./tools/setup.sh doctor works any
time. Two things stay manual because they live inside Steam's own UI
(per-game PROTON_ENABLE_HIDRAW=1 and disabling Steam Input), and the
driver now heals the classic "settings need sudo until you replug"
udev race by itself.

A cleaner TrueForce texture stream

Cross-pollination with the Trueforce-For-All
project (a Windows SimHub plugin built on this project's protocol docs,
see issue #20) taught us that bytes 6-9 of a TrueForce stream packet are
the motor torque target, with the audio window playing additively on
top. The driver now streams one unified packet per tick, carrying
the steering force and the texture audio together, which is exactly the
shape AC EVO itself sends. Measured on the RS50: the same texture effect
couples 2.6x less into the steering axis than the previous
implementation, texture resolution doubled to a 2 kHz slot rate, and
texture amplitude is capped in the vibration regime so a synthetic
full-scale rumble can never hijack steering torque. Feel-verified on
RS50 hardware for this release: the texture route is a clean rim
vibration with a smooth start and stop, and a rumble layered on top of a
steady steering force leaves that force unchanged.

Every wheel gets its right name, and its right features

  • dmesg lines are tagged with the actual bound model: RS50 (native):,
    RS50 (G PRO compatibility mode):, or G PRO:. The compat tag
    doubles as a mode indicator when you are debugging.
  • Real G PRO owners: your rim's rev lights are now driveable from
    Linux (wheel_rev_level, 0 to 10), decoded from G HUB captures, and
    the RS50-specific per-LED RGB attributes no longer appear on your
    wheel (different rim, different protocol). Needs a tester: issue #8.
  • G923 owners: your wheel speaks the same TrueForce protocol, and
    the udev rule now grants the SDK hidraw access under Proton. Whether
    TrueForce actually arrives is the open question only you can answer:
    issue #27.

New settings you can drive from Linux

  • wheel_response_curve: the steering axis's 64-point response
    curve (feature 0x80A4, the store behind G Hub's Sensitivity slider).
    Write in:out pairs or reset. This was the last G Hub feature that
    was protocol-mapped but unimplemented. The upload path (open, 64-point
    resample, chunked commit, and revert) is confirmed on RS50 hardware;
    the in-game feel of a custom curve is not yet characterised, so treat
    the shape of a curve as experimental while field reports accumulate.
  • wheel_pedal_response_curve: the pedal unit's three axes get the
    same 64-point hardware curves (feature 0x80A4 on HID++ sub-device
    0x02). Untested on hardware; <axis> reset is the escape hatch.

Correct force strength on every wheel (libtrueforce)

libtrueforce previously scaled every torque request against the RS50's
8 Nm ceiling. On an 11 Nm G PRO that meant a request for 8 Nm mapped to
full scale, roughly 11 Nm actual, about 37% more force than asked for.
Peak torque is now resolved per model (RS50 8 Nm, G PRO 11 Nm), and the
capability getters report the right value. A real-hardware confirmation
of the G PRO figures is requested in issue #28. The library's udev rule
was also fixed: it only granted access for the RS50's USB ID, silently
locking G PRO owners out of libtrueforce without root; it now covers the
G PRO too. A non-finite (NaN) torque request from game code can no
longer slip past the clamp into an undefined motor command; it is
treated as zero force.

Fixes worth knowing about

  • Settings commands were stalling about 5 seconds each for one day
    on master (a device-index matching fix colliding with a transport
    quirk). Found via usbmon, fixed the same day; range writes now measure
    4 ms.
  • Unifying/Lightspeed mice and keyboards paired through a receiver
    briefly inherited the same stall through this fork's shared code path;
    fixed by scoping the check to the wheels it was written for.
  • Oversteer integration: the bundled patch now unlocks the full settings
    set (gain, autocenter, spring/damper/friction levels, combined pedals)
    for both G PRO product IDs, not just range.
  • Teardown and concurrency hardening from two adversarial review passes
    (use-after-free windows on unplug, stall guards between sync sends,
    gain-independent autocenter with a firmer centring curve), plus the
    removal of a large dead code path left over from before the G PRO
    moved onto the direct-drive engine.

Compatibility matrix status

RS50 verified across the board on real hardware, including this cycle's
reworked TrueForce stream and the response-curve upload path, in both
G PRO compatibility mode and native mode
(046d:c276). SDK-driven
game TrueForce under Proton was packet-confirmed in native mode too
(AC EVO, 2026-07-08, ~2 kHz type-0x01 stream on ep 0x03), so native
mode keeps game TrueForce while unlocking the full 2700 range: compat
mode is no longer required for TrueForce. Real G PRO is expected to work
(same code path) with two items awaiting an owner: rev lights and
texture-routing feel. G923: standard force feedback is unchanged via the
in-tree path; TrueForce is plausible but unverified. Full matrix in the
README.

Docs: the protocol spec (now docs/PROTOCOL_SPECIFICATION.md, v6.7)
gained the Windows-side FFB architecture (HID++ 0x8123 fn2), the
unified-packet semantics, and the G PRO rev-light protocol, with
attribution to the TF4ALL project, whose findings we validated in-kernel
and reciprocated on issue #20.