Skip to content

Add Moza FFB + ViGEm virtual gamepad integration#1

Draft
drowhunter with Copilot wants to merge 6 commits into
ffbfrom
copilot/start-planning-session
Draft

Add Moza FFB + ViGEm virtual gamepad integration#1
drowhunter with Copilot wants to merge 6 commits into
ffbfrom
copilot/start-planning-session

Conversation

Copilot AI commented Jul 19, 2026

Copy link
Copy Markdown

Implements the full FFB plan from plan.md: Moza wheel → force feedback from live telemetry, wheel input → ViGEm virtual Xbox 360 controller.

Architecture

FixedUpdate → TelemetryStateStore
           → WheelIntegrationRuntime.Update()
               ├── MozaWheelInputProvider.Poll()   → VirtualPadState → VigemXboxGamepadOutput
               └── FfbModel.Compute(telemetry)     → FfbCommand     → MozaWheelFfbProvider

New components

  • Config/WheelConfig.cs — BepInEx ConfigEntry<T> bindings for Wheel/General, Wheel/FFB, Wheel/Input; all live-tunable at runtime
  • Contracts/IWheelInputProvider, IWheelFfbProvider, IVirtualGamepadOutput; backend-agnostic for future DirectInput support
  • Moza/MozaSdkAdapter.cs — Single boundary around all MOZA SDK calls; uses dynamic for effect objects (HIDData is a reference type); wraps installMozaSDK/removeMozaSDK, getHIDData, createWheelbaseETDamper, createWheelbaseETConstantForce, stopForceFeedback
  • Moza/MozaWheelInputProvider.cs — Polls getHIDData each frame; normalises fSteeringWheelAngle to −1..1 with configurable deadzone/saturation; maps int16 pedal axes to 0..1
  • Moza/MozaWheelFfbProvider.cs — Manages two persistent DirectInput effects: ETDamper (continuous cForce resistance) + ETConstantForce (tire impulse bursts)
  • Ffb/FfbModel.cs — Computes FfbCommand per frame: cForce → damper coefficient with exponential smoothing; TireFR − TireFL → threshold-gated, cooldown-limited impulse magnitude
  • Output/VigemXboxGamepadOutput.cs — ViGEm Bus virtual Xbox 360 controller; steer → left stick X (full short range), throttle/brake → triggers
  • Runtime/WheelIntegrationRuntime.cs — Orchestrator: x64 guard, graceful degradation on partial init failures (FFB-without-pad and pad-without-FFB both handled), clean teardown

Plugin wiring (NewStarTelemetryPlugin.cs)

// Awake
_wheelConfig = new WheelConfig(Config);
if (_wheelConfig.Enabled.Value)
{
    _wheelRuntime = new WheelIntegrationRuntime(Logger);
    _wheelRuntime.Initialize(_wheelConfig);
}

// FixedUpdate (after existing telemetry)
_wheelRuntime?.Update(in data);

// OnDestroy
_wheelRuntime?.Dispose();

Dependencies added

  • Nefarius.VigemClient 1.22.40 (NuGet)
  • libs/moza/x64/MOZA_API_CSharp.dll (local reference, <Private>true</Private>)

Runtime requirements

Native DLLs MOZA_API_C.dll + MOZA_SDK.dll must be copied from libs/moza/x64/ into the game root directory. ViGEm Bus driver must be installed. MOZA Pithouz must be running.

Upgraded target framework to net48 and added Microsoft.CSharp reference.
Added references and build logic for MOZA_API_CSharp.dll, Nefarius.ViGEm.Client.dll, and native Moza DLLs.
Enhanced build to copy native DLLs to a x64 subfolder and set DLL search path at runtime for P/Invoke compatibility.
Improved logging for native DLL path setup.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants