Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d88eead
Fix atomic writes and exhausted download cleanup on Windows
Villagers654 Sep 2, 2026
fc42c48
Add experimental native Windows CLI, library GUI, and host tests
Villagers654 Sep 2, 2026
b8f78b9
Add Windows installer, launcher, CI, and explicit game-test status
Villagers654 Sep 2, 2026
d593294
Normalize Windows checkout text to repository LF line endings
Villagers654 Sep 2, 2026
79abba4
Reuse the existing Linux UI on Windows and remove replacement window
Villagers654 Sep 2, 2026
40bec22
Integrate Windows into product metadata and remove separate experimen…
Villagers654 Sep 2, 2026
bd891d4
Fix native VR bridges and add simulated-headset diagnostics
Villagers654 Sep 3, 2026
38cb5ee
Support Windows browser sign-in and packaged callback routing
Villagers654 Sep 3, 2026
e35cb71
Enable Windows game downloads and automatic native runtime launches
Villagers654 Sep 3, 2026
03cf085
Polish Windows library controls and reuse the existing app window
Villagers654 Sep 3, 2026
04ba14d
Build a self-contained Windows app and per-user installer
Villagers654 Sep 3, 2026
b814839
Document Windows installation and separate compatibility results by OS
Villagers654 Sep 3, 2026
08fb11b
Fix Meta sign-in handoff on Windows
Villagers654 Sep 26, 2026
3ac00d3
Merge remote-tracking branch 'origin/main' into windows-native
Villagers654 Sep 27, 2026
a860da6
Use reachable pinned Meta runtime download host
Villagers654 Sep 27, 2026
9b72eeb
Fix Windows game downloads with long temporary paths
Villagers654 Sep 30, 2026
f3406af
License RiftLift under MIT
Villagers654 Oct 5, 2026
3f63ae8
Keep component notices separate from the MIT grant
Villagers654 Oct 5, 2026
96bd1e6
Merge main into windows-native
Villagers654 Oct 8, 2026
fa1fc93
Merge branch 'main' into windows-native
Villagers654 Oct 8, 2026
0046ac2
Merge branch 'main' into windows-native
Villagers654 Oct 9, 2026
64806c1
Merge branch 'main' into windows-native
Villagers654 Oct 9, 2026
d262661
Merge branch 'main' into windows-native
Villagers654 Oct 9, 2026
c23e21c
Merge branch 'main' into windows-native
Villagers654 Oct 9, 2026
68c6d2e
Merge branch 'main' into windows-native
Villagers654 Oct 9, 2026
b7510e0
Run OVRPlugin games on Windows and unblock the installer build
Villagers654 Oct 9, 2026
4d271bc
Polish the installed Windows app
Villagers654 Oct 9, 2026
e3a5fd0
Document Windows installer results and the SmartScreen prompt
Villagers654 Oct 9, 2026
a32c68c
Fix controller-time crashes and keep the OpenXR path runtime neutral
Villagers654 Oct 9, 2026
0d4eb56
Broaden OpenXR swapchain fallbacks and add opt-in crash dumps
Villagers654 Oct 9, 2026
6a9745b
Serialize OpenVR event polling with controller input
Villagers654 Oct 9, 2026
2ac6762
Record controller-tested Windows results
Villagers654 Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ jobs:
cmake -S windows-openvr/tests -B windows-openvr/tests/build -A x64 -DOVR_INCLUDE_DIR="$pwd/Externals/LibOVR/Include"
cmake --build windows-openvr/tests/build --config Release
ctest --test-dir windows-openvr/tests/build -C Release --output-on-failure
- name: Build the simulated Touch controller test driver
shell: pwsh
run: |
cmake -S tests/steamvr-touch-sim -B tests/steamvr-touch-sim/build -A x64
cmake --build tests/steamvr-touch-sim/build --config Release
if (-not (Test-Path tests/steamvr-touch-sim/build/riftlift_touchsim/bin/win64/driver_riftlift_touchsim.dll)) { throw 'Touch simulator driver missing' }
- name: Install native dependencies
shell: pwsh
run: |
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ permissions:
contents: read

jobs:
windows-app:
uses: ./.github/workflows/windows-package.yml

python-release:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -229,10 +232,14 @@ jobs:
riftlift-compat.zip.sha256

release-bundle:
needs: [python-release, compatibility, xrizer, dxvk, appimage]
needs: [python-release, compatibility, xrizer, dxvk, windows-app, appimage]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/download-artifact@v5
with:
name: riftlift-windows-installer
path: release
- uses: actions/download-artifact@v5
with:
name: riftlift-python-release
Expand Down Expand Up @@ -260,7 +267,7 @@ jobs:
version=$(PYTHONPATH=src python -c 'from riftlift import __version__; print(__version__)')
tag=$(python -c 'import re,sys; value=sys.argv[1]; match=re.fullmatch(r"(\d+(?:\.\d+){2,3})(?:a(\d+))?", value); assert match; print(f"v{match.group(1)}" + (f"-alpha.{match.group(2)}" if match.group(2) else ""))' "$version")
scripts/generate-release-installer.sh "$tag" release release/riftlift-installer.sh
(cd release && sha256sum riftlift-* > SHA256SUMS)
(cd release && sha256sum riftlift-* RiftLift-Setup-*.exe > SHA256SUMS)
(cd release && sha256sum -c SHA256SUMS)
bash -n release/riftlift-installer.sh
grep -F "release_tag='$tag'" release/riftlift-installer.sh
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/windows-host.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Windows
on:
push:
pull_request:
jobs:
windows-host:
runs-on: windows-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: python -m pip install -e . pytest
- run: python -m riftlift.cli --help
- run: python -m pytest tests/test_windows_package.py tests/test_windows_native.py tests/test_playtime.py tests/test_util.py tests/test_library.py tests/test_platform_exports.py -q
env:
QT_QPA_PLATFORM: offscreen
72 changes: 72 additions & 0 deletions .github/workflows/windows-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Windows installer

on:
workflow_dispatch:
workflow_call:
pull_request:
paths:
- '.github/workflows/windows-package.yml'
- 'scripts/*windows*'
- 'src/riftlift/**'
- 'runtime/**'
- 'compat/**'
- 'pyproject.toml'

permissions:
contents: read

jobs:
package:
runs-on: windows-2022
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- run: python -m pip install . pyinstaller==6.22.0 pefile ninja cmake pytest
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Fetch pinned native dependencies
shell: bash
run: |
scripts/prepare-runtime-ci-deps.sh
git clone https://github.com/microsoft/Detours.git build/Detours
git -C build/Detours checkout e4bfd6b03e50de46b47abfbd1e46b384f0c5f833
git clone https://github.com/KhronosGroup/OpenXR-SDK.git build/OpenXR-SDK
git -C build/OpenXR-SDK checkout 8899a91c17ce9618f565f42408b47db1d6e9ccc7
- name: Prepare signed SDK files
shell: pwsh
run: |
Invoke-WebRequest 'https://securecdn.oculus.com/binaries/download/?id=4377593722298679' -OutFile build/sdk.zip
if ((Get-FileHash build/sdk.zip).Hash -ne '3c8aeb66c822af731a8d1f1cb1cf97ab706100bf0bd003ef126f4bb9812906b3') { throw 'SDK checksum mismatch' }
Expand-Archive build/sdk.zip runtime/Externals -Force
Invoke-WebRequest 'https://securecdn.oculus.com/binaries/download/?id=3766757683456363' -OutFile build/platform.zip
if ((Get-FileHash build/platform.zip).Hash -ne 'adbdc5f0285a2ac2ead6fdd34522de98de1bf6782017d9857ea4044b2d2fd009') { throw 'Platform checksum mismatch' }
Expand-Archive build/platform.zip build/meta-runtime -Force
- name: Build complete Windows native runtime
shell: pwsh
run: |
cmake -S runtime -B build/native -G Ninja -DCMAKE_BUILD_TYPE=Release "-DCMAKE_POLICY_VERSION_MINIMUM=3.5" -DBUILD_TESTING=OFF "-DDETOURS_SOURCE_DIR=$PWD/build/Detours" "-DOPENXR_SDK_SOURCE_DIR=$PWD/build/OpenXR-SDK" "-DMETA_PLATFORM_IMPL=$PWD/build/meta-runtime/LibOVRPlatformImpl64_1.dll"
if ($LASTEXITCODE -ne 0) { throw 'Native configuration failed' }
cmake --build build/native -j 4
if ($LASTEXITCODE -ne 0) { throw 'Native build failed' }
- name: Build self-contained app and per-user installer
run: ./scripts/build-windows.ps1 -RuntimeDirectory build/native/bin
- name: Check installation, upgrade, launch and uninstall
run: ./scripts/test-windows-install.ps1
- name: Windows regression tests
run: python -m pytest tests/test_windows_package.py tests/test_windows_native.py tests/test_playtime.py tests/test_util.py tests/test_library.py tests/test_platform_exports.py -q
env:
QT_QPA_PLATFORM: offscreen
- uses: actions/upload-artifact@v4
with:
name: riftlift-windows-installer
path: |
dist/windows/RiftLift-Setup-*.exe
dist/windows/RiftLift-Setup-*.exe.sha256
- uses: actions/upload-artifact@v4
if: always()
with:
name: riftlift-windows-install-checks
path: build/install-check/
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ out/
# Runtime artifacts written by launched games in the repository working tree.
logs/
logConfig.xml

# Native Windows install and local verification output.
portable/
*.local.log
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# RiftLift

**Play your Meta Rift (Oculus Rift) PC VR games on Linux.**
**Play your Meta Rift (Oculus Rift) PC VR games on Linux and Windows.**

RiftLift is a Linux compatibility app for Meta Rift PC VR games. Its desktop
RiftLift is a compatibility app for Meta Rift PC VR games. Its desktop
GUI handles Meta sign-in, owned-game downloads, Steam shortcuts, local playtime,
and launching through your existing VR headset setup. It supports Rift Store
releases and compatible Steam games that include an Oculus mode. RiftLift can
Expand All @@ -13,13 +13,13 @@ use SteamVR directly or a Monado-based OpenXR setup.
> [!WARNING]
> **RiftLift is alpha software.** Game compatibility is still expanding.

See the [compatibility wiki](docs/COMPATIBILITY.md) for games tested with real VR output.
See the [compatibility wiki](docs/COMPATIBILITY.md) for Windows and Linux results.

## Quick start

Before you start, you need:

- a 64-bit Linux PC;
- a 64-bit Linux or Windows PC;
- Steam;
- a VR headset that already works through SteamVR or Monado/OpenXR; and
- a Meta account that owns a **Rift / PC VR** game.
Expand All @@ -29,7 +29,15 @@ drivers or Monado.

### 1. Install RiftLift

Download `riftlift-installer.sh` from the latest GitHub release, then run:
**Windows:** Windows builds produce `RiftLift-Setup-<version>-x64.exe`.
Open the installer, choose **Install**, then launch **RiftLift** from the Start
menu. Python, Git, administrator access, and a separate runtime download are
not required. The installer is not code-signed yet, so Windows SmartScreen may
say it "protected your PC"; choose **More info → Run anyway**. A desktop shortcut is optional. RiftLift selects your VR runtime
automatically. Re-running the installer updates the app; Windows **Installed
apps** can uninstall it while preserving your games and settings.

**Linux:** Download `riftlift-installer.sh` from the latest GitHub release, then run:

```bash
bash riftlift-installer.sh
Expand All @@ -43,12 +51,21 @@ Source installs use the checkout and selected payloads directly; release
artifact hashes are enforced by the generated all-in-one installer, not baked
into the application source.

For Windows source development, run `./install-windows.ps1` with Python 3.12 and
Git installed, then open `RiftLift.cmd`. To package a native build, install
PyInstaller 6.22.0 and Inno Setup 6, then run
`./scripts/build-windows.ps1 -RuntimeDirectory <complete-native-runtime-directory>`.
The Windows installer workflow builds and checks the standalone distribution.

### 2. Check your setup and sign in

Open **RiftLift** and click **System** to verify the setup.

Click **Sign In** and complete Meta's hosted sign-in page. Passwords and
security codes go only to Meta.
On Windows, Edge or Chrome uses a RiftLift browser profile. The first sign-in
there may ask for your Meta credentials again; later retries reuse that session
until you choose **Sign out and reset**.

![RiftLift Meta account screen after browser sign-in](docs/images/riftlift-account.png)

Expand Down
4 changes: 4 additions & 0 deletions RiftLift-Simulator.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@echo off
setlocal
call "%~dp0RiftLift.cmd" simulate --runtime "%~dp0portable\tools\SteamVR"
exit /b %errorlevel%
13 changes: 13 additions & 0 deletions RiftLift.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@echo off
setlocal
set "RIFTLIFT_HOME=%~dp0portable"
if not exist "%~dp0.venv\Scripts\python.exe" (
echo Run install-windows.ps1 first.
exit /b 1
)
if "%~1"=="" (
start "" "%~dp0.venv\Scripts\pythonw.exe" -m riftlift.windows_app
) else (
"%~dp0.venv\Scripts\python.exe" -m riftlift.cli %*
)
exit /b %errorlevel%
37 changes: 21 additions & 16 deletions docs/COMPATIBILITY.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
# RiftLift compatibility wiki

These games have been tested successfully with RiftLift. Results can vary with Wine, driver, GPU, and game updates.
Compatibility results are listed separately for Windows and Linux. Results can vary with runtime, Wine, driver, GPU, and game updates.

## Tested games

| Game | Build tested | Status | Oculus exclusive? | Setup notes |
| --- | --- | --- | --- | --- |
| [Aircar](https://store.steampowered.com/app/1073390/Aircar/) | Steam Oculus mode | ✅ Working | No | — |
| Echo VR | Community PCVR installation | ✅ Working | Yes, originally | Requires the community installer and patch; follow the [Echo VR setup guide](https://gist.github.com/Villagers654/d5bf4d11f56fc60d1eab91e7bf3f41c5). |
| [Five Nights at Freddy's: Help Wanted](https://store.steampowered.com/app/732690/FIVE_NIGHTS_AT_FREDDYS_HELP_WANTED/) | Steam Oculus mode | ✅ Working | No | — |
| [Keep Talking and Nobody Explodes](https://store.steampowered.com/app/341800/Keep_Talking_and_Nobody_Explodes/) | Steam Oculus mode | ✅ Working | No | — |
| [Lone Echo](https://www.youtube.com/watch?v=2pmV2mwAV9k) | Meta Rift Store | ✅ Working | Yes | — |
| [Lone Echo 2](https://www.meta.com/experiences/pcvr/lone-echo-ii/1711938725528735/) | Meta Rift Store | ✅ Working | Yes | — |
| [Oculus First Contact](https://www.meta.com/experiences/pcvr/oculus-first-contact/1217155751659625/) | Meta Rift Store | ✅ Working | Yes | — |
| [StereoPaint](https://store.steampowered.com/app/1920760/StereoPaint/) | Steam | ✅ Working | Yes | — |
| [Stormland](https://www.meta.com/experiences/pcvr/stormland/1360938750683878/) | Meta Rift Store | ✅ Working | Yes | — |
| [SUPERHOT VR](https://store.steampowered.com/app/617830/SUPERHOT_VR/) | Steam Oculus mode | ✅ Working | No | — |
| [The Thrill of the Fight](https://store.steampowered.com/app/494150/The_Thrill_of_the_Fight__VR_Boxing/) | Meta Rift Store | ✅ Working | No | Requires RiftLift 0.10.2.3 or newer for automatic legacy Unity runtime selection. |
| [Vader Immortal: Episode I](https://www.playstation.com/en-us/games/vader-immortal-a-star-wars-vr-series/) | Meta Rift Store | ✅ Working | Yes | — |
✅ = renders a menu or scene without major rendering errors; ❌ = does not work; ⚠️ = known problems; Untested = not tested. A check does not require a full gameplay pass.

| Game | Build tested | Windows | Linux | Oculus exclusive? | Setup notes |
| --- | --- | --- | --- | --- | --- |
| [Aircar](https://store.steampowered.com/app/1073390/Aircar/) | Steam Oculus mode | Untested | ✅ | No | — |
| Echo VR | Windows: original 34.4.636386.0; Linux: community PCVR installation | ✅ | ✅ | Yes, originally | Windows renders the original client's shutdown notice with hands. Online play requires the community installer and patch; follow the [Echo VR setup guide](https://gist.github.com/Villagers654/d5bf4d11f56fc60d1eab91e7bf3f41c5). Community client untested on Windows. |
| [Epic Roller Coasters](https://www.meta.com/experiences/pcvr/epic-roller-coasters/1477883658957255/) | Meta Rift Store; Windows: 8.11.2 | ✅ | Untested | No | Windows: coaster scene and comfort prompt through OVRPlugin's OpenXR path; needs the bundled compatibility layer (installer builds). |
| [Five Nights at Freddy's: Help Wanted](https://store.steampowered.com/app/732690/FIVE_NIGHTS_AT_FREDDYS_HELP_WANTED/) | Steam Oculus mode | Untested | ✅ | No | — |
| [Keep Talking and Nobody Explodes](https://store.steampowered.com/app/341800/Keep_Talking_and_Nobody_Explodes/) | Steam Oculus mode | Untested | ✅ | No | — |
| [Lone Echo](https://www.youtube.com/watch?v=2pmV2mwAV9k) | Meta Rift Store; Windows: 3.17.4 | ✅ | ✅ | Yes | Windows: main menu with tracked hands. |
| [Lone Echo 2](https://www.meta.com/experiences/pcvr/lone-echo-ii/1711938725528735/) | Meta Rift Store | Untested | ✅ | Yes | — |
| [Oculus First Contact](https://www.meta.com/experiences/pcvr/oculus-first-contact/1217155751659625/) | Meta Rift Store; Windows: 1.1.9 | ✅ | ✅ | Yes | Windows: room with tracked hands (OpenVR path). |
| [StereoPaint](https://store.steampowered.com/app/1920760/StereoPaint/) | Steam | Untested | ✅ | Yes | — |
| [Stormland](https://www.meta.com/experiences/pcvr/stormland/1360938750683878/) | Meta Rift Store; Windows: Stormland_008 | ✅ | ✅ | Yes | Windows: island scene; handedness selection accepts the trigger. |
| [SUPERHOT VR](https://store.steampowered.com/app/617830/SUPERHOT_VR/) | Steam Oculus mode | Untested | ✅ | No | — |
| [The Thrill of the Fight](https://store.steampowered.com/app/494150/The_Thrill_of_the_Fight__VR_Boxing/) | Meta Rift Store | Untested | ✅ | No | Requires RiftLift 0.10.2.3 or newer for automatic legacy Unity runtime selection. |
| [Vader Immortal: Episode I](https://www.playstation.com/en-us/games/vader-immortal-a-star-wars-vr-series/) | Meta Rift Store; Windows: 1.1.0 | ✅ | ✅ | Yes | Windows: Touch controllers detected; reaches the VR comfort setup. |

Windows results (2026-10-09) use the CI-built `windows-native` installer on SteamVR's null headset with two simulated Oculus Touch controllers ([test driver](../runtime/tests/steamvr-touch-sim/README.md)): every title presents stereo frames through the SteamVR compositor and detects the controllers. Physical-headset tracking, real controller input and full gameplay remain unverified. With SteamVR, RiftLift uses its OpenVR interface; forcing the OpenXR path on SteamVR's OpenXR runtime still fails for First Contact and Stormland, whose swapchains that runtime rejects. These results do not establish compatibility for the pinned release.

## What “Oculus exclusive” means here

Expand All @@ -37,4 +42,4 @@ riftlift doctor

The command includes concise setup details and recent launch evidence, then creates a shareable diagnostic paste. Attach that result when opening a [compatibility report](https://github.com/Villagers654/RiftLift/issues).

Last updated: August 2026.
Last updated: September 2, 2026.
24 changes: 24 additions & 0 deletions install-windows.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
param([string]$PythonVersion = '3.12')
$ErrorActionPreference = 'Stop'
Push-Location $PSScriptRoot
try {
if (-not (Test-Path '.venv/Scripts/python.exe')) {
& py "-$PythonVersion" -m venv .venv
if ($LASTEXITCODE -ne 0) { throw 'Python environment creation failed' }
}
& ./.venv/Scripts/python.exe -m pip install -e .
if ($LASTEXITCODE -ne 0) { throw 'RiftLift dependency installation failed' }
$env:RIFTLIFT_HOME = Join-Path $PSScriptRoot 'portable'
& ./.venv/Scripts/python.exe -m riftlift.cli setup
if ($LASTEXITCODE -ne 0) { throw 'Native runtime installation failed' }
& ./.venv/Scripts/python.exe -m riftlift.cli doctor --no-paste
if ($LASTEXITCODE -eq 2) {
Write-Host 'Runtime installed. Configure the headset/OpenXR runtime before game testing.'
} elseif ($LASTEXITCODE -ne 0) {
throw 'Windows diagnostics failed'
}

} finally {
Pop-Location
}
exit 0
9 changes: 4 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ build-backend = "setuptools.build_meta"
[project]
name = "riftlift"
dynamic = ["version"]
description = "Meta Rift games for Linux and Windows VR runtimes"
description = "Meta Rift games for OpenXR runtimes on Linux and Windows"
readme = "README.md"
requires-python = ">=3.10.12"
license = "MIT"
authors = [{name = "Villagers654"}]
keywords = ["linux", "meta", "monado", "oculus", "openxr", "rift", "vr"]
keywords = ["linux", "windows", "meta", "monado", "oculus", "openxr", "rift", "vr"]
classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Console",
Expand All @@ -34,14 +34,13 @@ xrizer = "https://github.com/Villagers654/xrizer"

[project.scripts]
riftlift = "riftlift.cli:main"

[project.gui-scripts]
riftlift-gui = "riftlift.gui:main"

[tool.setuptools.packages.find]
where = ["src"]

[tool.setuptools.package-data]
riftlift = ["assets/*.svg"]

[tool.setuptools.dynamic]
version = {attr = "riftlift.__version__"}

Expand Down
Loading
Loading