What's new in this build
Build 168 of nx2 (68a945d) is build 167 plus exactly one change: rumble works in Switch 2 titles (PR #155 by @neoluigi4123, merged as 68a945d). Two files, 26 insertions, 6 deletions — everything else in this build is identical to 167, so nothing from that release's notes needs re-testing.
Nothing to configure: the emulator has always had a working vibration path (that is what Switch 1 titles use), and Switch 2 titles simply never reached it. If your controller can rumble, it rumbles now.
Switch 2 titles send their vibration into a stub
Switch 2 games send rumble with HID command 214, once per frame, carrying an array of vibration-device handles and an array of vibration values — the same shape as command 206, which Switch 1 titles use. Eden answered 214 with a stub that logged (STUBBED) called and returned success, so the values were dropped and every Switch 2 title was silent.
The handler now forwards each pair to the emulator's normal vibration path — the one 206 already used — so the values reach the controller through the same code as on Switch 1: device validity checks, the emulated device's mounted state, the game's vibration-master-volume, and then the host's rumble output (SDL rumble on a real pad).
What to expect, and what not to
- You need a controller with rumble, and the title has to mount a vibration device — every retail game that rumbles on hardware does this itself, and a game that never mounts one stays silent on hardware too.
- Tested on Mario Kart World on Windows 10 by the PR author. Everything else is untested territory; vibration on Linux, macOS, Joy-Cons and third-party pads should go through the same path as Switch 1 titles, but it has not been confirmed on those.
- The command's argument layout is still inferred from captures — the log name still says
SendNx2VibrationValues (guessed). That is deliberate: the handler never returns an error, so a title whose layout differs simply doesn't rumble, rather than failing in a way the game could treat as fatal. If a Switch 2 title rumbles on hardware and not here, that is the reason, and a report is useful. - A title that sets its own rumble volume to zero stays silent here too — the value is respected, not overridden.
How it works, for the technically curious
git diff build-167..build-168touches onlysrc/core/hle/service/hid/hid_server.cpp(+21/−2) andhid_server.h(+11/−4).SendNx2VibrationValues()wasLOG_DEBUG("(STUBBED) called"); R_SUCCEED();. It is nowSendNx2VibrationValues(u64 unknown, AppletResourceUserId aruid, InArray<VibrationDeviceHandle, BufferAttr_HipcPointer> handles, InArray<VibrationValue, BufferAttr_HipcPointer> values), registered at command 214 as before.- The body takes
count = min(handles.size(), values.size())—(std::min)in parentheses, because Windows defines aminmacro — and callsResourceManager::SendVibrationValue(aruid.pid, handles[i], values[i])per pair. Unlike 206 it does not reject a handle/value count mismatch and does not propagate errors; failures are logged at debug level so a game can never see a new error from a per-frame call.#include <algorithm>was added. - From there it is the existing path:
ResourceManager::SendVibrationValue→NpadVibrationDevice::SendVibrationValue(which returns early unless the device is mounted and active, and scales the amplitudes by the game's vibration volume) → the emulated controller → the host driver (SDL_RumbleGamepad). - Sizes:
VibrationDeviceHandleis 4 bytes,VibrationValueis 0x10 (four floats), both pinned bystatic_assert.
Automatic build of nx2 at 68a945d.
Linux
Linux packages come as an AppImage (self-contained, needs glibc 2.39 or newer: Ubuntu 24.04, Fedora 40, Debian 13, Arch) and a tar.gz (uses your system libraries, so Qt 6 and the usual libraries must be installed).
| Build Type | Standard | PGO (Recommended) | Notes |
|---|---|---|---|
| amd64 | AppImage · tar.gz | AppImage · tar.gz | Make the AppImage executable (chmod +x) and run it
|
| ARM (aarch64) | AppImage · tar.gz | AppImage · tar.gz |
Windows
Windows packages are in-place zip files: extract and run eglantine.exe, or eden-cli.exe from a terminal.
| Build Type | Standard | PGO (Recommended) | Notes |
|---|---|---|---|
| amd64 / x86_64 (MSVC) | MSVC zip | Use if you run into graphical issues on other builds | |
| amd64 / x86_64 (MinGW) | PGO zip | Built with MinGW clang; bundles its own DLLs, no Visual C++ redistributable needed |
macOS
| Build Type | Standard | PGO (Recommended) | Notes |
|---|---|---|---|
| arm64 (Apple Silicon) | zip | macOS 15 or newer. Not notarized: right-click and choose Open the first time, or run xattr -dr com.apple.quarantine eglantine.app. eden-cli is inside the app, in Contents/MacOS
|
The PGO builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it.