[!TIP]
Don’t have an analog keyboard? See Keyboard Sim to simulate analog input with a regular keyboard and mouse.
Overview
Universal Analog Input bridges the gap between analog keyboards and games that don’t natively support them. It captures precise analog input from your keyboard and translates it into virtual gamepad controls, giving you smooth, proportional movement in any game that supports controllers.
Why Universal Analog Input?
Most games treat keyboard input as binary (pressed or not pressed), resulting in all-or-nothing movement. In racing games, for example, pressing a key means full acceleration or full steering, there’s no in-between. With analog keyboards, you can press keys partially, but most games don’t recognize this capability.
Universal Analog Input solves this by converting analog keyboard input into virtual gamepad controls — giving you smooth, proportional movement in any game that supports controllers. See Features for the full list of capabilities.
Build from Source
Alternatively, you can build from source:
**Requirements:**
- [.NET 9 SDK](https://dotnet.microsoft.com/download/dotnet/9.0)
- [Rust toolchain](https://rustup.rs/)
- [Visual Studio 2022](https://visualstudio.microsoft.com/) with Windows App SDK (optional, for UI development)
**Build Steps:**
```bash
# Clone the repository
git clone https://github.com/Ritonton/UniversalAnalogInput.git
cd universal-analog-input
# Build everything (Rust core + C# interface)
.\scripts\build.ps1
# Package for local distribution (creates UniversalAnalogInput.exe + published UI folder)
.\scripts\package.ps1 -SelfContained
# The executable will be in the output directory
```
Usage
Quick Start Guide
Connect Your Analog Keyboard
Plug in your keyboard before launching the app
Launch Universal Analog Input
Run UniversalAnalogInput.exe
The system tray icon will appear
The configuration interface opens automatically on first run
Verify your keyboard is detected in the app
Create Your First Profile
Click “New Profile” to create a game configuration
Name it after your game (e.g., “GTA V”)
Add sub-profiles if needed (e.g., “Driving”, “On Foot”)
Map Your Keys
Select a key from the “Supported Keys” list
Choose a gamepad control (stick, trigger, or button)
Configure response curve and dead zones in “Curves” tab
Click “Add Mapping”
Test Your Configuration
Switch to the “Tester” tab
Press your mapped keys and watch the gamepad visualization
Adjust curves and dead zones as needed
Start Playing
Click “Start Mapping” to activate your profile
Launch your game (it must support Xbox-style controllers)
The mapping runs in the background via the system tray
[!IMPORTANT]
Avoid key conflicts in your game’s settings. When UAI is active, your analog keys are translated into gamepad inputs. If your game also has those same keyboard keys bound to an action, the game will receive both a gamepad signal and a keyboard signal on the same action simultaneously, causing erratic behavior. To prevent this, go to your game’s key bindings and unbind any key you have mapped in UAI (set it to “None”), or reassign it to an unused key.
Profile Management
Creating Sub-Profiles
Sub-profiles are different mapping sets within a single game profile
Use them for different situations in the same game (e.g., driving vs. walking, flight vs. ground combat)
Example: GTA V with “On Foot” and “Driving” sub-profiles
Assign hotkeys to quickly switch between sub-profiles during gameplay
Import/Export Profiles
Share your configurations with the community
Click “Export Profile” to save as JSON
Click “Import Profile” to load shared configurations
Hotkeys
Assign a hotkey to cycle through sub-profiles
Set individual hotkeys for specific sub-profiles
Hotkeys work even when the interface is closed
Architecture
Universal Analog Input uses a hybrid architecture separating the core engine from the user interface.
Analog Data Flow
### From Key Press to Game Input
```mermaid
flowchart LR
KB["Analog Keyboard (Hall Effect switches 0.0–1.0 per key)"]
subgraph BRIDGE["Non-Wooting keyboards"]
direction TB
UAP["Universal Analog Plugin by AnalogSense"]
end
WSDK["Wooting Analog SDK (unified analog API)"]
subgraph UAI["Universal Analog Input"]
direction TB
DZ["Dead Zone Filter (inner & outer)"]
RC["Response Curve (linear or custom)"]
MAP["Key to Gamepad Mapping"]
DZ --> RC --> MAP
end
VIGEM["ViGEm Bus Driver (virtual Xbox controller)"]
GAME["Game (XInput or DirectInput)"]
KB -->|"raw analog values"| UAP
UAP -->|"normalized values"| WSDK
KB -->|"Wooting native direct path"| WSDK
WSDK -->|"per-key analog values"| UAI
UAI -->|"gamepad axis or button state"| VIGEM
VIGEM -->|"virtual controller"| GAME
style BRIDGE fill:#555,stroke:#888,stroke-width:1px,stroke-dasharray:4 4,color:#ccc
style UAI fill:#e67e22,stroke:#a85819,stroke-width:2px,color:#fff
style VIGEM fill:#9b59b6,stroke:#7d3c98,color:#fff
style WSDK fill:#27ae60,stroke:#1e8449,color:#fff
style GAME fill:#4a90e2,stroke:#2e5c8a,color:#fff
```
The **Universal Analog Plugin** is only needed for non-Wooting keyboards. Wooting keyboards communicate directly with the Wooting Analog SDK. In both cases, UAI receives the same normalized per-key values (0.0 – 1.0), applies dead zones and response curves, and forwards the result to ViGEm as a virtual Xbox controller that the game sees as a real gamepad.
Architecture Details
### Component Overview
```mermaid
flowchart TB
subgraph UI["WinUI 3 Config UI (C#)"]
PM["Profile Management"]
KM["Key Mapping Editor"]
RT["Real-time Tester"]
PM --- KM --- RT
end
IPC["IPC (Named Pipes)"]
subgraph Core["Rust Core Engine (System Tray)"]
WA["Wooting Analog SDK"] --> ME["Mapping Engine"]
ME --> VG["ViGEm Gamepad Emulation"]
PM2["Profile Management"]
HM["Hotkey Manager"]
RC["Response Curves"]
PM2 --- HM --- RC
end
UI <-->|JSON Payloads| IPC
IPC <-->|JSON Payloads| Core
style UI fill:#4a90e2,stroke:#2e5c8a,stroke-width:2px,color:#fff
style Core fill:#e67e22,stroke:#a85819,stroke-width:2px,color:#fff
style IPC fill:#95a5a6,stroke:#7f8c8d,stroke-width:2px,color:#fff
style WA fill:#27ae60,stroke:#1e8449,color:#fff
style ME fill:#e74c3c,stroke:#c0392b,color:#fff
style VG fill:#9b59b6,stroke:#7d3c98,color:#fff
linkStyle 0 stroke:transparent
linkStyle 1 stroke:transparent
linkStyle 4 stroke:transparent
linkStyle 5 stroke:transparent
```
### Technology Stack
**Rust Core Engine (`/native`)**
- High-performance input processing
- Wooting Analog SDK integration with plugin support
- ViGEm gamepad emulation
- IPC server for communication with UI
- System tray application
**C# Configuration Interface (`/ui`)**
- WinUI 3 for modern Windows interface
- Dependency injection with ServiceLocator pattern
- Real-time input visualization
- IPC client for communication with core
**Key Technologies**
- [Wooting Analog SDK](https://github.com/WootingKb/wooting-analog-sdk) - Analog keyboard input with plugin system
- [Universal Analog Plugin](https://github.com/AnalogSense/universal-analog-plugin) - Multi-keyboard compatibility
- [ViGEm](https://github.com/nefarius/ViGEmBus) - Virtual gamepad emulation
- [WinUI 3](https://docs.microsoft.com/windows/apps/winui/) - Modern Windows interface
- Rust + C# IPC - Separate processes communicating via Windows named pipes (JSON payloads)
[!NOTE]
For NuPhy, only keyboards in the HE (Hall Effect) line are supported — not all NuPhy keyboards. These are the models equipped with Hall Effect switches and the appropriate motherboard for analog output.
No Analog Keyboard? Use Keyboard Sim
Keyboard Sim lets you simulate analog input using a regular keyboard and mouse — no analog hardware required. You can try UAI, build profiles, and test mappings right away.
Hold any key and scroll the mouse wheel to set its analog value (0–100%). You can also enable Mouse mode to drive keys with physical mouse movement, binding each direction (Up / Down / Left / Right) to one or more keys.
Technical details and build instructions
### How it works
Keyboard Sim writes directly into the Wooting Analog Test Plugin shared memory. UAI reads from that same memory, so from its perspective the input is identical to a real analog keyboard.
### Usage
1. Launch **Universal Analog Input** first
2. Launch `keyboard-sim.exe` — it connects automatically
3. Build your profile in UAI as normal, using Keyboard Sim to produce the analog values
### Build from source
```bash
cd keyboard-sim
cargo build --release
# Output: keyboard-sim/target/release/keyboard-sim.exe
```
System Requirements
Minimum Requirements
Windows 10 version 1903 (build 19041) or later
Analog keyboard (Wooting or plugin-supported)
ViGEm Bus Driver installed
Wooting Analog SDK with plugin support
50 MB free disk space
100 MB RAM
Recommended Requirements
Windows 11 (latest version)
200 MB RAM for optimal performance
License
This project is licensed under the MIT License - see the LICENSE file for details.
For information about third-party dependencies and their licenses, see THIRD_PARTY_LICENSES.md.
Acknowledgments
Wooting - For the analog keyboard SDK and plugin system
AnalogSense - For the Universal Analog Plugin enabling multi-keyboard support
Nefarius - For the ViGEm virtual gamepad driver
Microsoft - For WinUI 3 and .NET
Rust Community - For excellent tooling and libraries
Known Issues
NavigationView crash when modifying profiles: Adding or deleting profiles can trigger a COMException (0x80004005) in WinUI 3’s NavigationView control. This is a known framework bug where dynamically clearing and re-adding navigation items corrupts the internal pane binding, causing the navigation pane to freeze. Tracked here: microsoft/microsoft-ui-xaml#10894
Important Notes
Xbox Controller Emulation Only: This application currently only supports Xbox-style controller emulation via ViGEm. PlayStation and other controller types are not supported yet
Game Compatibility: Your game must support Xbox controllers for this application to work
Privacy & Telemetry
Universal Analog Input includes optional error monitoring and crash reporting via Sentry.
Detailed Privacy Information
### Built from Source (Open-Source)
If you **build from source**:
- Sentry is **disabled by default** - you must set a DSN in the `.env` file to enable it
- Set `UI_SENTRY_DSN` and `NATIVE_SENTRY_DSN` environment variables to enable monitoring
- Leave them empty or unset to disable completely
### Official Releases (Distributed Binary)
If you **download the official release installer**:
- Sentry is **enabled by default** to help improve stability and fix bugs faster
- **No personal information (PII) is collected** (`send_default_pii: false`)
- Crash reports are sent to Sentry servers only when crashes occur
- You can **disable Sentry at any time** by editing or removing the `.env` file (see below)
### How to Disable Sentry in Official Release
Edit `%LOCALAPPDATA%\UniversalAnalogInput\.env`:
```bash
# Comment out or remove these lines to disable Sentry:
#UI_SENTRY_DSN=...
#NATIVE_SENTRY_DSN=...
```
Or simply delete the `.env` file entirely, the application will run without Sentry monitoring.
For full details, see [PRIVACY_POLICY.md](/UniversalAnalogInput/PRIVACY_POLICY.html) and [TERMS_OF_SERVICE.md](/UniversalAnalogInput/TERMS_OF_SERVICE.html).
Changelog
Current Version: 1.0.1 (January 14, 2026)
Latest Release Highlights
Sentry Integration - Automatic crash reporting (can be disabled)
Legal Documentation - GDPR-compliant privacy and terms
Improved Error Tracking - Better bug identification and fixing
Session Monitoring - Release health and stability metrics
See CHANGELOG.md for complete version history and upgrade guide.