#gamepad-input #joystick #gamepad

app ctrlassist

Controller Assist for gaming on Linux

2 unstable releases

Uses new Rust 2024

new 0.2.0 Dec 20, 2025
0.1.0 Dec 7, 2025

#73 in Game dev

Apache-2.0

45KB
821 lines

Banner

CtrlAssist brings "controller assist" functionality to Linux gaming by allowing multiple physical controllers to operate as a single virtual input device. This enables collaborative play and customizable gamepad setups, making it easier for players of all ages and abilities to enjoy games together. While similar features exist on modern game consoles, CtrlAssist is an open source project that enhances accessibility for PC gaming, offering additional quality-of-life improvements through virtual input devices on Linux.

Features

  • Combine physical controllers into one virtual gamepad
    • Controllers are assigned as either Primary or Assist
  • Customizable multiplexing modes for buttons and axes
    • Logically merging or preempting events is flexible
  • Hide physical controllers for improved game compatibility
    • Avoid controller interference from conflicting inputs
  • Spoof gamepad vendor for in-game layout recognition
    • Mimic either Primary or Assist controller hardware

Modes

  • Priority (default): Assist controller overrides when active
    • Axes: Prioritize when Assist exceeds deadzone
      • Buttons: OR'ed between controllers
    • Ideal for partial and asynchronous assistance
      • E.g. Assist for movement while Primary for actions
  • Average: Blend weighted inputs from both controllers
    • Axes: Averaged when both exceed deadzone
      • Buttons: OR'ed between controllers
    • Ideal for cooperative input and subtle corrections
      • E.g. For counter steer/brake assist in racing games
  • Toggle: Switch active controller on demand
    • All inputs forwarded from currently active controller
      • Toggle active controller via the Mode button on Assist
    • Ideal when fine-grain conflict-free control is needed
      • E.g. Game menu navigation or precise interventions

Prerequisites

  • Linux system using udev (libudev-dev)
    • with user permissions to manage virtual devices
    • already pre-configured on most distributions
  • Rust toolchain with included cargo

Install

cargo install ctrlassist

Usage

Use the --help flag for information on each CLI subcommand:

$ ctrlassist --help
Multiplex multiple controllers into virtual gamepad

Usage: ctrlassist <COMMAND>

Commands:
  list  List all detected controllers and respective IDs
  mux   Multiplex connected controllers into virtual gamepad
  help  Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version

list

List all detected controllers and respective IDs:

$ ctrlassist list
Detected controllers:
  ID: 0 - Name: Microsoft Xbox One
  ID: 1 - Name: PS4 Controller

mux

Multiplex first two detected controllers by default:

$ ctrlassist mux
Connected controllers:
  Primary: ID: 0 - Name: Microsoft Xbox One
  Assist:  ID: 1 - Name: PS4 Controller
  Virtual: ID: 2 - Name: CtrlAssist Virtual Gamepad

Optional: Specify Device Mapping

Manually specify Primary and Assist controllers via IDs:

$ ctrlassist mux --primary 1 --assist 0
Connected controllers:
  Primary: ID: 1 - Name: PS4 Controller
  Assist:  ID: 0 - Name: Microsoft Xbox One
  Virtual: ID: 2 - Name: CtrlAssist Virtual Gamepad

Optional: Specify Mux Mode

Manually specify mode for merging controllers:

$ ctrlassist mux --mode priority
...

Optional: Hide Physical Devices

Avoiding in game conflicts by hiding physical controllers:

$ sudo ctrlassist mux --hide
...

Hiding controllers... (requires root)

Assist mode active. Press Ctrl+C to exit.
^C
Shutting down.

Restoring controllers...

Optional: Spoof Virtual Device

Mimic controller hardware for in-game layout recognition:

$ ctrlassist mux --spoof primary
Connected controllers:
  Primary: ID: 0 - Name: Microsoft Xbox One
  Assist:  ID: 1 - Name: PS4 Controller
  Virtual: ID: 2 - Name: Microsoft X-Box One pad (Firmware 2015)

Limitations

  • Hiding physical input devices requires root access
    • temporarily modifies group permissions for selected devices
  • Hiding is by merely matching vendor and product IDs
    • Any controller with similar IDs may also be hidden
  • Hiding must be done before starting games or launchers
    • processes with open file handles may retain device access
  • Reconnecting a hidden controller reverts its visibility
    • custom udev rules should be used for persistent permissions

Background

Dependencies

~4.5–9MB
~175K SLoC