Visit the ControllerBuddy Homepage to get started.
Join the ControllerBuddy Discord for support and community discussions.
ControllerBuddy is an advanced gamepad mapping software that supports the creation of input profiles for complex target applications such as flight simulators.
In addition to the simple mapping of buttons and axes of a physical game controller to keyboard and mouse input, ControllerBuddy also supports feeding input commands to a virtual joystick device (vJoy/uinput).
ControllerBuddy eliminates the need for an expensive HOTAS setup to enjoy your favorite simulators. It gives you full control using just a gamepad - without even needing a keyboard or mouse.
For the easiest way to install and update, use the ControllerBuddy-Install-Script.
It automates all the steps below and much more!
Linux users may want to use the ControllerBuddy-Flatpak.
ControllerBuddy directory from the archive to any desired location on your hard-drive.ControllerBuddy.exe inside the extracted ControllerBuddy directory.sh
echo 'KERNEL=="uinput", SUBSYSTEM=="misc", TAG+="uaccess", OPTIONS+="static_node=uinput"' | sudo tee /etc/udev/rules.d/60-controllerbuddy.rulessh
echo uinput | sudo tee /etc/modules-load.d/controllerbuddy.confControllerBuddy directory from the archive to any desired location on your hard-drive.ControllerBuddy inside the extracted ControllerBuddy/bin directory.ControllerBuddy maps physical inputs to Actions, such as moving a virtual joystick axis, triggering a keystroke, or moving the mouse cursor.
Mappings are organized into Modes - distinct functional layers activated or toggled at the press of a button.
ControllerBuddy can be used as a standalone local tool or distributed over a network:
Profiles are JSON-based configuration files that tailor ControllerBuddy to specific games. Once loaded, they can be edited and saved through the built-in interface.
To manage complex setups, Profiles organize your input mappings into Modes. Think of Modes as different layers or "shift-states" for your controller.
Within each Mode, you can map an axis or button to one or more Actions.
By assigning different Actions to the same control across multiple Modes, you enable ControllerBuddy to instantly remap your controller as you switch between layers.
[!TIP] The ControllerBuddy-Profiles repository contains a vast collection of official profiles for many different flight simulators.
The general structure of a Profile looks as follows:
flowchart LR
profile[("Profile (.json file)")] ---- defaultMode
profile --- bButton(B Button) & xButton(X Button)
bButton --> bButtonModeAction[/Mode Action/] -. switch to .-> modeA
xButton --> xButtonModeAction[/Mode Action/] -. switch to .-> modeB
subgraph defaultMode[Default Mode]
direction LR
defaultModeXAxis(X Axis) --> defaultModeXAxisAction1[/Action 1/] & defaultModeXAxisAction2[/Action 2/]
defaultModeYAxis(Y Axis) --> defaultModeYAxisAction[/Action/]
defaultModeAButton(A Button) --> defaultModeAButtonAction1[/Action 1/] & defaultModeAButtonAction2[/Action 2/]
defaultModeYButton(Y Button) --> cycleAction[/Cycle Action/] -. perform next .-> cycleActions
defaultModeXAxis ~~~ cycleAction
defaultModeYAxis ~~~ cycleAction
defaultModeAButton ~~~ cycleAction
defaultModeYButton ~~~ cycleAction
subgraph cycleActions[Cycle]
cycleAction1[/Action 1/] --> cycleAction2[/Action 2/] --> cycleAction3[/Action 3/] --> cycleAction1
end
end
subgraph modeA[Mode A]
direction LR
modeAXAxis(X Axis) --> modeAXAxisAction[/Action/]
modeAAButton(A Button) --> modeAAButtonAction[/Action/]
end
subgraph modeB[Mode B]
direction LR
modeBXAxis(X Axis) --> modeBXAxisAction1[/Action 1/] & modeBXAxisAction2[/Action 2/]
end
classDef x-axis fill:#d5000055
classDef a-button fill:#ffd60055
classDef y-axis fill:#2962ff55
classDef b-button fill:#aa00ff55
classDef x-button fill:#ff6d0055
classDef y-button fill:#00c85355
class defaultModeXAxis,modeAXAxis,modeBXAxis x-axis
class defaultModeAButton,modeAAButton a-button
class defaultModeYAxis y-axis
class bButton b-button
class xButton x-button
class defaultModeYButton y-button
When switching between Modes, any axes or buttons not explicitly redefined will inherit their behavior from the previously active Mode.
This inheritance persists across multiple Mode levels, as illustrated by the following example:
Default Mode (Base) → Mode A (Layer 1) → Mode B (Layer 2)
If an axis or button is not mapped in Mode B, ControllerBuddy checks Mode A, and finally the Default Mode.
Two different switching behaviors can be configured:
flowchart
subgraph local[Local]
physicalController[Physical Controller] --> controllerBuddy[ControllerBuddy] --> vJoy[vJoy + Win32 / uinput] --> targetApplication[Target Application]
end
classDef bold font-weight:bold
classDef highlight fill:#448ade80
class local bold
class controllerBuddy highlight
flowchart LR
subgraph server[Server]
physicalController[Physical Controller] --> controllerBuddyServer[ControllerBuddy]
end
controllerBuddyServer -. UDP .-> controllerBuddyClient
subgraph client[Client]
controllerBuddyClient[ControllerBuddy] --> vJoy[vJoy + Win32 / uinput] --> targetApplication[Target Application]
end
classDef bold font-weight:bold
classDef highlight fill:#448ade80
class server,client bold
class controllerBuddyServer,controllerBuddyClient highlight

Modes Tab

Assignments Tab

Component Editor (Button)

Component Editor (Axis)

Overlay Tab (Dark Theme)

Visualization Tab

Overlay and On-Screen Keyboard
| Parameter | Arguments | Description | Available for scripting |
|---|---|---|---|
‑autostart |
local / client / server | starts the specified mode of operation after launch | yes |
‑export |
file destination | exports a visualization of the current profile to the specified path | yes |
‑gamecontrollerdb |
file source | adds the SDL controller mappings from the specified file | yes |
‑help |
prints the help and exits | no | |
-host |
hostname / IP address | sets the host address for outgoing network connections | yes |
-password |
password | sets the password for all network connections | yes |
-port |
port number | sets the server port for all network connections | yes |
‑profile |
file source | loads the specified profile after launch | yes |
‑quit |
quits the application | yes | |
‑save |
file destination | save the current profile to the specified path | yes |
‑skipMessageDialogs |
skips all message dialogs | no | |
-timeout |
timeout in milliseconds | sets the timeout in milliseconds for all network connections | yes |
‑tray |
launches the application to the system tray | yes | |
‑version |
prints the version information and exits | no |
If ControllerBuddy is already running, launching a second instance with any of the above parameters marked as available for scripting will forward the specified action to the first instance and then exit immediately.
This powerful mechanism allows seamless integration of ControllerBuddy into third-party applications.
For an example, see ControllerBuddy-DCS-Integration, which demonstrates how ControllerBuddy can be integrated into DCS World.
ControllerBuddy makes use of these awesome software technologies and libraries:
| Category | Techno
$ claude mcp add ControllerBuddy \
-- python -m otcore.mcp_server <graph>