I’ve purchased a used HTC Vive and I’ve been trying, for the past few days, to make SimulaVR work with it, using Copilot with Claude Sonnet 4 to help me make it work, as I don’t have a lot of free time to delve into how it works.
First I tried to install it on my Debian. Because SimulaVR was built with the NixOS in mind, I had to install the nix package manager and work through it. I faced several issues and came to the conclusion it would be best to attempt on a proper NixOS.
I’ve found an old 160 GB HD (not SSD) and I had a SATA to USB adapter so I installed NixOS in it. I’m using 25.11.8107.1073dad219cb-x86_64-linux. Not LTS, because I wanted to ensure I would have any package I might need.
I’ve installed SimulaVR in it. Because of some issues with their binary caches, I had to compile a lot of stuff. This was all done using the nix package manager, not make etc. I had to add some swap memory to do it.
After several days of back-and-forth with Copilot, I’ve managed to make Monado and Simula run, but I can’t get SimulaVR to run in the Vive. Copilot’s consensus seems to be that, while Monado starts in direct mode, Simula starts in X11 and they have trouble sharing contexts.
The best result I had was the following: Monado starts, the Vive turns on and displays a blank white screen. Simula starts, opens a window with a cloudy sky background and a terminal inside, which I can interact with, but I only see this on the laptop. On most other tests, either Simula crashes if Monado is up or starts in desktop mode only if Monado is down (commands used and output captured are attached at the end).
I got to the point where Copilot started suggesting me to
- Edit
~/.config/monado/config_v0.tomlto disable direct mode and etc. - Create
udevrules to force Monado to use X11 - Suggested to use WiVRn as an alternative OpenXR Runtime
- Using the AMD integrated graphics card instead of the nVidia GPU
- Using an LLVMpipe software renderer
- “Creating a custom Vulkan ICD that combines both drivers”
- Check for existing issues…
Now I strongly suspect that I shouldn’t be messing with such low-level stuff and that the solution is likely a lot simpler.
I’ve opened an issue in the SimulaVR repository and this is the reply that I got:
Sorry about this. @KaneTW and I haven’t used Simula with an HTV Vive in many years, so we can’t guarantee our fork of monado (simula-monado-service) will support it.
[…]
So it seems that it would not make sense to continue nagging them about it. They suggested me to attempt to use the original Monado, so I proceeded to do that.
Now I had to mess with make because Monado doesn’t have pre-compiled binaries I could use. Another several days with Copilot later, I managed to compile Monado and run it. However, this time, the Vive doesn’t turn on. Also, I get some different results out of attempting to run Simula.
Now Copilot was suggesting that either:
- Monado and Simula were running on separate OpenXR processes and should be ran in one integrated process
- Simula should launch Monado on its own
I think that I’ve reached the limit of how much Copilot can help me. So now my only hope is to reach out for people who are more capable than me in handling this kind of stuff.
Oh yeah, the Vive works just fine on Windows.
Does someone knows how can I make this work? If more information is needed, just ask and I’ll reply as soon as I can.
Thanks in advance.
Here are the logs using simula-monado-service:
__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia DRI_PRIME=1 simula-monado-service
(i’ve removed a lot of duplicate Warning: Could not find disambiguator state for HMD)
sudo -u vr DRI_PRIME=1 __NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia CAP_SYS_NICE=ep PATH=/run/current-system/sw/bin:$PATH simula
(I closed it with Super+Shift+Esc after I confirmed it was “working” in the laptop only)
Also, Monado only starts successfully once per login…
If I try to start Monado without the things suggested by Copilot, I get this:
simula-monado-service
And here are the logs using the Monado I compiled myself:
export LD_LIBRARY_PATH="/nix/store/cbifw447vv93ifvv1prqq9nrzi13jhwq-libjpeg-turbo-3.1.2/lib:/nix/store/2srsqvz4ghjcnn9xp7vs69iq3jrpz7f1-libtiff-4.7.1/lib:/nix/store/6lavn0jjgm8qmqpbam9bxg8r79inhbyi-libbsd-0.12.2/lib:/nix/store/bigkpra9jw48fip69q4wndsf4kb3d2w9-systemd-258.3/lib:/nix/store/fvp9ndylwa5z5ddvi6nns84q4r5mb8lz-hidapi-0.15.0/lib:/nix/store/3j0jwcygamiza2n1ga69sdk6skaz5k3k-zlib-1.3.2/lib:/home/vr/.local/lib64:/nix/store/vghr3ahlzfy9ji898lf1473yrnyyzv12-opencv-4.12.0/lib:/nix/store/db1178x260jvgvy94hb27xp395rr58fd-sdl2-compat-2.32.60/lib:/nix/store/08bph9k5m4xi8fsj9r057z7jbl18sk4-cjson-1.7.19/lib:/run/current-system/sw/lib/:$LD_LIBRARY_PATH"
export XR_RUNTIME_JSON=~/.local/share/openxr/1/openxr_monado.json
~/.local/bin/monado-service
(that Client 1 disconnected happened immediately after Client 1 connected, while Simula was still up and running)
export XR_RUNTIME_JSON=~/.local/share/openxr/1/openxr_monado.json
# export IPC_IGNORE_VERSION=1 # another Copilot suggestion, faired worse
simula
Here’s my /etc/nixos/configuration.nix:
{ config, pkgs, ... }:
{
imports = [ ./hardware-configuration.nix ];
# Boot configuration
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Enable experimental features for SimulaVR
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# Networking
networking.hostName = "simulavr-nixos";
networking.networkmanager.enable = true;
# Enable NVIDIA drivers with Wayland support
services.xserver.videoDrivers = [ "nvidia" ];
hardware.nvidia = {
modesetting.enable = true;
powerManagement.enable = false;
powerManagement.finegrained = false;
open = false;
nvidiaSettings = true;
package = config.boot.kernelPackages.nvidiaPackages.stable;
};
# Consolidated graphics configuration
hardware.graphics = {
enable = true;
enable32Bit = true;
extraPackages = with pkgs; [
mesa
vulkan-loader
vulkan-validation-layers
vulkan-extension-layer
vulkan-headers
vulkan-tools
libdrm
mesa_glu
freeglut
wayland
wayland-protocols
];
extraPackages32 = with pkgs.pkgsi686Linux; [
mesa
vulkan-loader
];
};
services.xserver = {
enable = true;
xkb = {
layout = "br";
variant = "abnt2";
};
};
services.displayManager.gdm = {
enable = true;
wayland = true;
};
services.desktopManager.gnome.enable = true;
console = {
keyMap = "br-abnt2";
};
i18n = {
defaultLocale = "en_US.UTF-8";
extraLocaleSettings = {
LC_TIME = "pt_BR.UTF8";
};
};
hardware.steam-hardware.enable = true;
services.udev.extraRules = ''
# HTC Vive headset
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bb4", ATTRS{idProduct}=="2c87", MODE="0664", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0bb4", ATTRS{idProduct}=="2c87", MODE="0664", GROUP="plugdev"
# Valve/Steam devices (base stations, controllers)
SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", ATTRS{idProduct}=="2000", MODE="0664", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", ATTRS{idProduct}=="2001", MODE="0664", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="28de", ATTRS{idProduct}=="2012", MODE="0664", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="28de", MODE="0664", GROUP="plugdev"
# General HTC devices
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bb4", MODE="0664", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0bb4", MODE="0664", GROUP="plugdev"
# Oculus devices (for compatibility)
SUBSYSTEM=="usb", ATTRS{idVendor}=="2833", MODE="0664", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fcf", MODE="0664", GROUP="plugdev"
# DRM access
SUBSYSTEM=="drm", KERNEL=="card[0-9]*", TAG+="seat", ENV{ID_SEAT}="seat0"
SUBSYSTEM=="drm", KERNEL=="controlD[0-9]*", TAG+="uaccess"
# VR specific settings
ATTRS{idVendor}=="0bb4", ATTRS{idProduct}=="2c87", ENV{VR_DIRECT_MODE}="false"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bb4", ATTRS{idProduct}=="2c87", ENV{XRT_COMPOSITOR_FORCE_WINDOWED}="1"
'';
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
users.groups.plugdev = {};
users.users.vr = {
isNormalUser = true;
description = "VR User";
extraGroups = [ "networkmanager" "wheel" "plugdev" "audio" "video" "render" "input" ];
};
environment.etc = {
"xdg/autostart/terminal.desktop" = {
text = ''
[Desktop Entry]
Type=Application
Name=Terminal
Exec=kgx
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
'';
};
"xdg/autostart/vscode.desktop" = {
text = ''
[Desktop Entry]
Type=Application
Name=VSCode
Exec=code
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
'';
};
"xdg/autostart/chrome.desktop" = {
text = ''
[Desktop Entry]
Type=Application
Name=Chrome
Exec=google-chrome-stable
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
'';
};
};
# Complete dependency list - added libmd for BSD compatibility
environment.systemPackages = with pkgs; [
# VR essentials
vulkan-tools
vulkan-loader
vulkan-validation-layers
# Monado core dependencies
cmake
python3
python3.pkgs.pip
python3.pkgs.numpy
python3.pkgs.scipy
vulkan-headers
libGL
libGL.dev
mesa
eigen
glslang
libusb1
libusb1.dev
systemd
systemd.dev
libv4l
libv4l.dev
# Critical missing dependencies
libcap
libcap.dev
libsysprof-capture
pcre2
pcre2.dev
libunwind
libunwind.dev
elfutils
elfutils.dev
zstd
zstd.dev
xz
xz.dev
# libsurvive specific dependencies
zlib
zlib.dev
libpcap
openblas
lapack
# X11 complete for libsurvive
xorg.libX11
xorg.libX11.dev
xorg.libxcb
xorg.libxcb.dev
xorg.xcbutil
xorg.xcbutilwm
xorg.xcbutilkeysyms
xorg.libXext
xorg.libXext.dev
xorg.libXrandr
xorg.libXrandr.dev
xorg.xorgproto
xorg.libXfixes
xorg.libXfixes.dev
xorg.libXau
xorg.libXau.dev
xorg.libXdmcp
xorg.libXdmcp.dev
xorg.libXrender
xorg.libXrender.dev
libGLU
libdrm
libdrm.dev
# Media libraries
libjpeg_original
libjpeg_original.dev
libjpeg_turbo
libjpeg_turbo.dev
libjpeg8
libjpeg8.dev
mozjpeg
opencv
libuvc
# OpenHMD and HIDAPI
openhmd
hidapi
# Bluetooth stack
bluez
bluez.dev
# Wayland complete
wayland
wayland.dev
wayland-protocols
wayland-scanner
libffi
libffi.dev
# GLib
glib
glib.dev
# SDL2
SDL2
SDL2.dev
# Additional utilities
doxygen
graphviz
cjson
# EGL support
libglvnd
libglvnd.dev
# GStreamer complete with ORC
gst_all_1.gstreamer
gst_all_1.gst-plugins-base
gst_all_1.gst-plugins-good
gst_all_1.gst-plugins-bad
gst_all_1.gst-plugins-ugly
orc
# D-Bus
dbus
dbus.dev
# BSD utilities - ADDED libmd for BSD compatibility
libbsd
libbsd.dev
libmd # Added missing libmd dependency
# OpenVR
openvr
# Build tools
git
ninja
meson
pkg-config
stdenv.cc
gcc
gnumake
glibc.dev
# System utilities
nano
wget
htop
pciutils
linuxPackages.nvidia_x11
usbutils
xorg.xrdb
wmctrl
i3status
firefox
xorg.xhost
vscode
google-chrome
];
# Enhanced environment variables - added libmd paths
environment.variables = {
PKG_CONFIG_PATH = pkgs.lib.concatStringsSep ":" [
"${pkgs.systemd.dev}/lib/pkgconfig"
"${pkgs.libusb1.dev}/lib/pkgconfig"
"${pkgs.bluez.dev}/lib/pkgconfig"
"${pkgs.libv4l.dev}/lib/pkgconfig"
"${pkgs.xorg.libX11.dev}/lib/pkgconfig"
"${pkgs.xorg.libXext.dev}/lib/pkgconfig"
"${pkgs.xorg.libXrandr.dev}/lib/pkgconfig"
"${pkgs.xorg.libxcb.dev}/lib/pkgconfig"
"${pkgs.xorg.libXfixes.dev}/lib/pkgconfig"
"${pkgs.xorg.xorgproto}/lib/pkgconfig"
"${pkgs.xorg.libXau.dev}/lib/pkgconfig"
"${pkgs.xorg.libXdmcp.dev}/lib/pkgconfig"
"${pkgs.xorg.libXrender.dev}/lib/pkgconfig"
"${pkgs.libGL.dev}/lib/pkgconfig"
"${pkgs.libdrm.dev}/lib/pkgconfig"
"${pkgs.wayland.dev}/lib/pkgconfig"
"${pkgs.SDL2.dev}/lib/pkgconfig"
"${pkgs.zlib.dev}/lib/pkgconfig"
"${pkgs.libjpeg_original.dev}/lib/pkgconfig"
"${pkgs.libjpeg_turbo.dev}/lib/pkgconfig"
"${pkgs.libjpeg8.dev}/lib/pkgconfig"
"${pkgs.libglvnd.dev}/lib/pkgconfig"
"${pkgs.libffi.dev}/lib/pkgconfig"
"${pkgs.dbus.dev}/lib/pkgconfig"
"${pkgs.libbsd.dev}/lib/pkgconfig"
"${pkgs.glib.dev}/lib/pkgconfig"
"${pkgs.libcap.dev}/lib/pkgconfig"
"${pkgs.libsysprof-capture}/lib/pkgconfig"
"${pkgs.pcre2.dev}/lib/pkgconfig"
"${pkgs.libunwind.dev}/lib/pkgconfig"
"${pkgs.elfutils.dev}/lib/pkgconfig"
"${pkgs.zstd.dev}/lib/pkgconfig"
"${pkgs.xz.dev}/lib/pkgconfig"
"${pkgs.orc}/lib/pkgconfig"
"${pkgs.libuvc}/lib/pkgconfig"
"${pkgs.gst_all_1.gstreamer.dev}/lib/pkgconfig"
"${pkgs.gst_all_1.gst-plugins-base.dev}/lib/pkgconfig"
];
CMAKE_PREFIX_PATH = pkgs.lib.concatStringsSep ":" [
"${pkgs.systemd.dev}"
"${pkgs.libusb1.dev}"
"${pkgs.vulkan-headers}"
"${pkgs.xorg.libX11.dev}"
"${pkgs.xorg.libxcb.dev}"
"${pkgs.xorg.libXfixes.dev}"
"${pkgs.xorg.xorgproto}"
"${pkgs.xorg.libXau.dev}"
"${pkgs.xorg.libXdmcp.dev}"
"${pkgs.xorg.libXrender.dev}"
"${pkgs.libGL.dev}"
"${pkgs.wayland.dev}"
"${pkgs.SDL2.dev}"
"${pkgs.libglvnd.dev}"
"${pkgs.glib.dev}"
"${pkgs.libcap.dev}"
"${pkgs.pcre2.dev}"
"${pkgs.libunwind.dev}"
"${pkgs.elfutils.dev}"
"${pkgs.zstd.dev}"
"${pkgs.xz.dev}"
"${pkgs.orc}"
"${pkgs.zlib.dev}"
"${pkgs.libjpeg_original.dev}"
"${pkgs.bluez.dev}"
"${pkgs.eigen}"
"${pkgs.openblas}"
"${pkgs.lapack}"
"${pkgs.libpcap}"
"${pkgs.libmd}" # Added libmd to CMAKE_PREFIX_PATH
];
# libsurvive specific paths
EIGEN3_ROOT = "${pkgs.eigen}";
EIGEN3_INCLUDE_DIR = "${pkgs.eigen}/include/eigen3";
OPENBLAS_ROOT = "${pkgs.openblas}";
LAPACK_ROOT = "${pkgs.lapack}";
LIBUSB_ROOT = "${pkgs.libusb1}";
LIBUSB_INCLUDE_DIR = "${pkgs.libusb1.dev}/include/libusb-1.0";
LIBUSB_LIBRARY = "${pkgs.libusb1}/lib/libusb-1.0.so";
ZLIB_ROOT = "${pkgs.zlib}";
ZLIB_INCLUDE_DIR = "${pkgs.zlib.dev}/include";
ZLIB_LIBRARY = "${pkgs.zlib}/lib/libz.so";
X11_ROOT = "${pkgs.xorg.libX11}";
X11_X11_INCLUDE_PATH = "${pkgs.xorg.libX11.dev}/include";
X11_X11_LIB = "${pkgs.xorg.libX11}/lib/libX11.so";
# Other CMake hints
HIDAPI_ROOT = "${pkgs.hidapi}";
OpenHMD_ROOT = "${pkgs.openhmd}";
EGL_ROOT = "${pkgs.libglvnd}";
OpenCV_ROOT = "${pkgs.opencv}";
OpenVR_ROOT = "${pkgs.openvr}";
bluetooth_ROOT = "${pkgs.bluez}";
# JPEG forcing
JPEG_ROOT = "${pkgs.libjpeg_turbo}";
JPEG_INCLUDE_DIR = "${pkgs.libjpeg_turbo.dev}/include";
JPEG_LIBRARY = "${pkgs.libjpeg_turbo}/lib/libjpeg.so";
};
nixpkgs.config.allowUnfree = true;
system.stateVersion = "23.11";
security.wrappers = {
"simula-monado-service" = {
source = "/home/vr/.nix-profile/bin/simula-monado-service";
capabilities = "cap_sys_nice+ep";
owner = "root";
group = "root";
};
};
}
and my /etc/nixos/hardware-configuration.nix
# Do not modify this file! It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usb_storage" "uas" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/7f49efe8-d667-473e-8f73-d6f10a76733c";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/5F71-EC96";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
I’m using an Acer Nitro 5 with AMD Ryzen 7-5800H and nVidia GTX 1650 (N20C1, AN515-45-R4S3).
Thanks again.