Nimbus Adaptive Controller is a free, open-source modular virtual controller for Windows. It transforms mouse input into virtual joystick commands via vJoy (DirectInput) or ViGEmBus (Xbox 360 XInput emulation).
Users build their own controller layout by dragging, dropping, and resizing widgets — joysticks, buttons, sliders, D-pads, and steering wheels — onto a customizable canvas. Every widget's axis mapping, sensitivity curve, deadzone, and button behavior is independently configurable.
Designed with accessibility in mind. Nimbus Adaptive Controller is a free software alternative to the Xbox Adaptive Controller, enabling people with mobility limitations to build custom controller layouts without expensive hardware. It works equally well for adaptive gaming, UAV/rover control via Mission Planner, or any application that expects joystick input.
Adaptive Platform 2 — modular drag-and-drop canvas: place joysticks, buttons, sliders, and D-pads anywhere on a fully customizable layout
Joystick Settings dialog with real-time sensitivity curve visualization, deadzone, and extremity deadzone controls
- Modular Layout Builder: Drag-and-drop canvas to place joysticks, buttons, sliders, D-pads, and steering wheels anywhere
- Dual Virtual Joysticks: Independent axis mapping with FPS-style delta tracking and tremor filtering for wheelchair joysticks
- Trigger/Slider Controls: Horizontal and vertical sliders with 3 snap modes (hold, snap-to-zero, spring-to-center)
- Button Support: Up to 128 configurable buttons with toggle/momentary modes, color and shape options
- Macro Joystick Mode: Convert any joystick into a macro pad — map directions to buttons, axes, or turbo actions
- Real-time Control: Low-latency input processing with 60 FPS update rate
- vJoy Integration: DirectInput with 8 axes (X,Y,Z,RX,RY,RZ,SL0,SL1) and 128 buttons
- ViGEm Integration: Xbox 360 XInput emulation for games that require XInput (No Man's Sky, etc.)
- Steam Input Support: Works with Steam Input for XInput-compatible games
- Axis Mapping Dialog: Configure which VJoy axes each control maps to
- Joystick Sensitivity Settings: Adjustable response curves with visual feedback and real-time graph display
- Rudder Sensitivity Settings: Dedicated sensitivity curves for rudder control with deadzone configuration
- Button Mode Configuration: Toggle between momentary and toggle modes for each button individually
- Individual Axis Locking: Lock X or Y axes independently on each joystick
- Auto-centering: Configurable auto-center behavior for rudder control
- JSON Configuration: Persistent settings stored in
controller_config.json
- Default Profile: Adaptive Platform 2 (modular canvas) opens on first launch
- Per-Profile Settings: Each profile stores its own joystick sensitivity, trigger sensitivity, button toggle modes, and full widget layout
- Automatic Save: Changes are automatically saved on every widget move, resize, or config change
- Save Profile As: Create new profiles with custom names and descriptions from the Widget Palette
- Portable Profiles: JSON-based profiles stored in user data directory for easy backup
- Custom Layout Type: The
customlayout type drives the modular canvas builder
- Qt Quick (PySide6 QML) UI: Dark-themed, resizable interface with smooth animations
- Menu System: File menu for profiles/settings; View menu with Size presets, Game Focus Mode, and Borderless Gaming
- Proportional Scaling: All UI elements scale via
controller.scaled()and View > Size presets; preference persists - Status Display: vJoy/ViGEm connection status and real-time value monitoring
- Keyboard Shortcuts: ESC to exit, SPACE to center
- Game Focus Mode: Prevents Nimbus Adaptive Controller from stealing focus from games (Windows only)
- Borderless Gaming: Auto-detect games, strip window borders, and continuously release cursor lock (View → Borderless Gaming)
The project was built with an accessibility-first philosophy. Instead of assuming users can handle conventional joysticks or gamepads, Nimbus allows mouse-driven or alternative inputs to control any software or hardware that supports vJoy.
This makes it especially valuable for:
- Users with mobility impairments who rely on mouse or adaptive devices
- Developers creating assistive technology solutions
- Hobbyists and researchers exploring human-computer interaction through unconventional inputs
- Anyone seeking alternative control schemes for specialized applications
- UAV and Rover Control: Bridge mouse input to Mission Planner and other MAVLink-compatible ground control software with professional-grade stability features
- Adaptive Gaming: Play joystick-only games using a mouse-first input scheme with customizable sensitivity
- Research and Prototyping: Explore new input models for robotics, simulation, or accessibility tools with comprehensive configuration options
- Assistive Technology: Provide joystick functionality for users who cannot operate traditional controllers
- Borderless Gaming: Use Nimbus Adaptive Controller alongside borderless gaming for seamless full-screen gaming with simultaneous mouse and joystick control
Nimbus Adaptive Controller includes built-in borderless gaming integration — no external tools needed.
How to use:
- Go to View → Borderless Gaming...
- Click "Scan for Games" — it auto-detects known games from the compatibility database
- Select your game window, then click "Apply Borderless + Free Cursor" (the green button)
- Your game fills the screen borderless, and your cursor is continuously freed so you can reach Nimbus
- Click "Restore Window & Stop" when done
What it does:
- Strips window decorations and resizes the game to fill your monitor (borderless windowed mode)
- Continuously releases ClipCursor confinement so the game cannot lock your mouse to its window
- Auto-detects 30+ games from a built-in compatibility database (see Compatibility tab in the dialog)
- Adjustable release speed — tune the cursor release interval from 16ms (aggressive) to 200ms (gentle)
Game compatibility: Verified with Minecraft, Stardew Valley, Terraria, Skyrim and many others. See docs/GAME_COMPATIBILITY.md for the full list.
When playing games that pause or lose input when unfocused, enable Game Focus Mode to keep your game running while interacting with Nimbus Adaptive Controller.
How it works:
- Go to View > Game Focus Mode to enable
- When you click on Nimbus Adaptive Controller, it briefly takes focus to register your input
- When you release the mouse, focus is automatically restored to the previous window (your game)
Technical details:
- Uses Windows API (
SetForegroundWindowwithAttachThreadInput) to restore focus - Works with most games, though some that pause instantly on focus loss may still notice the brief switch
- Setting is saved and persists across sessions
Note: This feature is only available on Windows. On other platforms, the menu option will be disabled.
Nimbus Adaptive Controller is evolving beyond a virtual controller into a broader adaptive input platform. The following directions are actively being explored and documented.
Speak to control. Buttons, axes, and macros triggered by voice — using offline engines (Faster-Whisper, Vosk) for low latency and privacy, or cloud engines for higher accuracy. Goal: act on interim results for time-critical commands.
"You direct. The AI executes." An accessibility-first AI copilot: the user provides high-level intent (via voice, click, or switch), and a trained agent handles precise execution through the existing vJoy/ViGEm bridge. Designed for users who have the cognitive engagement to play but not the fine motor precision.
Any Nimbus button or slider emits native keyboard shortcuts to any application — Photoshop, DaVinci Resolve, OBS, a browser — with no external software. Enables Nimbus as a Stream Deck replacement, a drawing tablet express key surface, or a DAW controller.
Nimbus can wrap existing adaptive hardware — Xbox Adaptive Controller, QuadStick, foot pedals, head trackers — reading their input via XInput/DirectInput and re-emitting through vJoy with Nimbus's sensitivity curves, macros, and voice layer applied on top.
The same customizable button surface that controls a game can output spoken phrases via text-to-speech, navigate AAC vocabulary pages, or trigger keyboard shortcuts in dedicated AAC software. Switch access and eye gaze (Windows Eye Control already works with Nimbus today) are natural extensions.
With opt-in telemetry, Nimbus could become a research instrument for understanding how people with disabilities play, in partnership with AbleGamers, Shirley Ryan AbilityLab, CMU HCII, and others.
Nimbus as a universal adaptive input layer for video editing, music production, streaming, and any Windows application. Pre-built profiles for DaVinci Resolve, Photoshop, Ableton, OBS. Auto-switch profiles by active window.
Nimbus Adaptive Controller is and will remain free for all accessibility use. The core — all layouts, vJoy/ViGEm, profiles, custom builder — is MIT-licensed and free forever. Advanced features (voice, AI, cloud sync) may be offered optionally in future to sustain development.
-
Download the latest release:
- Go to Releases
- Download
Nimbus-Adaptive-Controller-Setup-<version>.exe(installer) orNimbus-Adaptive-Controller-<version>.exe(portable)
-
Install the ViGEmBus driver (for Xbox/XInput emulation — recommended):
- Download from ViGEmBus Releases
- Run the installer, reboot if prompted
-
Install VJoy Driver (optional — for DirectInput / legacy games):
- Download and install from VJoy Official Site
- Configure VJoy device #1 with at least 6 axes (X, Y, Z, RX, RY, RZ)
-
Run the application:
- Run the installer, or double-click the portable
.exe - No Python installation required!
- Run the installer, or double-click the portable
- Python 3.8+ - Required for the application
- VJoy Driver - Download and install from VJoy Official Site
- Git (optional) - For cloning the repository
-
Clone or download the project:
git clone https://github.com/owenpkent/Nimbus-Adaptive-Controller.git cd Nimbus-Adaptive-Controller -
Install Python dependencies:
pip install -r requirements.txt
-
Configure VJoy:
- Install VJoy driver
- Configure VJoy device #1 with at least 6 axes (X, Y, Z, RX, RY, RZ)
- Ensure VJoy device is enabled and available
-
Run the application (Qt Quick UI):
python run.py
Notes:
- The Qt Quick (QML) UI is the default and primary UI.
- Settings persist via
controller_config.json.
See build_tools/BUILD_EXECUTABLE.md for detailed instructions on creating a standalone Windows executable using PyInstaller.
- Mouse Drag: Click and drag within joystick circles to control position
- Throttle Slider: Vertical slider for throttle control (does not auto-center)
- Rudder Slider: Horizontal slider for rudder control (auto-centers when released)
- Lock Buttons: Click "Lock X" or "Lock Y" to lock individual axes on each joystick
- Joystick Buttons: 8 configurable buttons (1-4 on left, 5-8 on right) with toggle/momentary modes
- ARM Button: Configurable ARM button (button 9) with toggle/momentary mode
- RTH Button: Configurable Return to Home button (button 10) with toggle/momentary mode
- File > Profile: Switch between profiles or create new ones
- File > New Profile...: Create a blank new profile with a custom name
- File > Recent Profiles: Quickly switch to one of the last 5 used profiles
- File > Save Profile / Save Profile As...: Save current settings to profile
- File > Settings: Consolidated settings submenu
- Joystick Sensitivity: Configure sensitivity curves for joysticks
- Trigger Sensitivity: Sensitivity curves for trigger/slider controls
- Axis Mapping: Assign UI controls to vJoy axes
- Button Modes: Configure toggle/momentary modes for buttons
- View > Game Focus Mode: Keep game focused while using Nimbus (Windows)
- View > Borderless Gaming...: Strip game window borders and continuously release cursor lock
- ESC: Exit application (or close open dialogs)
- F1: Toggle debug information display
- SPACE: Center both joysticks
- C: Open axis configuration dialog
- VJoy Connection: Shows VJoy driver connection status in real-time
- Real-time Values: Current joystick positions and processed values
- Lock Status: Visual indicators showing which axes are locked
Nimbus Adaptive Controller uses a profile system to save and manage different controller configurations. Each profile stores its own sensitivity curves, deadzones, button settings, and layout type.
Profiles are stored in your user data directory for easy access and backup:
| Platform | Location |
|---|---|
| Windows | %APPDATA%\ProjectNimbus\profiles\ |
| macOS | ~/Library/Application Support/ProjectNimbus/profiles/ |
| Linux | ~/.local/share/ProjectNimbus/profiles/ |
Quick Access: Use File > Open Profiles Folder... to open the profiles directory in your file explorer.
Each profile is a JSON file containing:
- name: Display name shown in the menu
- description: Optional description of the profile
- layout_type: UI layout (
flight_sim,xbox,adaptive, orcustom) - joystick_settings: Sensitivity, deadzone, extremity deadzone
- rudder_settings: Rudder-specific sensitivity settings
- buttons: Button labels and toggle modes
- axis_mapping: VJoy axis assignments
- custom_layout: (custom type only) Widget array with positions, sizes, and mappings
To back up your profiles:
- Open File > Open Profiles Folder...
- Copy the
.jsonfiles to your backup location - To restore, copy them back to the profiles folder
One profile is included by default:
- Adaptive Platform 2: Modular drag-and-drop controller builder — place joysticks, buttons, and sliders anywhere on a customizable canvas. Opens automatically on first launch.
You can create unlimited custom profiles using File > Save Profile As... from the Widget Palette, and open the profiles folder via File > Open Profiles Folder....
The application uses a JSON-based configuration system stored in controller_config.json. Auto-generated on first run with sensible defaults.
{
"joysticks": {
"left": {
"dead_zone": 0.1,
"sensitivity": 1.0,
"curve_type": "linear",
"curve_power": 2.0,
"invert_x": false,
"invert_y": false,
"max_range": 1.0
}
}
}{
"safety": {
"enable_failsafe": true,
"failsafe_timeout": 5.0,
"max_update_rate": 100,
"enable_smoothing": true,
"smoothing_factor": 0.1
}
}The Joystick Settings dialog provides comprehensive control over joystick response:
- Sensitivity (0-100%): Controls the steepness of the response curve
- 50% = Linear response
- <50% = Flatter curve (less sensitive, more precise)
-
50% = Steeper curve (more sensitive, faster response)
- Deadzone (0-100%): Creates a dead area around center where small movements are ignored
- Extremity Deadzone (0-100%): Prevents reaching absolute maximum values at the edges
- Real-time Graph: Visual representation of the sensitivity curve with deadzone indicators
Identical functionality to Joystick Settings but specifically for rudder control:
- Independent sensitivity curve configuration
- Separate deadzone and extremity deadzone settings
- Real-time visual feedback of the response curve
- Settings are applied immediately to rudder input
Configure the behavior of all 10 buttons:
- Toggle Mode: Button stays "pressed" until clicked again (green indicator)
- Momentary Mode: Button is only active while being held down (red indicator)
- Visual Feedback: Color-coded switches show current mode at a glance
- Individual Configuration: Each button (1-8, ARM, RTH) can be set independently
The sensitivity curve system provides precise control over input response:
- Linear (50%): Direct 1:1 response
- Flatter Curves (<50%): More precise control near center, exponential scaling
- Steeper Curves (>50%): Faster response near center, logarithmic scaling
- Deadzone Integration: Curves work seamlessly with deadzone settings
- Real-time Preview: See exactly how your settings affect the response curve
Nimbus-Adaptive-Controller/
├── qml/ # QML UI (Qt Quick)
│ ├── Main.qml # Main window, menus, layout loader
│ ├── layouts/ # Layout QML files
│ │ ├── FlightSimLayout.qml # Dual joysticks + throttle/rudder
│ │ ├── XboxLayout.qml # Standard Xbox gamepad
│ │ ├── AdaptiveLayout.qml # Accessibility-focused fixed layout
│ │ └── CustomLayout.qml # Modular drag-and-drop canvas
│ └── components/ # Reusable QML controls
│ ├── Joystick.qml # Virtual joystick
│ ├── DraggableWidget.qml # Drag/resize wrapper for any widget
│ ├── WidgetPalette.qml # Sidebar toolbar for adding widgets
│ ├── SliderVertical.qml # Throttle slider
│ ├── SliderHorizontal.qml # Rudder slider
│ ├── NumberPad.qml # Button grid
│ ├── BorderlessGamingDialog.qml # Borderless gaming & cursor release UI
│ └── MacroEditorDialog.qml # Macro joystick zone editor
├── src/
│ ├── qt_qml_app.py # QML application entry
│ ├── bridge.py # Python↔QML bridge (ControllerBridge)
│ ├── config.py # Configuration & profile management
│ ├── qt_dialogs.py # Qt Widgets settings dialogs
│ ├── vjoy_interface.py # vJoy driver interface (8 axes, 128 buttons)
│ ├── vigem_interface.py # ViGEm Xbox 360 controller emulation
│ ├── window_utils.py # Game Focus Mode (Windows API)
│ ├── borderless.py # Borderless gaming & cursor release
│ └── legacy/ # Legacy pygame UI (reference only)
├── profiles/ # Bundled profile JSON files
│ └── adaptive_platform_2.json # Default modular custom layout
├── docs/ # Documentation
│ ├── GAME_COMPATIBILITY.md # Borderless gaming game list
│ ├── architecture/ # Technical architecture docs
│ ├── development/ # Developer & AI assistant notes
│ ├── setup/ # Installation & packaging guides
│ └── accessibility/
├── build_tools/ # PyInstaller build system
├── research/ # Research notes
├── run.py # Launcher with venv + dependency checks
├── run.bat # Windows batch launcher
├── requirements.txt # Python dependencies
├── controller_config.json # Runtime settings (auto-generated)
├── logo.png
├── docs/screenshots/
├── tests/
└── README.md
- Migrated UI to Qt Quick (PySide6 QML) with a dark top menu bar.
- Standardized sizes using
controller.scaled(...)for consistent, DPI-aware scaling. - Joystick, throttle, rudder input behavior:
- No jump-to-click; dragging is relative.
- Joystick and rudder smoothly return to center on release; throttle does not auto-center.
- Throttle widened; rudder taller; refined animations.
- NumberPad and ARM/RTH buttons use dark styling with blue pressed/checked state.
- Optional debug borders for layout tuning.
Manages communication with the VJoy driver including:
- Device initialization and management
- Axis value updates
- Failsafe monitoring
- Error handling and recovery
Configuration management system providing:
- JSON-based configuration storage
- Sensitivity curve processing
- Dead zone calculations
- Configuration validation
- Automatic Activation: Triggers if no commands received within timeout period
- Emergency Stop: Manual emergency stop button
- Axis Centering: Automatically centers all axes during failsafe
- Visual Indicators: Clear status display when failsafe is active
- Update Rate Control: Prevents excessive update rates
- Safety Limits: Hard limits on maximum update frequency
- Smooth Operation: Ensures stable operation under all conditions
- VJoy Connection Monitoring: Continuous monitoring of VJoy driver status
- Graceful Degradation: Continues operation even if VJoy is unavailable
- Comprehensive Logging: Detailed error reporting and status information
- Ensure VJoy driver is properly installed
- Check that VJoy device #1 is configured and enabled
- Verify VJoy device has sufficient axes configured
- Run application as administrator if needed
- Check
update_ratesetting in configuration - Reduce
smoothing_factorfor more responsive control - Verify system performance and close unnecessary applications
- Increase
dead_zonevalues in configuration - Check for hardware interference (other controllers)
- Verify mouse sensitivity settings
Press F1 to enable debug mode, which displays:
- Current configuration values
- Update rates and timing information
- Detailed joystick position data
- VJoy driver status
- PEP 8 Compliance: All code follows Python PEP 8 style guidelines
- Type Hints: Comprehensive type annotations for better code clarity
- Documentation: Detailed docstrings for all classes and methods
- Error Handling: Robust error handling throughout the application
- Configuration Validation: Built-in configuration validation
- Failsafe Testing: Comprehensive failsafe system testing
- Edge Case Handling: Proper handling of edge cases and error conditions
- Custom Sensitivity Curves: Easy to add new curve types
- Additional Input Methods: Framework supports multiple input types
- Plugin Architecture: Modular design allows for easy extensions
An optional Qt Widgets-based shell is available for experimentation:
src/qt_main.py: Alternative interface implemented with Qt Widgets. It is not used by the default launcher and is not maintained at feature parity with the QML UI. The primary UI remains the Qt Quick (QML) app launched viarun.py.
Legacy pygame-based UI and dialogs are kept under src/legacy/ for reference only and are not used by the QML app launched via run.py.
The Adaptive Platform 2 profile (included with Nimbus Adaptive Controller) introduces a modular controller builder where users can design their own controller layout:
- Open Adaptive Platform 2 (loads automatically on first launch)
- Click "Edit Layout" (bottom-right corner) to enter edit mode
- Drag widgets to reposition, corner handle to resize, × to delete
- Double-click any widget to configure (label, axis mapping, button ID, color)
- Use the Widget Palette sidebar to add new joysticks, buttons, or sliders
- Click "Done Editing" to save and return to play mode
| Widget | Description |
|---|---|
| Joystick | 2-axis analog stick with triple-click mouse lock (maps to any axis pair) |
| Button | Single press with toggle/momentary support and color/shape options (maps to any vJoy button 1-128) |
| Slider | Single-axis analog control with horizontal/vertical orientation and 3 snap modes: hold position, snap to zero, snap to center |
| D-Pad | 4-directional digital button cluster with auto-assigned button IDs |
| Steering Wheel | Rotational single-axis input with spoke indicator |
| Backend | Axes | Joysticks | Buttons |
|---|---|---|---|
| vJoy | 8 (X,Y,Z,RX,RY,RZ,SL0,SL1) | Up to 4 | Up to 128 |
| ViGEm (Xbox) | 4 + 2 triggers | 2 | 14 |
See docs/development/WIDGET_IDEAS.md for planned accessibility widgets including dwell buttons, scan mode strips, steering wheels, and more.
See docs/architecture/ for detailed technical documentation of the custom layout system.
See CHANGELOG.md for the full version history.
Contributions are welcome! To get started:
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Make your changes — follow existing code style, add docstrings for new functions
- Run tests:
python -m pytest tests/ - Submit a pull request with a clear description
For larger changes or new feature ideas, open an issue first to discuss approach.
See docs/development/INTEGRATION_GUIDE.md for architecture notes useful for contributors.
MIT License — see LICENSE for details. Free for all use including accessibility and educational purposes.
Nimbus Adaptive Controller


