# UEVR from Frame Control, 2026-09-29 **Verified observations**, with limits below. Same device and software as [2026-09-28](mods-2026-09-28.md): aarch64, SteamOS `0.4.1`, BUILD_ID `20260925.6191901`, Proton `11.0-2c` ARM64, SteamVR `2.18.1`. Times are the Frame's AEST clock. Headset tests ran under the shared `/tmp/frame-test.lock`, taken 11:13–11:28, 11:33–11:49, 12:02–12:40, 12:44–12:52 and 13:01–13:03. Battery 45 % → 93 %, on charge throughout. **Not observed:** the VR image, head tracking and controller input. SteamVR reported `activity_level` 3 (user interaction timeout; the headset was not being worn) with `average_target_fps` 1. Every `frame_vrshot.py` stereo capture was a uniform dark frame. Frame submits prove the app is presenting to SteamVR, not that the image is correct. ## Manual injection (11:13–11:28) Game launched with `steam steam://rungameid/1067310`. `UEVRInjector.exe` was started with the game process's Wine variables, and its WPF window drew through DXVK's D3D9. It listed `Drop-Win64-Shipping (pid: 320) (SkyArk (64-bit, PCD3D_SM5))`, a Wine-side process id. - `--attach=Drop-Win64-Shipping` didn't inject. The button still read **Inject**, and the saved `OpenVRRadio=True` in `AppData/Local/praydog/…/user.config` was not restored on the next start. - XTest clicks landed on the game: `XQueryPointer` reported child `0x2000001` (the game) at the injector's coordinates, and `XLowerWindow`/`XRaiseWindow`/`XSetInputFocus` didn't change that. - `XSendEvent` button events to the injector window worked. After OpenVR and Inject, `/proc//maps` contained `drive_c/frame26/uevr/UEVRBackend.dll` and `openvr_api.dll`, next to Proton's `vrclient_x64.dll`. UEVR's log: ```text [11:17:32.948] Hooking D3D11 [11:17:33.020] Hooked DirectX 11 [11:17:34.263] Framework initialized [11:17:34.475] [VR] Requested runtime: openvr_api.dll [11:17:39.791] UGameViewportClient::Draw called for the first time. [11:17:39.792] is stereo enabled called! ``` It also logged repeated `Failed to initialize Framework on DirectX 12` (probing before it chose D3D11) and failed Unreal scans, for example `Failed to locate r.EnableStereoEmulation cvar` and `Failed to find FSceneView constructor`. SteamVR loaded UEVR's action manifest and `bindings_oculus_touch.json` for `steam.app.1067310`. `vrcmd --stats` then showed `"key" : "steam.app.1067310"` with `frame_submits` 4439, then 5506 a few seconds later. A second session's injector exited within about 20 seconds. The third, started fresh, injected again (`frame_submits` 1412). After the game was stopped, a plain launch had no UEVR modules and no SteamVR scene app. All test files were removed. ## Through Frame Control (11:33–11:49) Local `ui/server.py` against the `frame` alias. First the API, then the page's **VR mod** dialog, driven with a headless Chromium: | Step | Result | |---|---| | `status` for 2177750 (HL2 VR) | `eligible: false`; `install` refused ("doesn't look like an Unreal Engine game") | | `install` for 1067310 | 3 s. Three downloads, hashes matched, receipt written | | `start`, game running | First run refused: `the UEVR window is 960 px wide, not 625`. It was measured before WPF laid it out; `start` now waits for the width to settle. Rerun: injected, `frame_submits` 27 (36 s) | | `uninstall` while running | Refused: "the game is running; quit it first" | | `start`, game not running | Launched the game, injected, `frame_submits` 45 (55 s) | | UI: Remove, Install | Worked; the prefix listing matched its pre-install state except an empty `UnrealVRMod`, which uninstall now also removes | | UI: Play in VR | Failed once: the injector died with `Process terminated. … Resource name: Arg_AccessViolationException`, after `Fontconfig error: No writable cache directories` (it had no `HOME`). Fixed by keeping the normal environment under the game's (the relaunch-on-failure added next is gone with the GUI injector; see below) | | UI: Play in VR ×4 | 4 of 4 injected. The three cold starts took 54, 58 and 58 s; frame submits 56, 71, 80 | | UI: Remove | `drive_c`, `AppData/Roaming` and `AppData/Local` listings matched the pre-install state; download cache and receipt gone | ## The GUI injector wasn't reliable (12:02–12:40) After review fixes, cold starts through the API with UEVR's own injector: - Batches of 4, 6 and 8 runs: 3/4, 4/6 and 6/8 injected. A retry that relaunched the injector didn't rescue a bad session. In both failures of the last batch, the first injector ignored the clicks and the next two never showed a window within 60 s. - Captures of the ignoring injector (`xwd`) showed its first-drawn frame, with OpenVR still unselected. The injector's log had no error. Lock released at 12:40 before redesigning. ## Frame Control's own injector (12:44–12:52) `start` now runs `frame_inject.py` under python.org's embeddable Python 3.14.7 (SHA-256 `d297e5ff…1f15`, matching python.org's release-file API), in the game's Wine session. The old install was removed and the new one installed without the headset lock, since neither launches anything. The prefix listing after removal matched the pre-install state; the new install is 47 MB. | Step | Result | |---|---| | API `start`, cold | Injected in 35 s, `frame_submits` 39. UEVR log: `Hooked DirectX 11`, `Framework initialized`, `Requested runtime: openvr_api.dll`; `config.txt` has `Frontend_RequestedRuntime=openvr_api.dll` | | API `start` ×8, cold | **8/8** injected, 33–34 s each; `frame_submits` 33–42 at the check | | UI: dialog while running | "UEVR is running in the game now." Remove disabled (screenshot in `docs/img/uevr-dialog.png`) | | UI: Remove → Install → Play in VR → Remove | Each worked; Play in VR injected (`frame_submits` 106 a few seconds later) | | After the last Remove | `drive_c`, `AppData/Roaming` and `AppData/Local` listings matched the pre-install state; download cache and receipts gone; no game or `python.exe` processes. The empty `/tmp/frame-control-mods.lock` was deleted by hand (tmpfs) | Battery 98–100 % on charge. Lock released at 12:52. ## After the second review (13:01–13:03) `frame_inject.py` now declares every Win32 signature, checks each result, frees its remote buffers and closes its handles; uninstall accepts only our folder and UEVR's own settings folders. Rechecked: install; three cold starts injected in 35, 34 and 33 s (`frame_submits` 42, 38, 47), UEVR logging `Framework initialized` and `Requested runtime: openvr_api.dll`; uninstall left `drive_c`, `AppData/Roaming` and `AppData/Local` as before, with no cache, receipts or processes. Frame Control's injector total: 12 of 12 cold starts through the API, plus the UI run. ## Left on the Frame - Gravitas (free, 7.4 GB, installed 2026-09-28 for this work) is still installed; nothing else from this work is left. - No `UEVRInjector.exe` or game processes were left running. Steam and SteamVR were running at the end. - The test lock was released at 13:03.