Compare commits

...
Author SHA1 Message Date
spoopyghosty0 3f21bda2bd Docs: update screenshots and videos 2026-10-25 04:03:39 +00:00
spoopyghosty0 b440656560 Keep Android's shared libraries OVRPort removes (#484)
OVRPort's patch_remove_uses_library drops every <uses-library>, also ones
Lepton's Android 11 provides: YouTube VR (org.apache.http.legacy) then dies
at start with ClassNotFoundException org.apache.http.protocol.HttpRequestHandler.

New patch frame.keep_system_libraries (default on where the original
manifest names such a library) puts those entries back after OVRPort,
always android:required="false". Lepton's libraries are one list
(system_libraries.LEPTON_LIBRARIES); analysis extra.uses_libraries reads the
original manifest (ANALYSIS_VERSION 27). Builds of apps without such an entry
are unchanged. Triage system-library-missing, PLAYBOOK row, tests.
2026-10-24 23:56:06 -04:00
spoopyghosty0 5429ae5c2b Steam library (now): later installs no longer hang behind a waiting library update (#305)
While a now-mode library update waited for FramePort/Desktop Mode/a game to close it held the shortcut lock;
the next install's library_mode call blocked on it until the 600 s agent timeout. library_mode now tries the
lock once, shortcuts journals changes into the waiting worker (merged after Steam closes, one restart), the
later queue waits at most 30 s, and runs only drop the journal entries they applied. Agent v124.
2026-10-24 23:54:47 -04:00
spoopyghosty0 48367c7cf8 Expansion files: other kinds get the game's package spelling too (#415)
Crisis Brigade 2 reloaded's office/alleys/challenges/mansion/ta1-3 .222.<package>.obb
copies with a lower-case package part reached the Frame under names the game can't
open. obb_names renames such <kind>.<vc>.<package>.obb files (case or copy suffix,
kind spelling kept) without an "another app" warning; NAMED_OBB kinds may contain
digits (ta1 was skipped by the scan) and copy-suffixed files of any kind are found.
2026-10-24 23:53:37 -04:00
spoopyghosty0 a6b37f8331 Windows updates never mix two versions (#476)
A failed copy was rolled back without deleting the files the new version had added: the old version then started next to a new patch module and crashed at start (cannot import name 'ORG_MARK'). The swap script now changes nothing while FramePort or a program file is in use, moves the old version's files the new one doesn't have into 'previous' (only inside the bundle's own folders), and a rollback deletes what the update added. Bundles carry frameport/_bundle_files.txt; at start the app removes or ignores leftover package files and tells the user to reinstall when compiled modules don't match. update_smoke.py runs a locked-file rollback and a leftover-module update on Windows.
2026-10-24 23:43:30 -04:00
spoopyghosty0 f2297a4ac1 Site: current app and docs; Controller buttons page; clearer wording
- Home, meta descriptions: Linux apps alongside Quest, PC VR and Android; shorter notice, matching the README.
- Setup page: the app's labels ('Already set up?', 'Connect by address…'); Pair new host asks by itself.
- Tour: the install video is about 90 s.
- Docs: CONTROLLERS.md is a site page now, and the image sync copies docs/images subfolders (its diagram lives in
  controllers/); the 'game won't start' path starts with the FAQ.
- 'it'/'this'/'that' replaced by the noun where the referent was unclear (walkthrough, setup, download, install
  pages, compare, PC VR panel, demo app).
2026-10-24 23:41:58 -04:00
spoopyghosty0 89a501d5d8 Docs: name the thing instead of 'it', 'this' or 'that' where the referent was unclear
Every page this branch touches: sentences that started with 'It'/'This'/'That' after naming two things, and short
answers ('report it', 'click it'), now say what they mean. Two FAQ headings start with 'The game' (no page links to
them).
2026-10-24 23:41:58 -04:00
spoopyghosty0 8359856609 Docs: themes, install button, controller buttons, diagnostics, contributing: tighter wording
Diagnostics starts with what a user sends and moves the maintainer workflow into one paragraph; contributing folds
the tested-game section into the quick contributions.
2026-10-24 23:41:58 -04:00
spoopyghosty0 dfdd6cf0ca Docs: install guide and FAQ: shorter, one idea per sentence
Same instructions in fewer words: setup alternatives as a list, moving from a PC in three short steps, room editing
as numbered steps, save backups once in the FAQ. The FAQ's 32-bit answer was outdated: the 32-bit bridge is
suggested for such games now.
2026-10-24 23:41:58 -04:00
spoopyghosty0 59de1da268 Docs: README and compatibility: no game count, shorter text
'Hundreds of games' instead of a number that goes stale (README, COMPATIBILITY, the site's comparison). Shorter
notice, features, quick start and comparison bullets; one-line docs index rows.
2026-10-24 23:41:58 -04:00
spoopyghosty0 75a016b4ff Docs: architecture: triage signatures now update from GitHub main too 2026-10-24 23:41:58 -04:00
spoopyghosty0 3170b3acc9 Docs: third-party notices list Cpp2IL and APKEditor, which FramePort downloads on first use 2026-10-24 23:41:58 -04:00
spoopyghosty0 bd242be4a7 Docs: transfer benchmark: remove local report paths, say what the uploader does today
The page named report files under a personal Windows home folder; the measurements stay, the paths go. A short
current-state section (OpenSSH SFTP for big files, 3 parallel uploads) heads the page, so the older 'production
still uses Paramiko, default 2' statements read as history.
2026-10-24 23:41:58 -04:00
spoopyghosty0 3dcede3ee3 Docs: runtime reference: version-neutral title, current Revive-under-Proton facts, no agent versions
The title pinned SteamOS 0.3.0 although sections cover up to 0.5.x; PC VR under Proton isn't 'unverified' any more,
and Revive's hooks don't work there (the old line said they did). sshd comes with Developer Mode and FramePort's key,
no password. The headset-view webcam does show games. Foveation preferences moved next to the other foveation
notes (they sat under Monitoring sources), the scan preview below the room overview. Room tab paths.
2026-10-24 23:41:58 -04:00
spoopyghosty0 68aab29e85 Docs: playbook: fix the broken first table, current PC VR model, one section for FramePort's own problems
The startup table had a row above its header separator (it rendered as plain text). PC VR games are installed
unchanged by default, Revive only for LibOVR games; the two duplicate -3001 rows are one now. Upload/SSH, install
link and store-detail rows moved out of the startup and PC VR tables into their own section, the OutRun rows into
the startup table. No agent version numbers; room scanning in the headset exists now; Add from a link.
2026-10-24 23:41:58 -04:00
spoopyghosty0 2e86f97905 Docs: contributor pages: current menu labels, PC VR runs as-is by default, Linux apps, no agent versions
CONTRIBUTING: Share working recipe / Report a problem under their menu groups, Language lives in Appearance,
patch_docs and showcase pointers. ARCHITECTURE: bundles and backups as sources, session triage, remote catalog,
PC VR games installed unchanged with Revive only for LibOVR games, a Linux apps section. FRAME_SETUP: menu entries,
services and FEX that FramePort adds later. DIAGNOSTICS: no agent version numbers. 'for example' instead of e.g.
2026-10-24 23:41:58 -04:00
spoopyghosty0 439cc6c213 Docs: install guide and FAQ follow the new game menu, settings and save backups
INSTALL: menu paths through the game menu's groups, one section on when games appear in Steam (was buried under
running FramePort on the Frame), save backup folder/automatic snapshots, shorter overlay and first-launch notes,
rename/session/settings commands. FAQ: foveation lives in Game settings now, Exit game pauses games first, save
backups as a short list, controller buttons.
2026-10-24 23:41:58 -04:00
spoopyghosty0 26b2ea16fd Docs: README and compatibility pages: current game count, full docs index, Linux apps; regenerate the tested-games list 2026-10-24 23:41:58 -04:00
spoopyghosty0 46863a7c61 Catalog: Hungry Shark Evolution (#486) 2026-10-24 23:35:19 -04:00
spoopyghosty0 79e329afe5 Tests: shorter line in the shader-fix triage test 2026-10-24 22:01:35 -04:00
spoopyghosty0 9973833585 Shader fixes: say once when none of a game's configured fixes matched
vk_shader_fix (vkshim) and zink_shader_fix (shader-fix layer) match a shader by size + SHA-256, so a game update that changes the shader made the fix silently do nothing. Once per session, when fixes are configured and none matched 5 minutes after the first shader module (checked only at module creation), the shim/layer logs '<prefix>: N shader fix(es) configured, none matched after M modules in S s (game updated?)'. Triage shader-fix-unmatched (info, report) + PLAYBOOK row. Artifacts rebuilt; no revision bumps.
2026-10-24 21:59:20 -04:00
spoopyghosty0 c239a8cf32 Headset identity: other OVRPort runtimes found by structure, not fixed offsets
The verified 3.4.3-aa54c3f layout keeps its exact guards. Any other dispatcher (the older 3.4.3-23204ea, later
runtimes) gets Quest 3 when Quest 2's name and UUID each occur once and each is loaded by exactly one adr /
adrp+add / adrp+ldr q sequence; otherwise nothing changes and the build keeps Quest 2 with a WARN, as before.
Checked against both runtimes in the OVRPort workspace.
2026-10-24 21:50:16 -04:00
spoopyghosty0 9e69242001 Just Dance VR local save: no game version check
The patch finds its code by name, leaves a build that already saves unchanged and refuses when the code isn't
there, so it applies to every Just Dance VR build without parsing version names.
2026-10-24 21:45:05 -04:00
spoopyghosty0 6e0958b03d Just Dance VR keeps its progress (#480): frame.justdance_local_save
Just Dance VR (0.5.4 and later) loads its progress from a local save at
start, but LocalSaveEvents.RequestSave is empty (a single ret in
libil2cpp.so), so the SaveValueRequested event that LocalSaveManager
listens to is never raised and the OfflineSave file is never written.
On a Quest the progress lives in PlayFab after a Meta sign-in, which the
Frame doesn't have.

The patch gives RequestSave its declared body (raise SaveValueRequested
with the key and value). Everything is found per build: Cpp2IL (the
shared IL2CPP run) gives the methods and field offsets, capstone decodes
SaveSystemReady for the TypeInfo slot, the metadata init and the
delegate layout, and the new code goes into a new R+X segment
(elf.append_segment); RequestSave's ret branches there. A build whose
RequestSave has a body is left alone; anything unexpected is refused
with the reason. Nothing online is touched.

Triage signature justdance-local-save-off, gated with the new
unless_patch key (not when the fix is in the build); PLAYBOOK row,
DEVICE_NOTES.
2026-10-24 21:25:59 -04:00
spoopyghosty0 4c1cbc9f50 Triage signatures update from GitHub main like the catalog
refresh_remote also caches catalog/triage.yaml from the same tree listing
(triage-gh-<sha>.yaml); triage.database() merges it per signature id over
the bundled file, dropping remote signatures this app can't use (malformed,
unknown field, unknown patch/adapter key, min_app too new). Bundled-only
signatures stay; a bundled one dated later wins.
2026-10-24 21:20:45 -04:00
spoopyghosty0 f393884606 QuestZDoom slowdown (#237): Team Beef ports get gl_error_clear
QuestZDoom leaves GL_INVALID_ENUM pending every frame; the runtime's GL check fails on it at the first
swapchain and its GL interop then leaks ~105 GPU objects a second (debugfs gem, headless), until the
game slows to a crawl and the GPU driver oopses. gl_error_clear keeps the count flat. Suggested for
every Team Beef port; QuestZDoom catalog recipe with it; PLAYBOOK row and device note.
2026-10-24 17:28:05 -04:00
spoopyghosty0 984c1ab4f3 Locales: template with the latest patch texts 2026-10-24 17:19:38 -04:00
spoopyghosty0 53980029bb The Climb 1 starts again: the foveation layer file always ships with FrameBridge, and never interposes libvulkan (#432, #449)
e5921ccb kept libVkLayer_fdm_darken.so out of The Climb 1's libAndroidLauncher.so but also stopped shipping the
layer file, while frame.adapter links every arm64 FrameBridge build against it: FrameBridge didn't load, the VrApi
bridge logged 'xrInitializeLoaderKHR failed: OpenXR result -7' and CryEngine aborted (SIGTRAP; dev build zip, static
check warned the NEEDED was missing). diagnostic_support now always ships the layer; frame.adapter validate fails
without it.

The 1.3.0 start failure itself: the layer exports vkEnumerate{Instance,Device}{Extension,Layer}Properties for the
Vulkan loader and elf.add_needed linked it first, so a renderer importing those from libvulkan.so (libCryRenderVulkan.so
does, The Climb 1's monolithic launcher imports Vulkan directly too) got the layer's answers (no extensions /
VK_ERROR_LAYER_NOT_PRESENT). elf.add_needed(first=False) links it after the existing entries for every other engine.
frame.adapter package revision 5 for com.crytek.climb; triage vrapi-bridge-no-loader.
2026-10-24 17:17:04 -04:00
spoopyghosty0 c95efb92d7 Agent v123: the flat-launcher theater exception (#475) ships after v122's diagnostics change; test follows deployment_recipe 2026-10-24 17:16:47 -04:00
spoopyghosty0 a4d71c529d Apps with a flat launcher before their VR part get the Android window, shown in theater mode (#475)
Xelee opens MeleeActivity (a 2D SDL launcher that picks the game) and starts MeleeXrActivity from there. Lepton
runs VR apps headless, so the launcher was never seen and OpenXR never started. device.text_input_window is now
suggested for apps with an analysis vr_activity, the deployment recipe records flat_launcher (unless
frame.start_activity starts the VR part directly), and agent v122 keeps SteamVR's theater mode on for those, so the
launcher is in front of the player instead of a dashboard page. Catalog: Xelee gets the window.
2026-10-24 17:11:44 -04:00
spoopyghosty0 192bf14f9d Diagnostics: collect_diag returns the last launch's stop-pause, exit-hook, theater and dashboard logs and plays.log, so a zip shows whether the game was paused before it closed and how it was closed (agent v122, #480) 2026-10-24 17:10:08 -04:00
spoopyghosty0 e30361bc9e UI text: "for example" instead of "e.g." in the OBB name warnings 2026-10-24 16:00:03 -04:00
spoopyghosty0 a09fdd7ae3 Menus: a solid grey left edge and a solid soft highlight instead of the portal gradient (#414) 2026-10-24 15:54:48 -04:00
spoopyghosty0 f53b25686f Menus: FramePort's own menu with hover submenus for every context menu and the game page's "…" (#414)
- ui/popmenu.PopMenu draws menus in page.overlay: panels size to their labels (no 280 px cap, wrap past a
  maximum, scale with the UI), open at the click or under the button, flip and clamp into the window; submenus
  open to the side with room (hover with intent delays, click, or the arrow keys); Enter/Esc; closes on an outside
  click, a choice or a view change; portal edge in dual themes, no fade with Reduce motion.
- The game menu (app.game_actions) is one structure for the Library right-click and the page's "…": Play,
  Install/Update, Game settings | Open game page, Select | Update, On the Frame, Saves, Name and artwork, Recipe,
  Troubleshoot submenus | Uninstall, Remove from library. Launch tests are in Troubleshoot.
- Files, Screenshots and Monitor right-click menus use it too; the multi-select menus are unchanged.
- ui_smoke: menu steps open a submenu and use the keyboard.
2026-10-24 15:54:44 -04:00
spoopyghosty0 e542fd1b67 Menus: long items wrap instead of running past the edge; shorter Library right-click menu (#414)
- Menu rows put the label next to the icon themselves so a label wider than Flutter's menu limit wraps (Flet's own
  icon row overflowed); menu buttons scale the width limit with the UI scale.
- Library right-click: Play, Install/Update, Game settings | Open game page, Select, More actions. Rename, the
  newer-version updates and Remove from library stay in the game's menu; uninstalls on the game page and Frame page.
- Right-click on one of several selected games: Install them on Frame / this PC, Select all shown, Clear selection.
- Game page: the recipe's actions (reset, save as known-good, share) are buttons on its recipe card; Back up saves
  is only the button next to Play.
2026-10-24 15:54:40 -04:00
spoopyghosty0 5c9848c0ba Steam's own Exit game pauses FramePort games first: the launcher's _exit_hook worker hooks SteamClient.Apps.TerminateApp in Steam's UI through CEF devtools and lets Steam end the game once Android paused it (cap 3 s; other games pass straight through; #480)
Agent v121. Verified headless on the dev Frame with AC Nexus launched through Steam: OnApplicationPause(true)
0.15-0.29 s after TerminateApp, container gone 1.5-1.7 s after it (0.65-0.8 s before); a game that doesn't
answer is capped (3.2 s). The Monitor's End game calls Steam's TerminateApp past the hook (no second pause).
2026-10-24 15:46:41 -04:00
spoopyghosty0 0a59ebd7d3 App bundles: .xapk/.apks/.apkm/.apkx files and split APK folders are unpacked and merged into one APK (discussion #482)
Scan a folder, Add an APK, drag and drop, install links and the CLI take them. The arm64-v8a split's libraries and assets are merged in Python (split attributes and Play's splits.required flag removed); language/density/feature splits go through REAndroid's APKEditor (downloaded into tools/). OBBs from the bundle or next to it become the game's data. Old encrypted .apkm files are explained, not opened. Headless device check: Escaping Wonderland split into base + arm64 split, merged, built, installed and launch-tested at 72 fps.
2026-10-24 15:27:58 -04:00
spoopyghosty0 5d6f598c31 Installs: OBBs with a download's copy suffix or another case go to the Frame under the name the game looks for (#481)
main.203.com.Armature.VR4-003.obb is sent as main.203.com.Armature.VR4.obb (#450); the files on the PC keep their
names and the game page shows an info note instead of a warning. Another app's name (#129), a copy next to the
right-named file, two copies for one name and a copy suffix without a versionCode stay warnings. plan_update compares
the Frame's names (no repeated Update on Frame), a file installed earlier under the copy name is renamed on the Frame
instead of uploaded again, and on-Frame hardlinks (#433) keep the PC file as their source. Loose copy-named OBBs next
to an APK are found by name. Unreal chunk files and split parts are no longer flagged as named for another app.
2026-10-24 15:15:28 -04:00
spoopyghosty0 4f5b19e48b Games are paused before they end: launch.sh, agent stop and End game send the activity home in the container and wait up to 3 s, so saves written on pause run (Just Dance VR lost progress, #480)
Killing the container (launch.sh podman kill, Lepton's reboot -p + podman stop) never paused the app: no onPause, no Unity OnApplicationPause(true). am start of the HOME intent pauses it in Lepton's Android 11 (input keyevent does nothing headless); the script waits for STOPPED + 0.4 s, capped at 3 s. upgrade_launchers adds pause_game to existing Lepton launchers. Steam's own Exit game signals the whole process tree (container included) at once and isn't covered yet. Agent v120.
2026-10-24 15:14:19 -04:00
spoopyghosty0 ad295e12eb Theater hold: taken first thing in the launcher (a hold with Lepton's start came after the window was theatered), keyed by launcher pid; verified end to end on the Frame 2026-10-24 15:11:08 -04:00
spoopyghosty0 2be68ca37f Typing window no longer takes the controllers: SteamVR's theater mode stays off while a game with its Android window runs (AC Nexus, #476, #477)
device.text_input_window makes the game's Android window a gamescope "desktop game" overlay. SteamVR put it into
theater mode before the game's OpenXR session existed and opened the dashboard on it when the session started: the
Android screen with the controllers as a mouse pointer. The dashboard worker now turns dashboard.autoShowGameTheater
off while such a game runs (holds per worker, restored after the last one, by the next start or ensure_host_fixes
after a killed worker, and by purge). It also recognises SteamOS 0.5.6's open_dashboard_action as the player's
dashboard button instead of closing every press again. Agent 119.
2026-10-24 15:10:51 -04:00
spoopyghosty0 d13381db7f Browser stand-in for sign-ins: apps that look for a browser (Plex's sign-in, #466) find one in their own APK and Lepton opens the page in Steam's browser
Patch frame.browser_handoff (opt-in; offered for 2D apps, suggested-off when the manifest's <queries> ask for a
browser: analysis browser_query, ANALYSIS_VERSION 26) adds an http/https VIEW + BROWSABLE activity (no host) and its
class (native/java-handoff -> artifacts/dex/browser-handoff.dex) to the app. Lepton's ActivityStarter.execute takes
every VIEW intent before resolution and writes steam://openurl to /lepton/steam.pipe, so the stand-in normally never
runs; started directly it writes the same line itself. axml: queries_browser, browser_activities,
add_browser_activity (missing android: attribute names go into the resource-mapped part of the pool).
A 2D app with an APK patch turned on is now built instead of installed unchanged (engine.flat_as_is in set_recipe):
hand-enabled APK patches on 2D apps were never applied. Verified headless on the Frame with a test app.
2026-10-24 15:10:15 -04:00
spoopyghosty0 79bd23e728 Locales: template with the Provide space warp setting 2026-10-24 15:06:03 -04:00
spoopyghosty0 1262880f14 FrameBridge space_warp_emul: XR_FB_space_warp for games that require it (OutRun Quest VR, #336)
OutRun quits with "AppSW recommended buffers unavailable" whether XR_FB_space_warp is offered or hidden.
New per-game adapter setting space_warp_emul (off by default, native/adapter/space_warp.c): offers the
extension (emulated when the runtime lacks it, overrides hide_space_warp), reports a motion-vector size of
eye/4 (the Frame's runtime answers the full 1728x1728 eye), lists RGBA16F and depth formats after the
runtime's, serves motion-vector swapchains (RGBA16F/RG16F at the reported size or at most half the eye) and
their depth swapchains as FrameBridge-owned GL textures / Vulkan images (3 images, round robin, wait/release
in front of every other hook), and strips XrCompositionLayerSpaceWarpInfoFB at xrEndFrame (eye depth info is
now kept when space warp info isn't first in the chain, also for hide_space_warp).

Headless on the dev Frame with Pinball FX VR (UE5 + OVRPlugin, Vulkan): both 376x376 pairs served,
600/599/598 acquire/wait/release by FrameBridge, space warp info removed, 0 xrEndFrame failures, 72.2 fps like
its own recipe. Triage appsw-required, catalog entry for OutRun (fb_color_space + space_warp_emul),
PLAYBOOK row, DEVICE_NOTES section, host harness for the GL/Vulkan paths.
2026-10-24 15:01:03 -04:00
spoopyghosty0 a8f6c7f1e4 Type on Frame: the paste buttons move below the field when it would be squeezed (narrow window, large UI scale)
The paste field (expand) shrank to a few pixels in narrow windows while the buttons kept their size. The view now
measures the buttons and the row (on_size_change) and stacks the buttons, right-aligned and wrapping, below the field
when it would get less than 240 px (scaled).
2026-10-24 14:43:40 -04:00
github-actions[bot] 48805ff810 Docs: update screenshots and videos (#438) 2026-10-24 14:29:32 -04:00
Lucas Oskorep c66d364451 Docs: AUR package (community) install and update notes (#445) 2026-10-24 14:28:28 -04:00
spoopyghosty0 6e701ae33a Docs: moving from a PC to FramePort on the Frame (signing keys, original files, saves; discussion #442) 2026-10-24 14:27:33 -04:00
spoopyghosty0 7daf9aa103 Library: data files an older scan skipped are picked up at start, so the game shows Update on Frame (Asgard's Wrath 2's chunk OBBs: no badge, the user reinstalled, #471) 2026-10-24 14:13:16 -04:00
spoopyghosty0 d70e540482 Catalog: UNDERDOGS (#474, works) and Eternal Starlight (#479, voice commands don't work) 2026-10-24 14:08:42 -04:00
spoopyghosty0 5dee4bac51 Vulkan rename skips Dawn (WebGPU) libraries, which build the library name from two pieces: the in-place rename made Xelee and PrimedGun ask for libfp_vkn.so (#475, #254) 2026-10-24 14:03:56 -04:00
spoopyghosty0 7eec8fdf57 Catalog: Xelee without the Vulkan library rename (#475): the engine assembles libvulkan.so from two pieces 2026-10-24 14:01:56 -04:00
spoopyghosty0 25198bc11c FramePort on the Frame: an update replaces game data an earlier install copied with links to the originals, so the second copy is freed without reinstalling (#433) 2026-10-24 13:59:27 -04:00
spoopyghosty0 e5921ccb4e The Climb 1 starts again: the dormant foveation diagnostic also stays out of CryEngine's monolithic libAndroidLauncher.so (#432, #449)
a8e01c01 skipped only libCryRender*; The Climb 1 has no separate renderer, so engine_lib() picked
libAndroidLauncher.so and the layer was still linked into it. Both reporters' zips (1.3.0 and a dev build with
a8e01c01) crash identically: SIGSEGV fault addr 0xf0 under CreateSystemInterface+320 right after Vulkan instance
setup. frame.adapter package revision 4 for com.crytek.climb marks existing builds for Update on Frame.
2026-10-24 13:56:47 -04:00
spoopyghosty0 a4546e4ee4 Foveation: put Valve's sharp area on each eye (#394), second version; Vulkan eye snapshots
Valve's VALVE_fdm_injection layer gives every eye swapchain a density map covering the whole swapchain with its
FOVE_LEVEL rectangle at the swapchain centre; it never uses the submitted imageRect or the eye's optical axis, so games
with smaller or shifted eye rects (dynamic resolution, AC Nexus 0,0 / 287,0 1726x1728 in 2016x1728) got the sharp area
~14% of the view to the side. VK_LAYER_FRAMEPORT_fdm_centre (native/foveation/centre.h, second layer in
libVkLayer_fdm_darken.so, right below Valve's layer when FDM_DEBUG has "enable"; not for The Climb 2;
FRAMEPORT_FDM_CENTRE=0 turns it off) replaces the per-eye density-map offsets: the eye's optical centre (Fixed) or
Valve's gaze re-based on the eye's rect (Eye-tracked). FrameBridge reports the views (fdm_views.c).

Changes after the first version (b2be40af, reverted 2ce1c505) failed in the headset:
- Eye-tracked black: Valve declares fragmentDensityOffsetCount 1 for two-view passes while Turnip reads one offset
  per view regardless, so the right eye's offset came from uninitialised stack memory. Every offset Turnip reads is
  now written (view count from the pass's view mask, eye from the map view's layer, each eye's gaze from Valve's array).
- Fixed crash: the layer no longer flags images (it had flagged external-memory images Valve leaves alone). Valve's
  own disable_offsets path also crashed AC Nexus without this layer (Turnip under fdm_injection_CmdBeginRendering), so
  Fixed now drops disable_offsets in-process once the layer is in the chain and overrides Valve's gaze offsets with the
  optical centre; if Valve read the option first its maps carry no offset flag and passes are left alone.

Headless on the dev Frame, AC Nexus, 130 s per run, darkening test, snapshots every 15 s: centring Fixed (2 runs) and
Eye-tracked ran without crash at 72 fps, both eyes' sharp area within 2% of the optical centre (Valve only: +14% Fixed,
+25% left eye Eye-tracked; Valve-only Fixed crashed in 1 of 2 runs). FrameBridge snapshot=N reads Vulkan eye images
back; FRAMEPORT_FOVEATION_TEST=2 paints 1/fragment area. Triage valve-fdm-render-crash. Host harness
tests/test_fdm_centre.py. The sharp area's size still snaps to Turnip's GMEM bins (driver design).
2026-10-24 11:58:39 -04:00
spoopyghosty0 2ce1c50544 Revert the foveation centring layer (b2be40af): AC Nexus crashed in Valve's fdm layer (Fixed) and showed black (Eye-tracked) in the headset (#394); back until it is fixed and checked headless 2026-10-24 11:14:55 -04:00
spoopyghosty0 b2be40af35 Foveation: put Valve's sharp area on each eye (#394); Vulkan eye snapshots
Valve's VALVE_fdm_injection layer gives every eye swapchain a density map that covers the whole swapchain and centres
its FOVE_LEVEL rectangle there; it never uses the submitted imageRect or the eye's optical axis. Games that submit a
smaller or shifted rect (dynamic resolution, asymmetric eye rects such as AC Nexus 0,0 / 287,0 1726x1728 in a
2016x1728 swapchain) got the sharp area ~14% of the view off to the side, towards the bottom for corner-anchored rects.

VK_LAYER_FRAMEPORT_fdm_centre (native/foveation/centre.h), a second layer in libVkLayer_fdm_darken.so inserted right
below Valve's layer when FDM_DEBUG has "enable" (not for The Climb 2; FRAMEPORT_FDM_CENTRE=0 turns it off), rewrites
the per-eye density-map offsets at the end of each pass: Fixed puts the sharp area on the eye's optical centre (it adds
the offsets and the offset image flag Valve leaves out with disable_offsets), Eye-tracked re-bases Valve's gaze offset
on the eye's rect. FrameBridge reports the views (fdm_views.c: swapchain size, layer, imageRect, optical centre).

FrameBridge snapshot=N now also reads Vulkan eye images back (both eyes, half size, rect + FOV logged), and
FRAMEPORT_FOVEATION_TEST=2 paints 1/fragment area. Headless on the dev Frame (AC Nexus, Fixed, darkening test):
sharp-area centre vs optical centre +203,+43 px -> +26,+11 at 1x, +276,+65 -> +12,+17 at 1.5x, +407,+87 -> +47,+31
at 2x. The size still snaps to Turnip's GMEM bins (density is chosen per bin), so Small equals Large at 1x and the
shape changes between render scales; that part is the driver's.

Docs: DEVICE_NOTES "Foveation: sharp area centre and size", FRAME_RUNTIME, PLAYBOOK row, native/README; triage
dynamic-resolution-foveation is quiet once the centring layer ran. Host harness tests/test_fdm_centre.py.
2026-10-24 10:28:42 -04:00
spoopyghosty0 3dc7d823e4 Docs: Ghost Giant (#439) checked headless: the black screen after the logo was the intro video (no NDK media); with dcbcce0f/bccd916f both videos play and the main menu renders 2026-10-24 10:18:33 -04:00
spoopyghosty0 33f076e66c VrApi bridges: OVP_HEADLESS_TEST submits images, so headless snapshots show what a VrApi game draws (#439)
Without a worn headset the session stays SYNCHRONIZED: the VrApi bridge ended every frame empty and the a32 bridge dropped every projection with an untracked default pose, so FrameBridge's snapshot=N had nothing to read. Under OVP_HEADLESS_TEST (tests only) the VrApi bridge submits anyway and keeps GetTrackingTransform(3)'s floor 1.6 m below the eye origin (the runtime's headless STAGE sat 0.865 m below it, and Ghost Giant hid everything behind "Return to play area"), and vrapi.c keeps the game's pose. Harness: headless submit keeps the layer. Checked on the Frame: Ghost Giant's intro videos and main menu in the snapshots.
2026-10-24 10:18:30 -04:00
spoopyghosty0 aff56927ec FrameBridge: flipped Vulkan quads are shown as upside-down atlas copies made every frame instead of flipping the app's image in place (AC Nexus' late-drawn notices stayed upside down, re-flips and GPU waits; likely the white start flash)
The in-place flip raced Unity, which finishes some panels after xrEndFrame without acquiring them again, and its
blits/readbacks waited for the GPU inside xrEndFrame. swapchain_pool.c now owns flips (also without swapchain_pool):
a flagged pooled panel's atlas copy is a blit with reversed rows, a flagged runtime swapchain's quad gets a per-frame
atlas area with an upside-down blit of its released image. The app's images are only read; no CPU waits. flip_dump
reads back what the runtime is given (async); layer_debug logs copies and waits per 5 s. The late-drawing
fingerprints, scratch image and in-place flip are gone. Headless: every intro panel upright as submitted, 72 fps.
2026-10-24 00:28:10 -04:00
spoopyghosty0 8a89f821e0 Locales: template with the new patch summary (frame.ovr_org_scoped_id), which failed CI's i18n check 2026-10-24 00:06:41 -04:00
spoopyghosty0 02eb17dd91 FrameBridge: back to the sparse late-drawing check (revert fdaba13f): the every-pixel async version brought AC Nexus' white start flash back without fixing its notice panel (owner, headset 2026-10-23); the 595d12a0 state was headset-verified 2026-10-23 23:53:31 -04:00
spoopyghosty0 2c9a1add30 Agent: battery percent on Steam's scale (Steam shows the fuel gauge rescaled, ~/0.9: the app showed 77 % where the headset showed 85 %, #414); the gauge's own value stays as gauge_percent 2026-10-23 23:44:42 -04:00
spoopyghosty0 33a29a51d5 Triage: meta-org-scoped-id-wait matches Eleven's real log (platform start, then Request failed; the stack names no game code) 2026-10-23 22:33:00 -04:00
spoopyghosty0 9e15706068 Platform: answer Meta's org-scoped user id request (frame.ovr_org_scoped_id, GitHub #452)
OVRPort's platform loader exports ovr_User_GetOrgScopedID, ovr_Message_GetOrgScopedID and ovr_OrgScopedID_GetID as
`mov x0, xzr; ret` (runtimes 3.4.3-23204ea and -aa54c3f): request id 0, no message ever, so Meta's C# wrapper logs
"An unknown error occurred. Request failed." and the callback never runs (Eleven Table Tennis waits in
<BuildIdentity>b__0; Cortopia's Escaping Wonderland #360 / TMNT #422 too).

libfp_langpack.so (native/langpack) now answers it when its @FPORGID@ marker is set (or FRAMEPORT_ORG_SCOPED_ID=1):
a fresh request id and a successful ovrMessage_User_GetOrgScopedID (0x18F0B01B) whose ovr_OrgScopedID_GetID is an
ovrID hashed from the (already stable, frame.ovr_stable_user) user id: FNV-1a 64, top bit cleared, never 0. A new
@FPLANGS@ marker lets the library be linked for that alone with the language-pack calls passed through to the loader
(FRAMEPORT_LANGPACK_SERVE overrides); builds with frame.langpacks/asset_files behave as before.
ovr_User_GetUserProof (Eleven's next request) is answered by OVRPort itself (queued message with a nonce), so it is
left alone.

New patch frame.ovr_org_scoped_id (order 35, default on, suggested for games known to wait: Cortopia's analysis flag,
Eleven Table Tennis, TMNT), triage signature meta-org-scoped-id-wait, PLAYBOOK row, host tests against the stand-in
loader. frame.cortopia_org_id stays until the generic answer is headset-verified.
2026-10-23 22:31:42 -04:00
spoopyghosty0 379bd161cb Scan: Unreal's chunk expansion files next to an APK (patch.pakchunk<N>-Android_ASTC.<package>.obb) are sent too, and installs pick up files an older scan skipped (Asgard's Wrath 2 got only main + patch.0 and hung at start-up, #471) 2026-10-23 22:16:44 -04:00
spoopyghosty0 398081b22f Agent: diagnostics include the three newest XRService logs, SteamVR's vrcompositor/vrserver logs, Steam's previous console log and steam.service's journal (a session that took Steam down kept no host-side logs, #441) 2026-10-23 22:14:02 -04:00
spoopyghosty0 fdaba13f51 FrameBridge: late-drawing check compares every pixel of rarely acquired panels (a sparse sample missed AC Nexus' text-only notice), read back asynchronously so frames never wait on it 2026-10-23 19:14:22 -04:00
spoopyghosty0 7fd9e20e21 Tests: lint fixes (f-string in the shared-folder launcher test, long CryEngine log line) that failed CI's ruff step 2026-10-23 19:14:19 -04:00
spoopyghosty0 595d12a038 FrameBridge: a flipped panel the app finishes drawing after xrEndFrame (no new acquire) is flipped again once its content settles (AC Nexus' calibrate-arms screen stayed upside down) 2026-10-23 17:56:31 -04:00
spoopyghosty0 9793e6dbae FrameBridge flip_dump: a quad still empty whenever it was flipped is saved ~1 s later as shown ("late") 2026-10-23 17:34:28 -04:00
spoopyghosty0 94783f564e Catalog: AC Nexus without device.text_input_window (its Android window took the controllers' input in the headset) 2026-10-23 17:31:05 -04:00
spoopyghosty0 4ab6b670d2 FrameBridge: flips and alpha inversion use the last released image (the one a layer shows), not the last acquired one; layer_debug logs quad swapchains/rects and each swapchain's first flips, flip_dump adds the image as shown ~3 s later 2026-10-23 17:22:43 -04:00
spoopyghosty0 e3e8fc4388 FrameBridge: a flip blit still running after 100 ms counts as done (it was flipped again next frame, so AC Nexus' panels stayed upside down at random); the shared command buffer waits for it before reuse 2026-10-23 17:00:21 -04:00
spoopyghosty0 e0638d6b6d Catalog: a newer remote entry this app can't use (unknown patch, setting, field or min_app) keeps the last usable one instead of falling back to the bundled entry; fields that stand for a patch are checked too 2026-10-23 16:41:34 -04:00
spoopyghosty0 09a329d54a Catalog: AC Nexus keeps the Quest 2 identity until the release with the Vulkan panel pool reaches users, with swapchain_pool on (also eases the panel limit behind the tutorial freeze, #424) 2026-10-23 16:29:40 -04:00
spoopyghosty0 4eff40ca64 swapchain_pool (Vulkan): pool chained and mipmapped panels, log every decline (#424)
The first device run (AC Nexus, Quest 3) pooled nothing and said nothing
about why. The pool declined any chained create info and any mipCount
other than 1; on Vulkan it now accepts a XrSwapchainCreateInfoFoveationFB
(irrelevant to a private image) and honours XrVulkanSwapchainCreateInfoMETA's
extra create flags and usage, and keeps the app's mip levels (barriers
cover every level, level 0 goes into the atlas). GLES keeps its rules.

Every decline is logged once per reason ("swapchain_pool: not pooled:
..."): session mismatch (also from the proactive check), array/faces,
samples, mips, usage, flags, size, format, chained struct type, Vulkan
device, GL context, slots, atlas refused, image allocation, atlas full;
plus one line when the 8-swapchain trigger starts pooling. The
xrCreateSwapchain log gains mips= and the first chained struct type.

Harness: the device sequence (1728 eye set, 2x2 and 1024x1024 usage 0x39,
2016 eye set, twelve 0x39 panels with foveation/META chains and a 4-mip
panel, flip-tracked runtime creates) pools every panel and the 2592x2256
set then fits under a 15-swapchain cap; decline reasons are checked.
2026-10-23 16:22:39 -04:00
spoopyghosty0 7a194ccaa0 Fix #424: Vulkan panel pool for swapchain_pool, AC Nexus back to Quest 3
swapchain_pool now also covers Vulkan sessions (XR_KHR_vulkan_enable/2):
from eight live app swapchains, single-layer format-43 colour panels get
private device-local VkImages (app usage + transfer, returned as
XrSwapchainImageVulkanKHR, UNDEFINED -> COLOR_ATTACHMENT_OPTIMAL at the
first acquire) packed into up to two 4096x4096 sRGB runtime atlases.
xrEndFrame records one command buffer per frame on the binding's queue
(3-deep fence ring, submits under flip_lock): vkCmdCopyImage from each
referenced panel into the waited atlas image, which returns to
COLOR_ATTACHMENT_OPTIMAL before its release. Image ownership, crops and
layer ordering follow the GLES pool; the whole layer rewrite holds the
pool lock so a destroy cannot free an image with recorded copies.
Pooled Vulkan panels stay tracked by flip_vk.c (in-place flips keep
working). Other formats and arraySize-2 eye images keep runtime
swapchains. GLES behaviour is unchanged.

AC Nexus: Quest 3 identity again with swapchain_pool=1 (min_app 1.3.1),
frame.adapter revision 3 for it only. Settings text, triage diagnosis,
PLAYBOOK, DEVICE_NOTES, native README, PATCHES.md and the i18n template
updated. Host harness gains a recording Vulkan double (layouts, copy
regions, ring, failures, cleanup, AC Nexus swapchain count: 12 live with
the new eye set). Not verified on the device.
2026-10-23 16:11:59 -04:00
spoopyghosty0 697b774248 Tests: plain summary for device.shared_folder, outlined icon on the game page, Climb 2's adapter revision in the audio-geometry test 2026-10-23 15:14:39 -04:00
spoopyghosty0 c01257847b Hardware-video launchers log who holds the Iris decoder at start (Steam's web helper blocked 8K cutscenes, #437); room tests run from paths with spaces 2026-10-23 15:08:50 -04:00
spoopyghosty0 cb954b6fd0 device.shared_folder: a folder of /sdcard shared with another game (JKXR's companion app and /sdcard/JKXR, #440) 2026-10-23 14:59:45 -04:00
spoopyghosty0 e4ffc4eb8a Share invitation also for catalog recipes still marked unknown or with issues once the game was played or passed a launch test (#310/#329) 2026-10-23 14:26:29 -04:00
spoopyghosty0 bccd916fab a32 bridge: export libmediandk's AMEDIAFORMAT_KEY_* data symbols, which Unity's video player also looks up (#439)
On the device Unity got past AMediaFormat_new and stopped at AMEDIAFORMAT_KEY_AAC_PROFILE, falling back to its JNI path again. The guest runtime now defines the 25 keys libunity.so references (AOSP's values; the host's libmediandk compares key names by content) and exports them; the harness checks each one via dlsym and uses them as format names. Ghost Giant: package revision 3.
2026-10-23 14:19:17 -04:00
spoopyghosty0 e76366728c cortopia_org_id: TMNT by its package instead of an ANALYSIS_VERSION bump (no library-wide re-analysis for one game) 2026-10-23 14:16:10 -04:00
spoopyghosty0 fffe6c088c frame.cortopia_org_id: also TMNT: Empire City's Login (no .Meta namespace), Cpp2IL nested-type method lookup (#422)
TMNT: Empire City awaits Users.GetOrgScopedID in Cortopia.Scripts.Platform.OculusPlatform.<Login>d__17 (after the
licence check and GetLoggedInUser, behind the same internetReachability == LAN check as Escaping Wonderland), which
OVRPort's platform library never answers. The patch now also looks there (parse_methods: "<Login>d__.MoveNext" =
that nested type's MoveNext; a plain MoveNext would be FetchEntitlements'), the analysis flag also covers
OculusPlatform directly in Cortopia.Scripts.Platform (ANALYSIS_VERSION 26), the triage signature matches the
<Login>d__ stack. The entitlement request is untouched.
2026-10-23 14:14:17 -04:00
spoopyghosty0 dcbcce0f66 a32 bridge: NDK media (AMediaFormat/AMediaCodec/AMediaExtractor) for Unity's video player, codec buffers mirrored in guest memory (#439)
Unity 2017.4 (Ghost Giant) looks up 43 libmediandk functions and fell back to its JNI path when AMediaFormat_new was missing; that path reads MediaCodec ByteBuffers above 4 GiB (GetDirectBufferAddress returned 0), so the intro video never played. Format strings/buffers get guest copies freed with the format; input buffers are mirrored and copied to the codec at queueInputBuffer, output buffers copied in at getOutputBuffer (the range dequeueOutputBuffer reported). Harness: fake libmediandk with buffers above 4 GiB + guest test library. Triage a32-video-ndk; Ghost Giant gets Update on Frame.
2026-10-23 14:09:29 -04:00
spoopyghosty0 0578954826 artifacts: SHA256SUMS for codec revision 11 2026-10-23 14:09:26 -04:00
spoopyghosty0 69c61ac914 Diagnostics: the USB cable link's state on both sides (Frame usb0/UDC/gadget/services, PC addresses and adapters) and a logged cable wait (#398) 2026-10-23 14:08:17 -04:00
spoopyghosty0 0c4493af44 Game page and CLI warn about an .obb named for another package than the APK (a renamed build's data, #129) 2026-10-23 14:04:41 -04:00
spoopyghosty0 9612812609 GAZZLERS: take the Meta Quest platform path instead of stopping with "Current Platform is not supported" (#404)
The game picks Meta/PICO from SystemInfo.deviceModel and throws for Lepton's
Valve Lepton. frame.gazzlers_quest_platform (catalog recipe) makes
PlatformDeterminer.GetAndroidPlatform return Platform.Meta (Cpp2IL lookup);
triage signature, PLAYBOOK row, catalog entry, test.
2026-10-23 13:58:23 -04:00
spoopyghosty0 b1ba609e79 Lepton games get the Frame's time zone: a readlink shim on the launcher's PATH resolves SteamOS' relative /etc/localtime for Lepton (#429) 2026-10-23 13:58:04 -04:00
spoopyghosty0 9e2fce433f Video decoder: videos up to 640x480 decode in software so they never hold Iris (codec revision 11); notes on 8K (#437)
Iris takes an 8K session only while no other is open. Checked in Batman's container on the dev Frame (SteamOS 0.5.6):
the small video now stays off Iris, but DRM2.mp4 (8192x4096 HEVC) is still refused because Steam's web helper keeps
the Iris decoder open, so Batman's 8K cutscenes stay in software. hold_probe.cpp holds a decoder for such tests.
2026-10-23 13:44:54 -04:00
spoopyghosty0 ae2846f852 FramePort on the Frame: game data on the same drive is hardlinked into the install instead of copied, so games don't take twice the space (#433) 2026-10-23 13:32:47 -04:00
spoopyghosty0 913d06afa9 Type on Frame: Copy from Frame puts the Frame's clipboard (Desktop Mode's Plasma, else gamescope's X displays) on this PC's (#413) 2026-10-23 13:30:18 -04:00
spoopyghosty0 fee75576cf Files: Backspace goes to the folder above, and going back up returns to where that folder's list was scrolled (#411) 2026-10-23 13:26:44 -04:00
spoopyghosty0 2cca7d6012 Type on Frame: the agent releases a held key the PC stopped refreshing, so a lost key release can't repeat on the Frame without end (#411) 2026-10-23 13:25:37 -04:00
spoopyghosty0 12ed206a85 frame.launcher: a launcher on an <activity-alias> alone gets moved onto its target activity, which Lepton can start (HOTD2 VR, #400/#469) 2026-10-23 13:19:40 -04:00
spoopyghosty0 4fd46ba023 QuestCraft: frame.pojlib_connection counts the Frame's network as online, so it downloads its Java runtime (#468)
pojlib's API.hasConnection() only counts Wi-Fi; Lepton's Android reports Ethernet, so the JRE download was skipped
("libjvm.so not found", GitHub #18). hasConnection() returns true (in-place classes.dex edit). Catalog recipe +
QuestCraft's package (no ANALYSIS_VERSION bump for one game family; new scans record pojlib_connection), triage
questcraft-no-java-runtime, PLAYBOOK row. Checked on the dev Frame: the installed APK carries the edit and starts
(72 fps headless); the download itself runs only after Play in QuestCraft's menu, which needs the headset.
2026-10-23 13:13:52 -04:00
spoopyghosty0 a6a28aaf91 Scan: other expansion-file kinds named for the APK's package (Crisis Brigade 2's office.<ver>.<pkg>.obb) are sent too (#415) 2026-10-23 12:52:44 -04:00
spoopyghosty0 8fedb37860 Rescan: another version of a game whose files are gone is offered in a dialog with Use this version, instead of a summary line (#427) 2026-10-23 12:50:53 -04:00
spoopyghosty0 2ecaa56ead Steam library: Later is the default when FramePort runs on the Frame itself, and the waiting step says how to add the games now (#425) 2026-10-23 12:46:50 -04:00
spoopyghosty0 890b2bc615 Linux apps: launchers put an unpacked app's own library folders on LD_LIBRARY_PATH, as the install's library check already assumed (#473) 2026-10-23 12:42:53 -04:00
spoopyghosty0 a8e01c01dc The Climb 1/2 start again: the dormant foveation diagnostic stays out of CryEngine's renderer (#432, #449)
1.3.0 linked libVkLayer_fdm_darken.so into every arm64 game's engine library; in libCryRenderVulkan.so CrySystem
initialization then fails right after the renderer lists its Vulkan device extensions, and the shutdown crashes
(SIGSEGV in CSystem::ShutDown). Bisected headless on the dev Frame by swapping libraries between the September
known-good APK and a current build: only the modified renderer breaks it. Climb 2's private VrApi bridge still
loads the layer itself (72 fps headless with this change). frame.adapter package revision 3 for both games;
triage cryengine-init-failed.
2026-10-23 12:41:02 -04:00
spoopyghosty0 a08d46a1b7 Embedded OpenXR loaders: the game's loader skips implicit API layers, so Valve's layer isn't stacked twice (crash at Play, #254) 2026-10-23 12:19:04 -04:00
spoopyghosty0 2fefb1e6d1 Catalog: AC Nexus keeps the Quest 2 headset identity (#424)
With Quest 3 the game switches to a 2592x2256 eye buffer after the intro; by then its UI panels have used up the
runtime's ~15 swapchains per session, so the new eye buffer is refused (XR_ERROR_LIMIT_REACHED) and it stops
drawing. Headless on the dev Frame, same build: Quest 3 frames stop, Quest 2 holds 72 fps.
2026-10-23 12:13:26 -04:00
spoopyghosty0 043955983f Catalog: PrimedGun v2 without the embedded-loader patch until its loader recursion is fixed (crash at Play, #254) 2026-10-23 12:02:54 -04:00
spoopyghosty0 ffe57c5c89 Diagnostics: read the bundled agent and bootstrap.sh as UTF-8; an ASCII default encoding made every diagnostics zip fail (#349) 2026-10-23 12:01:53 -04:00
spoopyghosty0 dd9f20049e Catalog: PianoVision unsupported (needs camera hand tracking and USB MIDI) (#297) 2026-10-23 11:56:41 -04:00
spoopyghosty0 26975686f9 Catalog: 15 community recipes (Drums Rock, Darksword, GoldenEye VR, Barbaria, Little Nightmares VR, Movie Deck for Plex, JKXR, SpaceControl, Solero, Orcs Must Die, Epic Roller Coasters, Simpsons Hit and Run VR, Deisim, Astro VR Host, Umurangi Generation VR)
From issues #409 #410 #412 #418 #421 #435 #441 #447 #448 #453 #456 #461 #462 #464 #472 via
scripts/catalog_from_issue.py. GoldenEye VR (no sound), JKXR (stutters after minutes) and Umurangi Generation
(freezes when saving a photo) are "issues"; Simpsons and Astro VR Host setup steps point to the Files tab, the
long instructions moved to details.
2026-10-23 11:54:10 -04:00
spoopyghosty0 459c62ba2d Room tab: the not-connected screen sits under the heading like the other tabs (the heading's expand, meant for its row with the buttons, took half the window's height when it stood alone) 2026-10-20 08:24:32 -04:00
spoopyghosty0 0df0bd16b5 hevc: tone map HDR (PQ/HLG) Main 10 to SDR BT.709 instead of flat colours
The software Main 10 path narrowed HDR10 pictures to 8 bits as they were, so
PQ shown as SDR looked grey and BT.2020 colours dull. hdr_tonemap.h maps
brightness with BT.2390's EETF (203 cd/m2 reference white = SDR white,
highlights rolled off up to MaxCLL / the mastering peak / 1000 cd/m2) and
converts colour per chroma sample through linear light into BT.709, moving
out-of-gamut colours toward grey of the same luminance. The component then
prefers its bitstream colour aspects, so surfaces and its RGBA conversion see
BT.709. Bands run in the colour helper threads (about 10 ms per 1080p picture
on one big core). Decoder revision 10; artifacts rebuilt with build.py.
2026-10-19 12:41:20 -04:00
Veticia Misumena 7128432e39 hevc: decode Main 10 in software instead of hanging on Iris
Iris on the Frame's kernel (6.18) offers HEVC Main 10 only into its
compressed Q10C capture format. The component always asks for NV12, and a
Main 10 stream in such a session returned no pictures: playback stayed at
0:00, the flush on leaving timed out (ACodec -110) and the next video hit
MediaCodec::reclaim, so every later decoder start in the app failed until it
restarted (seen in Bigscreen Beta with local files over DLNA).

- hevc_profile.h reads general_profile_idc from the parameter sets
  (CODECCONFIG or the first access unit, Annex B or hvcC); streams beyond
  Main never open Iris and decode in FFmpeg's software HEVC decoder, which
  the component already contains.
- Its 10-bit planar pictures are rounded to 8-bit planar before the existing
  outputs (no HDR tone mapping).
- The HEVC component lists Main 10 (level 5.1), so format-aware players
  select it instead of reporting NoSupport and using it anyway.
- Decoder revision 9; artifacts rebuilt with native/hevc/build.py (the same
  toolchain rebuilds revision 8 byte for byte).

Tested on a Steam Frame in Bigscreen Beta: 1080p and 4K Main 10 clips and a
real 1080p Main 10 episode play; 8-bit HEVC and H.264 afterwards play too.
FFmpeg's software HEVC decoder on the Frame's CPU, 4 threads as the
component uses: 1080p Main 10 episode 232 fps, synthetic 4K Main 10 72 fps.
2026-10-19 12:22:36 -04:00
spoopyghosty0 3268c3c412 Site: a Room tab in the clickable app (turnable 3D view of the showcase's made-up bedroom, pretend scan, raw scan vs clean-up, labels with the door suggestion); room data from scripts/showcase/site_room.py 2026-10-19 11:12:48 -04:00
spoopyghosty0 11dd195688 Site: release data refreshed (1.3.0) 2026-10-19 01:12:55 -04:00
spoopyghosty0 5b86843430 FramePort 1.3.0 2026-10-19 00:59:27 -04:00
spoopyghosty0 3e5044ce4a Site: contributor data and games list refreshed (1.3.0) 2026-10-19 00:58:53 -04:00
spoopyghosty0 5345434ba7 Lint: wrap long lines, raise ... from None in the room-scan lock, zip(strict=True) in the scene tests (CI's ruff check failed on the MR merge) 2026-10-19 00:57:08 -04:00
spoopyghosty0 0ca7bc45f0 Room tab: the right column sizes to its content (the Test Quest MR line was clipped when Delete room wrapped or the furniture chips took two rows); the top row stays level by measuring both sides (a short column's last card grows, a tall one makes the 3D view taller); box sizes under 10 cm show two decimals (a 3 cm rug was 0.0 m); room shots re-rendered 2026-10-19 00:23:58 -04:00
spoopyghosty0 a4702d2a13 Docs screenshots: re-rendered with the Room tab in the sidebar 2026-10-19 00:23:57 -04:00
spoopyghosty0 455bc987b2 Docs: the Room tab (experimental) in the README features, INSTALL.md and the site's app tour; showcase shots room + room-editing from a made-up bedroom (bed under a wall TV, desk with two monitors under a window, closet, door, lamp, plant; noisy scan mesh, clean-up report and labels to match); steps open_room / room_editing 2026-10-19 00:23:57 -04:00
spoopyghosty0 4b0b0daa6d Room tab layout: the top row ends level (legend on the 3D view, the right column as tall as it), Test Quest MR as one line in In this room, equal cards and gaps, full-width sliders and segmented tracks, one slider per row in the box editor, dropdown and Delete the same height, even suggestion buttons, aligned Labels columns and counts; clean-up report follows the scanner's scan.json keys (walked_skipped as a note, truncated as a warning) 2026-10-19 00:23:57 -04:00
spoopyghosty0 91f73fbd03 ui_smoke: Room tab editing steps (clean-up, more settings, box selected, doors, a suggestion taken, applying, applied); the pretend Frame cleans up and saves rooms; docs 2026-10-19 00:23:56 -04:00
spoopyghosty0 77b527f129 Room tab: Clean-up card (Recommended or your settings, the key ones in sight, More settings, Apply as a job, the last clean-up's counts), Labels card (rule decisions, Add as door / Add as closet), Furniture & screens editor (select in the list or by clicking the 3D view, type/move/size/turn, add/delete, doors and windows on a wall, Save) 2026-10-19 00:23:23 -04:00
spoopyghosty0 6ab6c11f06 Rooms: REFINE_DEFAULTS (the owner's clean-up defaults + slider metadata), rooms.refine / put_room, doors and windows on a wall and suggestion helpers in mr/room, view3d furniture overlay + picking, CLI frameport frame room refine [--set key=value] [--reset] 2026-10-19 00:23:23 -04:00
spoopyghosty0 92e84a1a4b Agent v107: room scan clean-up settings (rooms/refine.json, passed to every build), room_refine (fp_roomscan --refine-only on a copy of the room folder), raw files + scan.json kept with the room, room_status returns refine/report/labels/suggestions, edited rooms keep their boxes over a new clean-up 2026-10-19 00:23:22 -04:00
spoopyghosty0 a0b71fdfb7 Docs: room refinement (scan.md options + passes + parity, ROOM_FORMAT raw files and scan.json, CLAUDE.md MR line) 2026-10-19 00:23:22 -04:00
spoopyghosty0 3e8f0ce369 Tests: room refinement (floating pole + walked-through column removed, panels wind inward, --refine-only reproduces, --refine 0 = raw output, label rules on an older room folder) 2026-10-19 00:23:22 -04:00
spoopyghosty0 b65abb4b95 Room scanner: refinement + label rules after the mesh (raw files, scan.json, --refine-only)
The owner's tuned room-scan cleanup (2026-10-18) ported to C, pass for pass: plane offsets re-estimated from the
scan, one-sided structural bands, flat wall/floor/ceiling panels (or snap), near clearing, erase spheres, the walked
volume from the recording's head path, furniture tops, clipping with the unseen-edge allowance, islands, thin
floating pieces, Taubin smoothing; label rules on the scanner's volumes (merged/nested/outside boxes removed, shape
relabelling, SCREEN flatness from the raw mesh, door/closet suggestions in scan.json).

room.txt + room-mesh.bin are now refined (ceiling re-estimated); the unrefined output stays as room-raw.txt +
room-mesh-raw.bin with the same UUIDs; scan.json holds heads, settings, report, labels, suggestions. The scan path
refines its raw files as read back, so --refine-only on them reproduces the scan byte for byte; --refine 0 writes
the old output. The fusion grid is freed before the refinement (peak memory unchanged).
2026-10-19 00:23:22 -04:00
spoopyghosty0 0478588886 Tests: map the floor plan back with forward (-Z) at the top, as preview_svg now draws it (4f871b20) 2026-10-19 00:23:21 -04:00
spoopyghosty0 1a5892ee40 RoomCanvas: a room full of furniture draws only its outlines while the view moves (smaller patches) 2026-10-19 00:23:21 -04:00
spoopyghosty0 e3788c0b2b Room tab: fit the view to the scan without its stray far-off bits (2nd-98th percentile), rounded icons, US spelling 2026-10-19 00:23:20 -04:00
spoopyghosty0 feda5f4a03 Docs: the Room tab (INSTALL.md, CLAUDE.md UI notes) 2026-10-19 00:23:20 -04:00
spoopyghosty0 6d9fb0b1e6 ui_smoke: Room tab steps; the pretend Frame has a made-up scanned room with a mesh, a scan that steps forward and can be cancelled 2026-10-19 00:23:20 -04:00
spoopyghosty0 b78160ca6f Room tab: scan in the headset with progress and Cancel, play area, delete, the room in 3D (window + full browser view), what's in it, an experimental pill and a Test Quest MR tip; the room cache moves to ui/room_state.py (mesh cached per Frame in rooms-cache), the Frame page keeps a short room card with Open Room 2026-10-19 00:23:20 -04:00
spoopyghosty0 20c36b112e RoomCanvas: the room in 3D inside the window (Flet canvas, one redraw worker at <=18 fps through a LoopUpdater, fewer mesh edges while moving; drag turns, scroll/pinch zooms, right-drag moves, double-click fits) 2026-10-19 00:23:19 -04:00
spoopyghosty0 fcfba77f31 Room 3D models: mr/view3d (walls, furniture boxes, mesh reduced to a few thousand edges, orbit camera, dollhouse projection) and a token-protected 127.0.0.1 server for a self-contained WebGL room page (FPRM parsed with DataView) 2026-10-19 00:23:19 -04:00
spoopyghosty0 8870afe18a Room scans can be cancelled: agent room_capture_stop (agent 106) stops the scan job and marks it cancelled; rooms.cancel_scan, rooms.scan raises ScanCancelled 2026-10-19 00:23:19 -04:00
spoopyghosty0 4be04b8a34 Room floor plan: seen from above with forward (-Z) at the top; it had +Z at the top with +X still on the right, i.e. the room mirrored 2026-10-19 00:23:18 -04:00
spoopyghosty0 e231c5a6fe scene: drop PR #246's per-call semantic-label log line (it logged every call; mr-scene logs each entity's labels once), as in the PR's merge 2026-10-19 00:23:18 -04:00
spoopyghosty0 7585acd0a8 Tests: the quest_buttons harness declares scene_app_mesh (mr-scene's xrCreateInstance sets it; the native test didn't compile) 2026-10-19 00:23:18 -04:00
spoopyghosty0 b9fb5791b0 Regenerated docs/PATCHES.md, site patches.json and the locale template for the two new patches 2026-10-19 00:23:17 -04:00
spoopyghosty0 a5199495fd Artifacts: FrameBridge (arm64-v8a + armeabi-v7a) rebuilt from the merged source (PR #246's layer limit and quad filter on mr-scene's scene emulation); xrshim rebuilt, unchanged bytes; SHA256SUMS regenerated (now also lists the roomscan finish_*.png prompts, which it had missed). None of PR #246's binaries are kept. 2026-10-19 00:23:17 -04:00
spoopyghosty0 28a5795323 Docs: PLAYBOOK rows for depth occlusion, the player-in-room check and the layer limit; DEVICE_NOTES note on what PR #246 brought into mr-scene 2026-10-19 00:23:16 -04:00
spoopyghosty0 d6cf9a3503 Tests: restore the scan test's APK inside a PC program folder (PR #246 had made it a .dll, which no longer tests anything); ruff fixes in the PR's test 2026-10-19 00:23:16 -04:00
spoopyghosty0 2a769dddba Catalog (PR #246): min_app 1.2.2 on the MR recipes (they need this branch's layer limit and room emulation); drop the com.mrf.* copies of games the catalog already has (com.kluge.SynthRiders, com.PotamWorks.SmashDrums, jp.co.hit_point.vneko: same titles, other package ids, they listed every game twice); LEGO Bricktales back to 'use VR mode' (MR not verified, its recipe turns no MR setting on); honest notes where no tested version was recorded 2026-10-19 00:23:15 -04:00
spoopyghosty0 7a65e86cdc FrameBridge layer limit: FrameBridge's own fade quad is always kept with the projection layers, the app's other layers fill the rest in submission order; one log line per trim (at most 5), trimmed layers no longer counted as unusable 2026-10-19 00:23:15 -04:00
spoopyghosty0 2be8873fec frame.meta_depth_occlusion: offered but not turned on by detection, only for 64-bit IL2CPP Unity games; asset files are streamed and only those with the keywords rewritten (max 512 MiB); Laser Dance's asset fixes only for the build whose original values all match; revision 1
- detect: many Meta XR SDK games carry the Depth API without using it; until a headset check shows more games
  with the symptom (or OVRPort is found advertising XR_META_environment_depth, which a FrameBridge hide setting
  would fix generally), the patch comes from Laser Dance's catalog recipe or the user's choice.
- ApkWorkspace.size/contains: entries are searched in 4 MiB chunks instead of read whole.
- Laser Dance: the fixes' original values at all seven places together identify the build (no versionName was
  recorded with them); another build gets none of them.
- tests: lz4 is skipped when missing, the known/unknown Laser Dance build, chunked search.
2026-10-19 00:23:14 -04:00
spoopyghosty0 7d5ed42d18 frame.unity_scene_active_rooms: never suggested (catalog recipe or the user's choice, Laser Dance), shown only for Unity scene games; plain summaries for both new Unity patches, stray blank lines removed
The PR turned it on for every Unity game with USE_SCENE or MRUK's library: a game-logic change keyed to one
game's symptom (MRUK games mostly don't use OVRSceneManager at all). A scanned room around the player usually
passes IsUserInRoom by itself.
2026-10-19 00:23:14 -04:00
spoopyghosty0 90bf8bcd67 adapter: scene_emul needs the xrshim through XRSHIM_SETTINGS already (mr-scene); drop PR #246's duplicate 2026-10-19 00:23:14 -04:00
spoopyghosty0 d028390da5 Library: drop PR #246's meta_spatial_permissions and meta_depth_occlusion migrations and the re-analysis hook that forced frame.meta_depth_occlusion into user recipes (mr-scene's scene_permissions covers the room games; non-user recipes follow detection and the catalog after the analysis bump; user recipes stay as edited) 2026-10-19 00:23:14 -04:00
spoopyghosty0 0a542d849e xrshim: emulated functions again only for a real instance (OpenXR: XR_NULL_HANDLE serves only the pre-instance functions; with mr-scene the shim would otherwise hand out the routed xrPollEvent/xrLocateSpace) 2026-10-19 00:23:13 -04:00
alicecatpaw 09358fb65e Address review comments on meta_depth_occlusion
- Limit _patch_shader_proximity_fade to known builds (Laser Dance) and known shader signatures/keywords to avoid modifying unrelated shaders
- Rename HARD_OCCLUSION and SOFT_OCCLUSION keywords in .assets files only, leaving global-metadata.dat intact so managed code cannot enable renamed occlusion variants
- Defer meta_depth_occlusion library migration for entries analysed before the field existed until re-analysis, and update user recipes on re-analysis
- Bump ANALYSIS_VERSION to 23 so older library entries are re-analysed for meta_depth_occlusion
2026-10-19 00:23:13 -04:00
alicecatpaw ae49d886da Address review: bump ANALYSIS_VERSION to 14, restore hand-tracking heuristic, and fix library migration 2026-10-19 00:23:13 -04:00
alicecatpaw 7afaa2629b Add catalog recipes for Neko Atsume, Punch Fit, Smash Drums, and Hitstream 2026-10-19 00:23:12 -04:00
alicecatpaw 5e27333f74 Add catalog recipes for Laser Dance and Synth Riders MR modes 2026-10-19 00:23:12 -04:00
alicecatpaw 68f278a744 Add Meta depth occlusion and active room patches for Unity MR games
- Implement frame.meta_depth_occlusion to zero out Meta EnvironmentDepthManager methods in libil2cpp.so and neutralize close-proximity depth shader occlusion in Unity assets

- Implement frame.unity_scene_active_rooms to bypass Meta OVRSceneManager active room position evaluations in libil2cpp.so

- Recommend frame.meta_permissions when spatial data or scene permissions are declared

- Remove redundant hand-tracking heuristic forcing controller_fix=0

- Add unit tests for depth occlusion, active room bypass, and manifest heuristics
2026-10-19 00:23:12 -04:00
alicecatpaw a0c26c9646 Emulate Meta spatial entity discovery and enforce runtime layer limits
- Emulate XR_META_spatial_entity_discovery (xrDiscoverSpacesMETA, xrRetrieveSpaceDiscoveryResultsMETA) and XR_META_boundary_visibility
- Add system properties for space discovery and boundary visibility
- Fix semantic labels length and null termination
- Allow xrGetInstanceProcAddr with null handle for emulated procs in xrshim
- Trim composition layers exceeding runtime maxLayerCount in xrEndFrame and validate quad extents
- Hook xrshim when scene_emul is enabled in adapter settings
- Update prebuilt native artifacts and checksums
2026-10-19 00:23:12 -04:00
spoopyghosty0 45900ef294 Installing a room-emulation game syncs the room scanner and its headset prompts to the Frame (in-game scan requests used whatever copy a PC-started scan had left there, e.g. none on a fresh Frame or without the new "Almost done" prompts) 2026-10-19 00:23:11 -04:00
spoopyghosty0 95eed63460 MR scan: once every direction, the ceiling and the floor are covered before the minimum scan time, the prompt says "Almost done" with the time left instead of a ring stuck at 12/12 (owner turned past 360 degrees waiting) 2026-10-19 00:23:11 -04:00
spoopyghosty0 04d03b8f87 MR scan preview: one calm colour (FramePort's secondary blue, opacity by floor/furniture/wall), filled 10 cm squares instead of 3x3 blotches, fainter, sort order below the scan prompts (owner: colours and layers clashed) 2026-10-19 00:23:11 -04:00
spoopyghosty0 6617941d47 MR scan preview (agent 104): a world-locked floor map overlay shows what the headset scan has covered (10 cm cells: floor grey, furniture orange, walls blue), redrawn at most once a second; also in game-requested scans; --no-preview / preview:false; disables itself on overlay errors or slow uploads 2026-10-19 00:23:10 -04:00
spoopyghosty0 05344906ef MR diagnostics: log room-entity locates (base space, flags; every one without both valid bits): MRUK keeps an anchor pending forever otherwise (Pinball FX's load never succeeds) 2026-10-19 00:23:10 -04:00
spoopyghosty0 94ece1a232 MR scan on request (FrameBridge): a capture request asks FramePort to scan (request/ack/result files), holds the completion, reloads the scanned room on ok, fails with XR_ERROR_RUNTIME_FAILURE otherwise, falls back to the stored room without a scanner (setting scene_scan_request, default on) 2026-10-19 00:23:10 -04:00
spoopyghosty0 38bd178aa3 MR scan on request (Frame side, agent 103): launch.sh watcher _scan_watch runs the headset room scan when FrameBridge requests one (request/ack/result files in the game's external files dir), saves it as the current room and copies it into the game folder 2026-10-19 00:23:09 -04:00
spoopyghosty0 56c821cce3 Triage: no scene-missing / mr-discovery-unsupported warning when FrameBridge serves the room (they matched OVRPort's extension list and the shim's own routing line; TestQuestMR saw the full room) 2026-10-19 00:23:09 -04:00
spoopyghosty0 3298c5f64d MR: scene capture completes after 1.5 s like a real scan (Pinball FX re-asked at once); log each room query per entity and the labels an app gets (with its support info) 2026-10-19 00:19:18 -04:00
spoopyghosty0 087ad75f47 MR: shim-routed generic calls handle only fake room spaces and room events; real ones go to OVRPort's dispatcher (its headset identity, events and controller spaces were skipped for every scene_emul game: Vermillion's controllers, NOPE) 2026-10-19 00:19:18 -04:00
spoopyghosty0 460c503e43 MR diagnostics: log the head against the floor outline when a game looks for the room (MRUK's current room; Pinball FX asks for a scan again and again) 2026-10-19 00:19:17 -04:00
spoopyghosty0 3687a6eb0d MR: Meta scene/anchor permissions with every scene_emul recipe (migration scene_permissions; NOPE/Pinball never asked for the room), emulate XR_META_boundary_visibility, log the app's passthrough calls 2026-10-19 00:19:17 -04:00
spoopyghosty0 e07441fb09 MR: hiding the STAGE bounds becomes per-game setting scene_hide_bounds (Demeter on; NOPE stalled on a black screen without a play area) 2026-10-19 00:19:16 -04:00
spoopyghosty0 212801ead2 Cpp2IL: run with invariant globalization (.NET aborts without libicu on fresh WSL/Linux); don't cache .NET start failures as unreadable games, retry old cached ones; CLAUDE.md/PLAYBOOK: STAGE bounds note 2026-10-19 00:19:16 -04:00
spoopyghosty0 7971354675 MR: hide the STAGE bounds from scene-emulation apps (OVRPlugin can't outline the Frame's 1x1 m rect: Demeter's guardian check threw), box walls in loop order 2026-10-19 00:19:15 -04:00
spoopyghosty0 c3144f65dd MR: room entities offer SHARABLE like Meta's runtime; log refused scene components (Demeter rejected the room) 2026-10-19 00:19:15 -04:00
spoopyghosty0 210d6e80c5 MR: rooms older Meta SDKs accept (labels as Meta's runtime maps them, GLOBAL_MESH only with the mesh extension), rectangular rooms from perpendicular walls, ceilings found after a short look up, 60 s minimum scan 2026-10-19 00:19:15 -04:00
spoopyghosty0 f8ee87145f MR scan: record only while passthrough streams meshes (a leftover block started a scan), pause + prompt when it stops, refuse scans under 30 frames 2026-10-19 00:19:14 -04:00
spoopyghosty0 52df211266 MR scan prompts: starts by itself (no passthrough wait), ceiling then 'look back down', floor step, finish early once everything was seen 2026-10-19 00:19:14 -04:00
spoopyghosty0 976260ed14 MR: agent and PC room parsers accept the optional wall label (scanner output was refused) 2026-10-19 00:19:13 -04:00
spoopyghosty0 893db92985 MR: scene emulation always brings the xrshim (OVRPort's dispatcher refuses scene calls; Pinball FX VR) 2026-10-19 00:19:11 -04:00
spoopyghosty0 a690d0ee3f Ship robust room scanner and document capture performance 2026-10-19 00:18:59 -04:00
spoopyghosty0 d48dcaba4e Fit stable room surfaces from smoothed depth fans 2026-10-19 00:18:58 -04:00
spoopyghosty0 f68c7f4232 Skip unusable tracking frames and reject inpainted depth 2026-10-19 00:18:58 -04:00
spoopyghosty0 fc5933bb2a Ship deterministic room scanner artifact and device validation notes 2026-10-19 00:18:58 -04:00
spoopyghosty0 0e41e1fcca Validate room scanning geometry and harden bounded reconstruction 2026-10-19 00:18:56 -04:00
spoopyghosty0 bbb05cfc0b Add offline room reconstruction and synthetic depth renderer 2026-10-19 00:18:44 -04:00
spoopyghosty0 71a427ac0f CLAUDE.md: mixed-reality room scanning notes 2026-10-19 00:18:44 -04:00
spoopyghosty0 e8eea8548c MR: scan the room in the headset - RoomView 3D capture with headset prompts, wall labels, agent 92
The agent records Valve's passthrough depth mesh (IVRBlockQueue + IVRPaths, Background/Overlay OpenVR app), converts
poses with the final raw->standing transform, shows pre-rendered prompts as a SteamVR overlay, then builds the room
with fp_roomscan (room_capture / room_capture_status). PC: rooms.scan, Frame page progress, frameport frame room scan.
FrameBridge reads the optional wall label (INVISIBLE_WALL_FACE). ROOM_FORMAT: outline orientation stated exactly.
2026-10-19 00:18:42 -04:00
spoopyghosty0 ab4bb5b68d Finish room launcher integration and document device validation 2026-10-19 00:18:40 -04:00
spoopyghosty0 ee902e4c40 Diagnose missing MR rooms and unsupported scene discovery 2026-10-19 00:18:16 -04:00
spoopyghosty0 e1fd4fd244 Enable scene emulation for scene and spatial anchor games 2026-10-19 00:18:15 -04:00
spoopyghosty0 a5172c1e2f Show room readiness and floor plans in the Frame UI 2026-10-19 00:18:12 -04:00
spoopyghosty0 5c9d2e5c62 Add room CLI and reuse host helper synchronization 2026-10-19 00:18:11 -04:00
spoopyghosty0 79c5a210f8 Store rooms on the Frame and synchronize Quest launchers 2026-10-19 00:18:10 -04:00
spoopyghosty0 4864703e11 Add portable room format validation and floor plan previews 2026-10-19 00:17:51 -04:00
spoopyghosty0 b3e5b2401e Document scene implementation validation and exact device handoff 2026-10-19 00:17:51 -04:00
spoopyghosty0 301f734dbf Rebuild FrameBridge scene emulation artifacts deterministically 2026-10-19 00:17:49 -04:00
spoopyghosty0 577b72969a Verify shim routing and protect erased or stale scene handles 2026-10-19 00:17:34 -04:00
spoopyghosty0 11ccdb7fac Test room geometry discovery persistence and malformed data on the host 2026-10-19 00:17:33 -04:00
spoopyghosty0 7fe604dbec Report scanned room or guardian box on scene capture requests 2026-10-19 00:17:33 -04:00
spoopyghosty0 2306b2e788 Route all emulated scene APIs and fake space consumers through the shim 2026-10-19 00:17:33 -04:00
spoopyghosty0 65b39a51ca Persist random UUID application anchors across sessions 2026-10-19 00:17:32 -04:00
spoopyghosty0 8473fe429e Add META discovery and persistence entry points and events 2026-10-19 00:17:32 -04:00
spoopyghosty0 3586d520d3 Expose room polygons volume bounds and triangle meshes 2026-10-19 00:17:32 -04:00
spoopyghosty0 79f60057fa Load scanned STAGE room files and bounded mesh sidecars 2026-10-19 00:17:31 -04:00
spoopyghosty0 77b01cbadb MR: optional wall label in room.txt; in-headset scan prompts (render_prompts.py) 2026-10-19 00:17:31 -04:00
spoopyghosty0 b9cb73a6c7 MR: Phase 0 findings - Valve's RoomView 3D mesh is readable through IVRBlockQueue/IVRPaths 2026-10-19 00:17:31 -04:00
spoopyghosty0 11a677ed1c MR: room file contract (room.txt, room-mesh.bin, scan dumps) 2026-10-19 00:17:30 -04:00
spoopyghosty0 d3a0846775 Release prep: the #406, #254 and #387 fixes together on main
Adapter rebuilt from the combined source (fixed_resolution + swapchain_pool), libfp_xrruntime.so back in SHA256SUMS, ANALYSIS_VERSION 24 for static OpenXR loaders (23 is frame.main_process), agent v108 for the static-loader launcher line (above the MR branches' 104-107 so a Frame with one of those still updates), patch docs and translations template regenerated, Ruff line length.
2026-10-19 00:10:31 -04:00
Codex 25db57f468 Fix #387: pool GLES panel swapchains before the runtime count limit
Add opt-in swapchain_pool with private GLES images and up to two packed
runtime atlases. Start at eight live app runtime swapchains to reserve
headroom before the session cap. Preserve image ownership, GL state,
source fences, crops and the existing cylinder/equirect layer ordering.

Enable for 4XVR, add count-limit triage without unknown suggestions for
older apps, and document the pending headset menu check. Leave default
recipes and adapter revisions unchanged. Rebuild arm64/arm32 artifacts.

Validation: 132 targeted tests passed (2 skipped), including the native
runtime/GL harness; Ruff and generated docs pass. Full host suite:
2095 passed, 137 skipped, 12 failures and 16 setup errors, all denied
socket creation in this sandbox. No headset validation or push.
2026-10-19 00:04:16 -04:00
Codex bd2a742356 Route embedded Khronos OpenXR loaders through FrameBridge
Detect and redirect static loader manifests and Android brokers, ship a runtime negotiation shim and the inner loader chain, and maintain per-game manifests on install and launch. Add the PrimedGun recipe, triage and host coverage.
2026-10-19 00:03:49 -04:00
spoopyghosty0 d0a2d89c92 Keep opt-in OpenXR layer recommendations at full swapchain resolution (#406)
Route OVRPlugin recommendations through the existing extension shim, retain native loader hooks, and log projection rect changes once per second per eye. Enable the fix for Batman, document verification, and rebuild both adapter architectures.
2026-10-19 00:03:20 -04:00
spoopyghosty0 12025e73dd Catalog: Test Quest MR (works)
Verified on the Frame 2026-10-18 with 0.2.1 (room, planes, mesh and anchors through FramePort; with frame.meta_permissions and scene_emul, the MR heuristics' picks).
2026-10-18 19:36:03 -04:00
spoopyghosty0 8d4fb7b6e1 Catalog: KillerFrequency and cubism (works)
Closes #402
Closes #403
2026-10-18 14:23:19 -04:00
spoopyghosty0 4b513e195f Gamepad for 2D apps: own button layout (swap sticks, swap A/B, own .kl lines) and Steam's controller log in diagnostics (#162); fix main's CI
Steam Input's per-game remapping doesn't reach a 2D app; device.steam_gamepad's options now change the buttons
inside the app: the launcher exports FRAMEPORT_GAMEPAD_LAYOUT/_KEYS, the agent's Podman wrapper mounts a per-game
key layout (agent v103). Diagnostics of such games carry gamepad.log and Steam's controller activation lines. The
game page shows a patch's on/off options under it while it's on.
CI: locales template refreshed; frame.main_process counts as a patch that works on the 32-bit bridge.
2026-10-18 12:57:04 -04:00
spoopyghosty0 206a2448b3 Triage scene-missing: extension listings don't count (OVRPlugin Name=, OVRPort's list, Unity's Extensions=) (#404) 2026-10-18 12:40:10 -04:00
spoopyghosty0 104c003c44 frame.main_process: run a game activity that has its own process in the main one (#178)
Halo CE VR's HaloActivity runs in :halo_game; Lepton starts it directly and watches only the main process, which
never exists, so it closed the game about a minute in ('Target app ... did not start'). Analysis field
separate_process (ANALYSIS_VERSION 23), default-on patch, triage app-separate-process, PLAYBOOK row.
2026-10-18 12:35:48 -04:00
spoopyghosty0 b281cd5fdb Catalog: HardBullet (issues: cube loading screen, view freezes during loads)
Closes #385
2026-10-18 12:17:35 -04:00
spoopyghosty0 4fec0656ff OpenGL ES shader dump/fix offered for Unity games whose boot.config mentions Vulkan; either setting brings in the shader-fix layer (#382)
SynthRiders is analysed as 'Vulkan (Unity boot.config)' but renders with GLES on Zink, so the dump was hidden in
Game settings and session triage's suggestion was dropped; the dump setting alone also never added the layer.
2026-10-18 12:14:42 -04:00
spoopyghosty0 a205743561 Catalog: BattleTalent online rooms need Meta's account check, LAN works (#408) 2026-10-18 12:06:49 -04:00
spoopyghosty0 dd3bdf5d35 Catalog: Test Quest Controllers (works)
Verified on the Frame 2026-10-18 with 0.2.2: controller types, highlighting, vibration and passthrough; switching types restarts the app on the Frame (SteamVR runtime limit).
2026-10-18 11:07:29 -04:00
spoopyghosty0 ca10e109e6 Settings → Controllers recommends Test Quest Controllers for trying the button modes
A callout under the controller diagram (Get Test Quest Controllers: FramePort's own install question for its install link; Open … once it's in the library), a tooltip on the button, and the controller buttons help text points to it. ui_smoke gets a settings-controllers step.
2026-10-18 10:52:08 -04:00
spoopyghosty0 4e8486418f Install links: Check for updates on the game page; links without a version are checked too
Games installed from an install link get a row on the game page (where it came from, the installed version) with Check for updates, and the same entry in the page's menu: it asks the link now instead of waiting for the 6-hourly check. Manifests that named no version (e.g. an app's first release) were never checked; the installed APK's own versionName (from the analysis) is now the version to compare with, in the automatic check, the button and frameport link-updates.
2026-10-18 09:47:02 -04:00
spoopyghosty0 d801ff6bc8 Controller buttons: second button up and toward the other hand like Quest (Quest pair: Y = d-pad right, B = X; Mirror follows); d-pad touch is one sensor 2026-10-18 09:23:52 -04:00
spoopyghosty0 c67f79ebc6 Install-link update: take the new download instead of failing ('couldn't be read as an Android app')
Updating a game from its install link downloads the new APK into its own folder; the scan then finds it as another version of a library game (#351 relinking), switches the entry to it and returns nothing, and add_from_link reported that as an unreadable APK, so the update stopped before the link version was recorded. add_from_link now takes the entry from the scan report; if the scan left the library's copy (still on disk), the link switches the game to the download like Update with a newer APK.
2026-10-18 08:54:23 -04:00
spoopyghosty0 c469327590 Monitor: idle Frame no longer shows 100 % GPU (agent v102)
msm reported SteamVR's compositor engine time near 2^64, rising ~1000x faster than real time, so the summed GPU busy
was pinned at 100 % on an idle Frame. Each render fd is now tracked on its own; a delta longer than the interval
falls back to drm-cycles-gpu / GPU clock. Checked on the dev Frame: installed agent 100 %, this one 0.0 % at 231 MHz.
2026-10-18 08:51:02 -04:00
spoopyghosty0 b00abe3ce1 Install-link update toast gets an Update button
It said a newer version was available but offered no way to get it from there (the Library bar and the game page
had the button).
2026-10-18 08:46:30 -04:00
spoopyghosty0 eaf4e3d5b6 Game page: rounded save icon (UI style check) 2026-10-17 22:27:12 -04:00
spoopyghosty0 05f221b216 pop_dialog() closes the pop-up, never a toast (install-link question stayed open)
Flet 1.0 keeps toasts in the same stack as dialogs and pop_dialog() closes the topmost open entry. An install link's
job shows a "waiting for your answer" toast just as its question appears; when the toast came second, "Download
and install" closed the toast, the download ran, and the question stayed on screen. pop_dialog now skips toasts
(reproduced and checked with real clicks in the web build). Also a too-long test docstring line.
2026-10-17 22:25:11 -04:00
spoopyghosty0 472c607efd Restart after a source/wheel update keeps a hidden console on Windows
DETACHED_PROCESS left the restarted FramePort without a console, so every console program it started (ssh, git) opened
its own visible terminal, and the Frame connection's ssh kept one open. CREATE_NO_WINDOW gives it a hidden console,
as the dev shortcut does.
2026-10-17 22:15:32 -04:00
spoopyghosty0 33bb14e034 FrameBridge: cube-only frames as quads (#385); CI: lint, foveation test
HardBullet's loading frames submit only a cube layer, which the Frame's runtime doesn't composite, so the loading
screen stayed black. Adapter setting cube_quads (default on) draws a cube-only frame's six faces as quad layers
around the viewer; frames with a projection layer are unchanged. Adapter rebuilt on current main.

Also: the foveation test expected a numeric FOVE_LEVEL to pass through (Valve's layer ignores numbers since #394),
a long description line and an import order in adapter_dialog.py failed lint.
2026-10-17 21:52:39 -04:00
spoopyghosty0 0c06e1142f Install links: GitHub file pages become raw.githubusercontent.com; release manifests named via the API
The install page shows a manifest's name, description and icon only when the manifest's host allows CORS. GitHub file pages (github.com/<o>/<r>/blob|raw/<ref>/<path>) are now turned into their raw.githubusercontent.com address by the page (preview and the frameport:// link it hands over) and by deeplink.parse (a /blob/ page is HTML, so FramePort couldn't install from it). Release downloads can't be read by any web page: the page shows the release's name and the repo's description from GitHub's API instead of 'A game or app'. INSTALL_BUTTON.md says where to host a manifest.
2026-10-17 21:48:26 -04:00
spoopyghosty0 358db1360f quest_buttons: rebuild the adapter on current main, regenerate patch docs and translations 2026-10-17 21:44:01 -04:00
spoopyghosty0 1b43c1c544 quest_buttons on main: rebuild the adapter with main's Batman changes, harness stub for mx_batman_geometry_initialize 2026-10-17 21:37:39 -04:00
spoopyghosty0 5ae303fc45 Controller buttons: experimental (pill in Game settings and Settings, note in the guide) 2026-10-17 21:37:24 -04:00
spoopyghosty0 72edbebac1 Controller diagram: draw the Steam Frame controllers (d-pad, face buttons, sticks, View/Menu, Steam) 2026-10-17 21:37:09 -04:00
spoopyghosty0 ca80018d98 Device notes: quest_buttons accepted by the Frame runtime headless; OVRPort workspace collisions 2026-10-17 21:37:07 -04:00
spoopyghosty0 a585e24647 Rebuild reviewed adapters and record Round 2 validation 2026-10-17 21:36:42 -04:00
spoopyghosty0 b42d85d7c4 Fix Frame binding ownership and accepted Touch translation 2026-10-17 21:36:41 -04:00
spoopyghosty0 c9501bd446 Clarify controller mode support and Round 2 validation 2026-10-17 21:36:40 -04:00
spoopyghosty0 bc728bb121 Report controller installs that need Update on Frame 2026-10-17 21:36:39 -04:00
spoopyghosty0 838952b4f5 Test: input_diag reports created actions through session_fixes' hook since #323 2026-10-17 21:36:38 -04:00
spoopyghosty0 eab28b98c5 Controller diagram: draw d-pad arrows (the app's SVG renderer has no arrow glyphs) 2026-10-17 21:36:37 -04:00
spoopyghosty0 1f64d089e1 quest_buttons: bare trigger/squeeze/button paths map too (OpenXR resolves them to value/click) 2026-10-17 21:36:37 -04:00
spoopyghosty0 49de808650 Document Quest controller modes and integration checks 2026-10-17 21:36:35 -04:00
spoopyghosty0 54a2d84755 Keep inherited controller settings current after live updates 2026-10-17 21:36:23 -04:00
spoopyghosty0 31b4c684fe Add inherited Quest controller button preferences and mapping diagrams 2026-10-17 21:36:19 -04:00
spoopyghosty0 5d483746f9 Document native controller mode validation and device checks 2026-10-17 21:36:18 -04:00
spoopyghosty0 1f27cd47a3 Rebuild adapters and cover binding suggestion failures 2026-10-17 21:36:18 -04:00
spoopyghosty0 ff592e41e8 Add opt-in Quest controller bindings for Frame 2026-10-17 21:36:17 -04:00
spoopyghosty0 72d755973f Quest controller mode: contract and button mapping 2026-10-17 21:36:16 -04:00
spoopyghosty0 d02ff3c9aa Vulkan shim: leave out Lepton's Fossilize layer, blank shaders for refused pipelines (#349)
Transformers Beyond Reality: Redux ended its first frames with Unreal's "Shader compilation failures are
Fatal." With Lepton's Fossilize layer loaded every graphics pipeline failed with
VK_ERROR_OUT_OF_HOST_MEMORY, even a constant-colour one; the pipeline cache, the app's CPU allocator and
Valve's FDM/RPO layers were ruled out on the device. Without Fossilize a few multiview vertex shaders
still fail in Turnip.

- adapter.vk_no_fossilize: the shim removes VK_LAYER_fossilize from GraphicsEnv's debug layer list when
  the engine loads it (library constructor, same GraphicsEnv calls as zinkfix)
- adapter.vk_pipeline_fallback: a refused graphics pipeline is created again with a blank fragment
  shader, then blank vertex + fragment shaders
- catalog entry (status unknown, headless only), triage vulkan-pipeline-refused, PLAYBOOK, DEVICE_NOTES

Headless on the dev Frame: RUNNING after 78 s at 72 fps (was: exit within 21 s). Headset check pending.
2026-10-17 21:34:00 -04:00
spoopyghosty0 107215525f Save backups: choose the folder, quick actions, automatic snapshots (#352)
Settings -> Data picks the PC backup folder (e.g. a cloud-sync folder; old folders stay listed) and turns on
automatic snapshots (off by default): Quest launchers snapshot the saves when the game closes, under the launch lock,
keeping the newest three changed ones on the Frame, and FramePort imports them as automatic backups when it connects.
Agent v101. Checked on the Frame with BlazeRush (snapshot per close, one import per snapshot).
2026-10-17 21:29:32 -04:00
spoopyghosty0 a32e48367a Catalog: PrimedGun v2 without the Vulkan library rename (#254)
frame.vk_sanitize rewrote "libvulkan.so" in the game's library, but the game builds that name from two pieces, so it
asked for "libfp_vkn.so", Dawn found no Vulkan, fell back to OpenGL ES and left VR. Status stays unknown until it is
checked in the headset.
2026-10-17 21:28:09 -04:00
spoopyghosty0 95a226d54f Catalog: five working recipes from players (#395 #396 #397 #399 #401)
Summer Sports, Black Hole Pool, The Wizards, Surviving Mars: Pioneer and Survival Nation, all played in the headset.
Foveation choices left out (experimental, per player).

Closes #395
Closes #396
Closes #397
Closes #399
Closes #401
2026-10-17 21:19:06 -04:00
spoopyghosty0 6a6b6be5b5 USB setup: no console flash, connect when the Frame answers (#398)
The cable wait ran ipconfig every 2 s without CREATE_NO_WINDOW, so the windowed Windows app flashed a console each
time, and it only tried the Frame once ipconfig listed this PC's cable address, which Windows can report differently.
Commands now run hidden and the wait connects as soon as the Frame's SSH answers over the cable.
2026-10-17 21:14:33 -04:00
spoopyghosty0 01ad5e6b97 Foveation area size: use Valve's FOVE_LEVEL presets (#394)
The old radius setting exported FOVE_INNER/FOVE_OUTER, which Lepton doesn't pass into the container and Valve's
foveation layer doesn't read, so every size looked the same. Game settings now offers Default (large) / Large /
Medium / Small, exported as FOVE_LEVEL=lo/med/hi (the layer's own preset names); saved radius choices map to the
nearest preset. The agent's launcher update accepts FOVE_LEVEL.
2026-10-17 20:56:27 -04:00
spoopyghosty0 33d306a11e Catalog: Thief Simulator unsupported (install-source check, #368)
Quits at start with the game's own "installed from unknown source" message: Lepton installs the game itself at every
start and the Frame has no Meta store app, so the check can't pass.

Closes #368
2026-10-17 18:07:45 -04:00
spoopyghosty0 8e463a55de Catalog: Scared By Squares works (confirmed in the headset, #323) 2026-10-17 17:21:52 -04:00
spoopyghosty0 faca9bf396 unreal_noreserve: a build with nothing to rewrite passes its check (#393)
The validator required at least one rewritten mmap call, so an Unreal build without the Binned3 reservation
pattern (Lies Beneath) failed to build with "0 rewritten, 0 left" once the patch was on.
2026-10-17 16:53:43 -04:00
spoopyghosty0 e0a9b5f7cb Catalog: Table Troopers (works)
Closes #391
2026-10-17 16:52:13 -04:00
spoopyghosty0 3e906d55cf Catalog: Spectre (works)
Closes #390
2026-10-17 16:51:02 -04:00
spoopyghosty0 5e668f33d3 Batman audio hooks: place stubs in verified free gaps, say which step failed
On the Frame the atomic-branch detours never installed ("installation failed"): an mmap hint isn't honoured,
so the stub landed out of B range. Stubs now go into free gaps from /proc/self/maps within +-128 MiB of the
entry, mapped with MAP_FIXED_NOREPLACE (a relocated result is rejected); no gap = no hook. Every failure logs
the target and the failing step.
2026-10-17 16:47:06 -04:00
spoopyghosty0 feb4658dde Batman audio hooks: publish detours with one atomic branch (#389, #34)
The detour helper from PR #34 (used by the metadata hook and PR #389's two geometry hooks) wrote a 16-byte
branch + literal in two steps while game threads may run the function (installation is retried from
xrPollEvent). Each hook now publishes a single aligned release-atomic AArch64 B to a stub within +-128 MiB;
the trampoline replays the one verified instruction and returns to entry+4. Every mprotect is checked;
failures before publication free the stub and trampoline and leave the function untouched; no stub in range =
no hook. Adapter artifacts rebuilt by us (the PR's binary isn't shipped).
2026-10-17 16:47:06 -04:00
Lucas-Mathieu 4ed7929b1c Include package revisions in showcase build fingerprints 2026-10-17 16:47:06 -04:00
Lucas-Mathieu 61a6b3e2b2 Keep the ELF installer regression Linux-specific 2026-10-17 16:47:06 -04:00
Lucas-Mathieu 78fc926a48 Fix Batman audio geometry input lifetime across background loading 2026-10-17 16:47:05 -04:00
spoopyghosty0 503e64367c Showcase: monitor_settled waits for the newest fake stream
The Frame card starts a stream before the Monitor tab, whose faster interval starts a new one: the hook
returned on the first stream's flag while the new one was still replaying (CI rendered 71 vs 72 fps).
Each frozen session now has its own settled flag; the hook waits for the newest one.
2026-10-17 16:42:54 -04:00
spoopyghosty0 3deb279270 Headset model: an unknown OVRPort dispatcher keeps Quest 2 instead of failing the build (#373)
Quest 3 is the default for every Quest game, but the dispatcher patch only knows OVRPort 3.4.3-aa54c3f: an
APK converted with another runtime (found with an already converted Batman copy) failed to build. It now
keeps OVRPort's Quest 2 answers and says so in the build checks.
2026-10-17 16:35:35 -04:00
spoopyghosty0 0df1212bfe Showcase: the monitor shot waits for the frozen stream's replay
The Monitor tab asks the frozen fake stream to replay its history; on CI's slower runner the shot came
halfway through, so its numbers differed between renders ("three renders, no two alike"). New hook
monitor_settled waits until the replay is done.
2026-10-17 16:34:23 -04:00
spoopyghosty0 9106d3f090 Agent: uninstall works with Steam library mode later/off (#305)
cmd_shortcuts returns without "started" when it queues (later) or skips the change; cmd_uninstall indexed it
and failed after the shortcut removal was already queued, leaving the game installed. Found on the Frame.
2026-10-17 16:23:27 -04:00
spoopyghosty0 39fefd225f Steam library scheduling: now / later / off (#305)
Installing on the Frame restarted Steam to add the shortcuts, which also closed FramePort running there.
Settings -> Installing gets a Steam library mode: now (as before; restarts also wait while FramePort runs on
the Frame), later (no restart: Steam's next start re-applies and verifies the shortcuts through bounded
steam.service hooks) or off (no shortcuts; Play starts the game from FramePort). Restart Steam now bypasses
the holds and asks before ending a running game. Agent v99.

Based on the feature branch's two commits (a311498, cf05ce2), merged onto main.
2026-10-17 16:23:26 -04:00
spoopyghosty0 282f0e33c3 Showcase: keep the three renders of an unstable shot for --keep
CI's monitor shot fails with "three renders, no two alike" but discarded the renders; the artifact now has
unstable-<shot>-<k>.png to show what changes between them.
2026-10-17 16:22:27 -04:00
spoopyghosty0 8381dacdaa CI: fix the tests main broke (Files icons, headset default, adapter revision)
- Files: line-style icons for the drive, PC VR and Linux sections (test_ui_consistency).
- test_pc_target: Quest games now also gain device.headset_model from its migration; PC VR games never do.
- test_surface_projection: frame.adapter is revision 2 since the dormant foveation diagnostic (#365).
2026-10-17 16:08:26 -04:00
spoopyghosty0 fc5908618c Files: separate sections for PC VR games and Linux apps (#361)
Their entries open the install folder rather than Android storage, so they get their own "PC VR games" and
"Linux apps" sections next to Game storage. ui_smoke: linux-files step.
2026-10-17 15:58:13 -04:00
spoopyghosty0 d7f0d51472 Foveation as a per-game setting; "Sharpness" is "Render resolution" (#365)
Foveation (Default / Eye-tracked / Fixed / Off, radius, test) moves from Customize to Game settings →
Picture. It's a user preference, not part of the recipe: existing recipes are migrated once and Share
working config leaves it out. Agent v98 set_settings rewrites only the launcher's foveation exports, so a
change applies at the next game start without a rebuild (checked on the Frame: Fixed adds the FDM exports,
Default removes them). The APK-side parts (Batman allocation fix, Climb 2 bridge) stay in the build.
The scale setting's label is now "Render resolution (supersampling)". ui_smoke: game-settings-dialog step.
2026-10-17 15:46:35 -04:00
spoopyghosty0 55c6da7010 Files: read drives through the Frame target (shared drive cache)
The drive locations called the agent directly, bypassing the target that the Storage section and Move to…
use and the cached app.frame_drives list.
2026-10-17 15:42:36 -04:00
spoopyghosty0 f996e5e7d9 Files: SD cards/drives and PC VR/Linux game folders as locations (#361)
Each drive the agent reports (SD card, USB, other Steam library drives) is a Files location with its free
space; read-only drives allow downloads only. Installed PC VR and Linux games get their install folder.
Agent v97: drives report read_only explicitly (checked on the Frame).
2026-10-17 15:29:59 -04:00
spoopyghosty0 1e1c435191 Headset model per game, Quest 3 by default (#373)
Games saw a Quest 2: OVRPort's dispatcher hardcodes the system name "Oculus Quest2" and a Quest 2
headset UUID (XR_META_headset_id), and OVRPlugin decides the headset type from the UUID first, then the
name. device.headset_model (Customize; Quest 3 default for every Quest game, also Quest 3S, Quest Pro,
Quest 2) rewrites both in the dispatcher after checking the original bytes; Quest 2 leaves the build
byte-identical. FrameBridge reports the same name to games that call the runtime directly. A library
migration adds the default to existing recipes (installed games show Update on Frame).
Lepton's ro.product.model ("Lepton") can't be overridden by boot properties, so Build.MODEL is unchanged.

Verified on the Frame: OVRPlugin logs "systemName Meta Quest 3" (was "Oculus Quest2").
2026-10-17 15:18:45 -04:00
spoopyghosty0 33942aa509 Catalog: CrazyTaxiVR (works)
Closes #380
2026-10-17 15:08:55 -04:00
spoopyghosty0 dd7f5d67c7 Catalog: Breachers (unsupported: needs Meta's online services)
The game's own copy of Meta's platform library (libovr_custom.so) quits at start; online-only (#357).
2026-10-17 15:08:52 -04:00
spoopyghosty0 7d4e20844f FrameBridge: XR_FB_color_space for games that require it (#336)
OutRun Quest VR quits before its VR session with "Rec.709 color space unavailable": the Frame's runtime
has no XR_FB_color_space. Adapter setting fb_color_space (off by default; triage color-space-missing
suggests it) offers the extension when the runtime lacks it, reports Rec.709 and accepts any colour
space without converting. OVRPort's dispatcher can't forward the new functions, so it isn't on for every
game. Not yet tried on the device.
2026-10-17 14:56:59 -04:00
spoopyghosty0 fc8443fc56 Store details: refetch after Rename, reject adult Steam matches (#377)
An import named after its code name ("Lollipop") matched an adult Steam game by exact title, and the
screenshots stayed after the user renamed it. Details now record whether they were matched by package or
by title; a rename (GUI, CLI, --reset) drops title-matched details and screenshots and fetches them again
under the new name, keeping package-matched details and custom art. Steam matches whose
content_descriptors mark sexual content are treated as no match, for details and artwork.
2026-10-17 14:36:26 -04:00
spoopyghosty0 3c43b0fb5d Per-game language setting (device.language, #354)
Lepton's Android is set to English (US), so games that follow the system language start in English.
device.language (Customize -> Game language) sets persist.sys.locale through its own LEPTON_GFXRECON_*
boot-property line, like device.hide_navbar. Verified on the Frame: the container reports de-DE and the
game's VM starts with user.locale=de-DE.
2026-10-17 14:32:16 -04:00
spoopyghosty0 8e8b3c819c Catalog: ToyTrains (works)
Closes #384
2026-10-17 14:08:28 -04:00
spoopyghosty0 434e614d6c Catalog: BattleTalent (issues; MR mode missing, multiplayer untested)
Closes #381
2026-10-17 13:56:44 -04:00
460 changed files with 43681 additions and 2371 deletions

No files matched your search

+76 -13
View File
@@ -59,8 +59,22 @@ Detailed device findings per game/issue: docs/DEVICE_NOTES.md (read before debug
agent ends at EOF); sources and costs in docs/FRAME_RUNTIME.md "Monitoring sources"; game card (fps from
FrameBridge pacing; End game = Steam's Exit game, then cmd_stop), tiles with `C.Sparkline` (Flet canvas, no charts
extension), details, a pooled process table (Game / Steam & SteamVR / All; right-click: end / force kill / end
game; MON_CRITICAL needs force, MON_NEVER is refused)); settings; welcome; activity panel). Files, Screenshots and the Library share right-click menus
(one `ft.ContextMenu` per view, filled on right-click; on one of several selected items they act on the whole
game; MON_CRITICAL needs force, MON_NEVER is refused)); room (`views/room.py`, persistent, "experimental" pill:
scan with progress + Cancel = agent v109 `room_capture_stop`, play area, delete; cache `ui/room_state.py` shared
with the Frame page's short card, mesh cached in `<data>/rooms-cache/<frame>/`; in-window 3D `ui/room3d.py`
RoomCanvas over `mr/view3d.py` (pure-Python projection, mesh reduced to ≤4k/≤1.5k edges at rest/moving, ≤18 fps
worker; each redraw sends NEW shape controls: changing a Points list made Flet diff it item by item, 0.3-1 s);
"Open full 3D view" = `mr/room_viewer.py` token server on 127.0.0.1 + hand-written WebGL `mr/viewer_page.py`,
stopped on disconnect/close; Test Quest MR tip = `mr.TESTER_*`; editing cards `views/room_edit.py` (agent v109):
Clean-up = fp_roomscan's refinement settings, `install/rooms.REFINE_DEFAULTS` = the owner's defaults + slider
metadata (agent `ROOM_REFINE_DEFAULTS` must match, a test checks), saved non-defaults in the Frame's
`rooms/refine.json`, used by every build; Apply = job → agent `room_refine` (`--refine-only` on a copy of the room
folder from `room-raw.txt`/`room-mesh-raw.bin`, scan.json → status `report`/`labels`/`suggestions`); Labels =
the label rules' decisions + Add as door / Add as closet; Furniture & screens = box editor (click a box in the
canvas: `view3d.pick`) + doors/windows on a wall (`mr.room.plane_on_wall`), Save = `rooms.put_room` → `room_put
edited` (keeps raw files, `edits.txt` survives a new clean-up; "Back to the scan's boxes" = keep_edits false); no
eraser in the GUI (`rooms.refine(erase=)` only)); settings; welcome; activity panel). Files, Screenshots and the Library share right-click menus
(`app.popmenu`, filled on right-click; on one of several selected items they act on the whole
selection, `C.menu_targets`) and click-and-drag multi-select (`C.DragSelect`: pan start/end on the area + item
hover events, which Flutter also sends with the button held; Flet can't report item positions, so no rubber band).
Selection bars sit below the list: above it, their appearing shifted the items mid-drag. Async handlers (they
@@ -130,10 +144,19 @@ Detailed device findings per game/issue: docs/DEVICE_NOTES.md (read before debug
in Containers with `ft.ScrollKey`), the header stays; `app.settings_view.show_section(key)` (ui_smoke
`settings-index`).
Help hints: wording for non-obvious terms lives in `ui/help.py` (`HELP`); show it with `C.help_icon(key)` or the
`help=` argument of `section`/`kv` (`C.Check` help key), tooltips via `C.tip()` (wraps). Game actions for the Library
right-click menu (one `ft.ContextMenu` around the grid, filled on right-click; short: `menus.quick_menu`, key actions
+ "More actions…" = the game page with its full "…" menu opened from code, `app.open_game_menu`) and the game
page's "…" menu (`menus.menu_sections` quick=False, sectioned) come from `app.game_actions()`. Picking art (`sources.apply_choice`) downloads into a staging dir and keeps the old
`help=` argument of `section`/`kv` (`C.Check` help key), tooltips via `C.tip()` (wraps). Context menus
(Library, Files, Screenshots, Monitor) and the game page's "…" are FramePort's own (GitHub #414):
`ui/popmenu.PopMenu` = `app.popmenu.show(entries, at=(x, y) | below=box)`, drawn in page.overlay (outside-click
barrier + panels; hover submenus with open/close intent delays, ↑ ↓ → ← Enter Esc via `app._on_key` first, closes
on outside click/Esc/choice/`app.go`; panels size to the estimated label width between MIN_W and MAX_W, longer
labels wrap, flip/clamp into the window, submenus on the side with room; a solid grey left edge (owner: no portal gradient) and a solid soft-accent highlight; fade off with
Reduce motion; hovering only repaints rows). Flet's stock ContextMenu/PopupMenu can't nest and cap at 280 px, so
they're only used for button menus (`C.menu_button`, width scaled; `C.menu_label` wraps). Game menus come from
`app.game_actions()` = `menus.menu_sections`: right-click = Play, Install/Update, Game settings | Open game page,
Select | Update ▸ On the Frame ▸ Saves ▸ Name and artwork ▸ Recipe ▸ Troubleshoot ▸ | Uninstall…, Remove from
library… (`menus.group`: a one-item group stays inline); the page's "…" (quick=False) is the same without what
its hero has; on one of several selected games `menus.selection_menu` (`library.menu_actions`); the recipe card's
buttons = `game_actions(recipe=True)`. Picking art (`sources.apply_choice`) downloads into a staging dir and keeps the old
art if nothing came back; "Update Steam art on Frame" re-sends the art set to the game's anchor (agent ≥ 12).
Patch descriptions/reasons describe the general case, naming games only as "e.g. …".
- Installs: queued/cancelled/failed ones are remembered (library setting `ui.installs`) → Library "Resume" bar;
@@ -218,6 +241,11 @@ Rick and Morty runs on the Frame via its catalog recipe (OpenVR, no Revive),
`FRAMEPORT_DESKTOP=1` skips the Steam-parent watchdog and Steam's display; ensure_host_fixes refreshes entries
(older installs, stale ones removed), uninstall/purge remove them. Per app: library entry field `desktop_entry`
(default on; patches don't apply to Linux apps) → game page switch → agent `desktop_entry`. Untested on device.
- App bundles (discussion #482, `sources/bundles.py`, docs/DEVICE_NOTES.md#app-bundles-xapk--apks--apkm--apkx-discussion-482):
.xapk/.apks/.apkm/.apkx files and folders of split APKs are unpacked + merged into ONE APK (Lepton: one APK per app;
OVRPort: one APK) in `<data>/bundles/<pkg>/<key>/` (lib/assets splits in Python, resource/feature splits via
APKEditor `tools/apkeditor.py`); arm64-v8a split only; library field `bundle`; merged APKs are unsigned (builds sign).
FrameDrop itself takes no bundles; `.apkx` is no defined format (read as a zip of APKs); old encrypted .apkm: refused.
- Scanning: SideQuest backups (`<package>/<time>/apk|obb|data`) and AXRB downloads (`AXRB/<app id>/<binary id>/base.apk`
+ OBBs/assets; its `patched/`/`*-axrb.apk` PC builds are skipped) are recognised (`sources/quest_dump.py`, FAQ).
- Quest/Rift twins stay separate entries, shown and named in Steam "Title (Quest)"/"(Rift)" (`core/titles.py`).
@@ -251,7 +279,11 @@ Rick and Morty runs on the Frame via its catalog recipe (OpenVR, no Revive),
restore = untrusted input (staged + checked first), rollback copy `<base>/saves-before-restore.tar.gz` (undo =
`rollback: true`). PC `install/saves.py` (`<data>/save-backups/<pkg>/<ts>.tar.gz` + `.json`, keep `saves.keep`
= 10), GUI `ui/views/saves_dialog.py` (game menu section "Saves", Frame page "Back up all saves", uninstall's
"back up before deleting"), CLI `frameport saves backup|list|restore|undo`.
"back up before deleting"), CLI `frameport saves backup|list|restore|undo`. Agent v101: PC folder `saves.folder`
(Settings → Data; old folders stay listed in `saves.previous_folders`), automatic snapshots `saves.auto` (default
off; flag `~/.local/share/frameport/save-snapshots/enabled`, Quest launchers run `_snapshot_close` in the EXIT
trap under the launch lock, newest 3 per game on the Frame; `install/saves.sync_snapshots` imports them as
"automatic" once, ledger `<data>/save-snapshots-synced.json`). Device-checked 2026-10-17 with BlazeRush.
- `patches/` — **the unit of modularity**. `base.py` (Patch interface, registry), `overport.py` (overport CLI patch ids,
discovered dynamically via `overport patches`), `frame/*.py` (one module per Frame fix), `settings.py` (FrameBridge
adapter keys + device files as patches). Add a patch = add a module that calls `register(...)`.
@@ -304,7 +336,11 @@ Rick and Morty runs on the Frame via its catalog recipe (OpenVR, no Revive),
reinstall of the release's `.whl`); `prepare()` → `<data>/updates/<ver>/` (SHA256SUMS.txt required + checked,
layout checked, Windows: the new FramePort.exe must have the running exe's Authenticode signer when that one is
signed, `ready.json`); `apply()` writes + starts detached `apply.ps1`/`apply.sh` (wait for pid → Windows: copy over,
replaced files kept in `updates/<ver>/previous` because the zip has no top folder; macOS/Linux: mv to `.old` + swap,
replaced files kept in `updates/<ver>/previous` because the zip has no top folder; nothing touched while a program file
is in use, old-only files of app/Lib/DLLs/site-packages/data moved to `previous`, a failed copy deletes what it
added (#476: the old rollback kept new modules → old version crashed at start); bundles carry
`frameport/_bundle_files.txt` (package.py) → `core/bundle_files.check` at GUI start removes/ignores leftovers and
reports a mixed install; macOS/Linux: mv to `.old` + swap,
rollback, `xattr -dr` quarantine → relaunch; `<data>/logs/update.log`). `ui/updater.py`: background check (10 s,
then 6 h), sidebar card (hidden control, toggled), Library bar (`library_bar`), changelog dialog, job
`app-update` that restarts only when no other job is active, `apply_pending_at_start()` in `main()` for
@@ -451,7 +487,9 @@ Repo is on an NTFS drive (`core.fileMode=false`); line endings are LF (`.gitattr
- No XR_FB_display_refresh_rate (`xrGetDisplayRefreshRateFB` -7), yet OVRPort's dispatcher offers it and answered 0 Hz
→ FrameBridge always answers with the measured rate (1/predictedDisplayPeriod, else 72). PreyVR (#306, idTech 4:
`USERCMD_MSEC = 1000 / GetRefresh()`) had 0 ms tics: async thread spinning, `com_frameTime` stuck at 0, menu black.
- Guardian STAGE bounds report 1×1 m (scene emulation uses ≥1.5 m).
- Guardian STAGE bounds report 1×1 m (scene emulation uses ≥1.5 m). OVRPlugin treats that rect as a configured
boundary but can't outline it ("ovrpBoundary_Outer is not supported"): Demeter's guardian check indexed an empty
array → with `scene_emul` the app's STAGE `xrGetReferenceSpaceBoundsRect` returns XR_SPACE_BOUNDS_UNAVAILABLE.
- GL goes through **Zink** (Mesa GL on Vulkan). Mesa GLSL is strict: `#pragma` before `#extension` fails, implicit
int/float conversions fail (enable `GL_EXT_shader_implicit_conversions`), num_views=2 shaders on single-view FBOs
give GL_INVALID_OPERATION. Some GLES games hit `zink: DEVICE LOST` (Unity MSAA RTT; Sniper Elite VR even without).
@@ -553,6 +591,7 @@ Output is deterministic (same input + runtime → same bytes), which is what mak
- VrApi-direct engines (CryEngine Climb 2, POTW) need the VrApi bridge; the bridge drops whole frames on unknown layer
types (→ black screen with audio).
**Quest controller mode:** adapter `quest_buttons` (0/1/2, per game + library `input.quest_buttons`) suggests Frame Controller bindings translated from the game's Touch set (`suggest_frame`, mapping docs/input/quest_buttons.json = single source for C table, tests, diagram `scripts/controller_diagram.py`); runtime accepts them headless. → docs/DEVICE_NOTES.md#quest-controller-mode-quest_buttons-2026-10-17
**Steam Frame controller models:** adapter setting `controller_models` (`native/adapter/render_model.c`, emulates XR_FB_render_model) + agent `install_controller_models` (Frame's SteamVR models → glb at finalize); no catalog game uses runtime models; Valve's models are never committed or copied off the Frame. → docs/DEVICE_NOTES.md#steam-frame-controller-models
**overport's dispatcher (`libopenxr_loader.so`) only forwards functions in its own table** (`overportOXR: Unknown
proc addr: …`), so adapter emulations of functions it doesn't know are unreachable. For XR_FB_render_model,
@@ -563,20 +602,21 @@ Toy Master doesn't request a model after that (it uses its own), so the glb load
**Crash backtraces:** Lepton writes tombstones only to `lepton-logcats/steamlaunch-<appid>/logcat-crash.log` (launch tests return `crash_log`). Fossilize loads into every app (userdebug guest) → `frame.vk_sanitize` (`native/vkshim`); overport's dispatcher aborts on swapchains > 4096 px → `frame.swapchain_limit`; cylinder layers → quad strips (`cylinder_strips`). Drawing equirect layers ourselves and a focus debounce were tried and removed: don't retry without a new approach. → docs/DEVICE_NOTES.md#crash-backtraces-fossilize-swapchain-limit-cylinder-and-equirect-layers
**360° layers / 4XVR:** the Frame's Android runtime composites only quad + projection layers (quads always above projection layers). Per-game adapter settings (off by default): `equirect_emul` (GLES), `equirect_flip/face/res/fps/stereo`, `stable_local`, `focus_hold` (default on), `aim_pitch/aim_yaw/aim_forward`, `refresh_rate`, `layer_debug`; agent `link_media` / `app_media_dirs` put sent files into a player's own folder. → docs/DEVICE_NOTES.md#360-layers--4xvr
**Companion apps / intents:** a second APK can run inside a game's Lepton container, but Lepton turns every `android.intent.action.VIEW` with data into `steam://openurl` → "open in external player" hand-offs can't work; Lepton installs exactly one `*.apk` per app folder. → docs/DEVICE_NOTES.md#companion-apps--intents-stremio--4xvr
**Text input:** Lepton's Android has no IME and VR apps run headless (no focused window); `lepton-show-flatscreen` keeps VR and gives focus + Steam's keyboard (`device.text_input_window`); `frame.unity_text_input` patches Unity's TMP_InputField/InputField at Cpp2IL offsets; agent `_keyboard` = uinput "Type on Frame". `pm install` of a second APK corrupts the main app (`cmd_real package install` skips the hook). → docs/DEVICE_NOTES.md#text-input-stremio-vr
**Browser stand-in (#466):** Lepton's `ActivityStarter.execute` takes every VIEW intent before resolution → `steam://openurl` into `/lepton/steam.pipe`; apps that first query for a browser (Plex) find none → opt-in `frame.browser_handoff` (activity + `dex/browser-handoff.dex` in the app's own APK, analysis `browser_query`); a 2D app with an APK patch on is built, not as_is (`engine.flat_as_is`). → docs/DEVICE_NOTES.md#browser-stand-in-for-sign-ins-plex-github-466
**Text input:** Lepton's Android has no IME and VR apps run headless (no focused window); `lepton-show-flatscreen` keeps VR and gives focus + Steam's keyboard (`device.text_input_window`); `frame.unity_text_input` patches Unity's TMP_InputField/InputField at Cpp2IL offsets; agent `_keyboard` = uinput "Type on Frame". `pm install` of a second APK corrupts the main app (`cmd_real package install` skips the hook). Its window is a gamescope "desktop game" overlay: SteamVR auto-theaters it before the OpenXR session and opens the dashboard on it at session start (controllers = mouse on the Android screen, AC Nexus/#476/#477) → the launcher (`_theater_hold`, first thing) and dashboard worker keep `dashboard.autoShowGameTheater` off while such a game runs (agent v119, holds per launcher pid in `theater-holds/`); SteamOS 0.5.6 logs the dashboard button as `open_dashboard_action`. → docs/DEVICE_NOTES.md#text-input-stremio-vr, #typing-window-takes-the-controllers-steamvr-theater-mode-476-477-ac-nexus
**User reports #4-#10:** shortcuts go to the signed-in account (agent `library_users`), `launch` errors `NOT_IN_LIBRARY`; shared Cpp2IL run (`unity_text_input.Il2cppReturnPatch`) for `frame.unity_runtime_msaa_off` and `frame.unity_multipass`; VR4 → catalog `use_alt`. **Catalog changes reach existing games**: recipes store `catalog_rev`, `library._follow_catalog` re-derives non-user recipes. → docs/DEVICE_NOTES.md#user-reports-2026-10-04-issues-4-10
**Round 2 of reports / headset rounds 2-3 (2026-10-04):** vkshim `vk_shader_fix` (VR4); `Il2cppReturnPatch.field_loads` (I Am Cat); builds record `recipe_fp` (changed recipe/revised patch → "Update on Frame"); `Frame.relocate`; adapter `profile_remap` (Touch Plus/Pro); `sync_guard` (Myst); `focus_hold` tuning; ovrpshim for Unity 2017 (Accounting+); Steam library to every account, `shortcuts_lost` / `add_devkit_entry`; no clipboard service → `frame.sdl_clipboard`, `frame.godot_clipboard`; 2D apps keep non-VR patches (`needs_vr = False`); `frame/local.py` (FramePort on the Frame); after every app update `library._follow_catalog` re-derives non-user recipes once (`recipes.app_version`, `library.REFRESH_ON_UPDATE`). Analysis fields added later: **bump `analysis/detect.ANALYSIS_VERSION`** (re-analysis at GUI start + `pipeline.refresh_analyses`; `analysis_failed`). Roblox and BONELAB crash (unsupported). → docs/DEVICE_NOTES.md#round-2-of-reports-headset-rounds-2-3-2026-10-04
**Round 4:** XR_KHR_android_surface_swapchain is listed but unsupported → adapter `surface_emul` (default on, `native/adapter/surface_swapchain.c`); save folders without u/g+rwx → launch.sh `fix_perms`; Lucky's Tale OOM (no fix); `perf` works as steamos (gdb blocked); QuestCraft JRE, WiiCompiled import by hand (Lepton has no document picker). → docs/DEVICE_NOTES.md#round-4-2026-10-04-surface-swapchains-save-folder-permissions
**Steam library failures (GitHub #21/#30/#41/#42):** on some Frames Steam never loads FramePort's shortcuts.vdf entries (Play → AppError_9) → fallback: register through Steam's devkit interface (`devkit-1 … create-shortcut`, `~/devkit-game/<id>/`; `devkit_appid`, `devkit_appid_from_log`, `devkit_unregister`, `copy_grid_art`; ids: letter first, letters/digits/_ only); `collect_diag` adds `steam_library`. Cause still unknown. → docs/DEVICE_NOTES.md#steam-library-failures-and-the-devkit-fallback-github-21304142
**Exit game (GitHub #36):** `Apps.TerminateApp` (Steam CEF devtools on 127.0.0.1:8080) closes games; launch.sh ends the game when its parent reaper is gone (`upgrade_launchers` adds it). → docs/DEVICE_NOTES.md#exit-game-github-36
**SteamVR dashboard at game start:** launch.sh's `_dashboard_worker` hides the dashboard via `SteamClient.OpenVR.VROverlay` (agent `steam_js`) from the first FrameBridge `new layer:` line (120 s, ≤10 times, stops after `toggle_dashboard_action`); log `<base>/dashboard.log`, opt out `FRAMEPORT_KEEP_DASHBOARD=1`. → docs/DEVICE_NOTES.md#steamvr-dashboard-at-game-start
**Space warp / ITR2:** OVRPort's dispatcher offers XR_FB_space_warp itself (`patch_disable_space_warp` doesn't reach UE5) → FrameBridge `hide_space_warp` (per game, off; suggested for UE5 + OVRPlugin). `equirect_emul` switches itself off on Vulkan. → docs/DEVICE_NOTES.md#space-warp--itr2
**Space warp / ITR2:** OVRPort's dispatcher offers XR_FB_space_warp itself (`patch_disable_space_warp` doesn't reach UE5) → FrameBridge `hide_space_warp` (per game, off; suggested for UE5 + OVRPlugin). Games that *require* space warp (OutRun, #336: "AppSW recommended buffers unavailable") → `space_warp_emul` (`native/adapter/space_warp.c`: MV size, FrameBridge-owned MV/depth images, info stripped; overrides hide_space_warp). `equirect_emul` switches itself off on Vulkan. → docs/DEVICE_NOTES.md#space-warp--itr2
**PR #34 (Lucas-Mathieu):** `native/adapter/audio_metadata.h` keeps Meta XR Audio Wwise metadata alive (Batman: Arkham Shadow 1.4.1 smoke-bomb crash). Outside PRs: review source, rebuild `artifacts/` ourselves, merge locally. → docs/DEVICE_NOTES.md#pr-34-meta-xr-audio-metadata-batman
**Heuristics eval (2026-10-04):** 19/44 recipes exact (superseded by the 2026-10-15 numbers under Heuristics). → docs/DEVICE_NOTES.md#heuristics-eval-2026-10-04
**Power (0.9, agent v47):** sidebar bar below the Frame card: Sleep / Restart / Shut down, each confirmed (`app.frame_power`, a running game asks again). logind answers CanSuspend/CanReboot/CanPowerOff = "challenge" for an SSH session but "yes" inside a user unit, so agent `power` runs `systemctl suspend|reboot|poweroff` from a transient `systemd-run --user --on-active=3` timer (the command answers first). Restart verified on the device (back in ~84 s, new boot id).
**Proton default:** the newest **stable** ARM64 Proton (`pick_proton`; owner's headset A/B); `pcvr.proton_tool` dropdown (Experimental = alias `proton-experimental`), `ensure_proton`, `proton_alternative_worth_trying`. → docs/DEVICE_NOTES.md#proton-default-stable-vs-experimental
**USB cable link:** `usb0` is a USB NCM gadget (Developer Mode only); Frame 10.86.200.233, PC **10.86.200.234** (`frame/usb.py`); ~37 MB/s; `scripts/usb_autotest.py`, `frameport frame usb-check`; discovery prefers USB > hotspot > network (`discovery.dedupe`). → docs/DEVICE_NOTES.md#usb-cable-link
**Catalog updates without a release (2026-10-05):** apps fetch `catalog/games/*.yaml` from GitHub `main` (`recommend/catalog.refresh_remote`: one API call `git/trees/main?recursive=1` + raw.githubusercontent downloads of changed blobs, cached as `catalog-gh-<sha>.yaml`, every 6 h; GUI at start + Settings → Data "Check now"; CLI background thread + `frameport catalog-update`). `catalog.load()` only reads the cache. A remote entry is skipped (`unusable_reason`) when it names a patch/adapter key this app doesn't register, has a field `CatalogEntry` doesn't know, or `min_app` > this version: add `min_app` (or rely on new patch ids) when a config needs an unreleased FramePort. Remote beats bundled unless the bundled entry has a later updated/verified date; the user's own entries still win as before. Off: setting `catalog.auto_update`, env FRAMEPORT_NO_CATALOG_UPDATE; FRAMEPORT_CATALOG_URL still overrides the source. So: **pushing a catalog change to main reaches users within 6 h** (their recipes follow via catalog_rev → Update on Frame).
**Catalog updates without a release (2026-10-05):** apps fetch `catalog/games/*.yaml` from GitHub `main` (`recommend/catalog.refresh_remote`: one API call `git/trees/main?recursive=1` + raw.githubusercontent downloads of changed blobs, cached as `catalog-gh-<sha>.yaml`, every 6 h; GUI at start + Settings → Data "Check now"; CLI background thread + `frameport catalog-update`). `catalog.load()` only reads the cache. A remote entry is skipped (`unusable_reason`) when it names a patch/adapter key this app doesn't register, has a field `CatalogEntry` doesn't know, or `min_app` > this version: add `min_app` (or rely on new patch ids) when a config needs an unreleased FramePort. Remote beats bundled unless the bundled entry has a later updated/verified date; the user's own entries still win as before. Off: setting `catalog.auto_update`, env FRAMEPORT_NO_CATALOG_UPDATE; FRAMEPORT_CATALOG_URL still overrides the source. So: **pushing a catalog change to main reaches users within 6 h** (their recipes follow via catalog_rev → Update on Frame). `catalog/triage.yaml` comes from the same tree listing (cached `triage-gh-<sha>.yaml`, index key `triage`; a new copy → `triage.reset()`; with FRAMEPORT_CATALOG_URL: that folder's optional `triage.yaml`): `validate/triage.database()` = bundled merged with remote per signature id (remote wins unless the bundled one has a later `updated:`; bundled-only ids stay), each remote signature dropped (bundled one kept) when malformed, it has an unknown field, suggests a patch/adapter key this app lacks, or `min_app` (per signature or top-level = whole file) > this version; `triage.skipped()`, `frameport catalog-update` lists them.
**Start activity / QuestCraft / ITR2 pop-in:** `frame.start_activity` (analysis `extra.vr_activity`, `axml.set_start_activity`; OVRPort gives every MAIN activity LAUNCHER, so take the VR activity from the original APK); Unreal reads user config from **internal** storage; Lepton passes `LEPTON_ENV_<NAME>` to the app as `<NAME>` (QuestCraft `LIBGL_NOERROR`); vkshim `vk_query_slots` left off. → docs/DEVICE_NOTES.md#start-activity--questcraft--itr2-pop-in
**Vulkan validation / ITR2 solved:** bundle Khronos' `libVkLayer_khronos_validation.so` into a test APK + vkshim `vk_validation=1` (logcat tag VALIDATION); `vk_spec_fixes=1` drops ITR2's invalid depth resolve; VALVE_rpo removed its fog (catalog `lepton_env: VK_INSTANCE_LAYERS`). Agent `not_started` waits 30 s for "Boot complete!". → docs/DEVICE_NOTES.md#vulkan-validation--itr2-solved
**GitHub #38/#39:** SteamVR rejects image rects past their swapchain (-25) → FrameBridge `rect_clamp` (default on), triage `swapchain-rect-invalid`; The Room VR MSAA crash in libgallium. → docs/DEVICE_NOTES.md#github-3839-powerwash-simulator-the-room-vr
@@ -585,9 +625,11 @@ Toy Master doesn't request a model after that (it uses its own), so the glb load
**Vader Immortal (GitHub #49):** stuck on its loading card and leaked GPU mappings (solved below: `gl_error_clear`); diagnostics FrameBridge `layer_debug`, `strip_color_bias`, `frame_balance`, `snapshot=N` (`snapshot_gl.c`: saves the submitted left-eye image as `files/fb_snap_*.ppm`). → docs/DEVICE_NOTES.md#vader-immortal-headless-investigation
**SteamVR overlay apps:** host OpenVR overlays composite over Lepton games; detection `analysis/vroverlay.py`, patch `pcvr.vr_overlay`, Linux fields `vr_overlay`/`vr_overlay_autostart`, agent `register_vr_overlay`/`unregister_vr_overlay`/`launch_vr_overlay`; SteamVR on the Frame reads only `binary_path_linux_arm`; FramePort's own autostart (`ensure_overlay_service`, `frameport-vr-overlays.service`). See also docs/FRAME_RUNTIME.md "Overlay apps". → docs/DEVICE_NOTES.md#steamvr-overlay-apps
**Vader's leak solved / AC Nexus flips:** stale GL errors broke SteamVR's GL interop → adapter `gl_error_clear` (GLES, catalog for Vader ep1-3); read `xrclient_<pkg>.txt` in Steam's logs for runtime errors; the runtime caps swapchains per session (~15) → flip emulation in place; adapter `flip_dump`. → docs/DEVICE_NOTES.md#vaders-leak-solved--ac-nexus-flips
**Mixed reality: scanned rooms (branch mr-scene):** agent `room_capture` records Valve's RoomView 3D depth mesh -> `fp_roomscan` -> `room.txt` + `room-mesh.bin` (docs/mr/ROOM_FORMAT.md; refined by default: the owner's cleanup passes + label rules in `native/roomscan/refine.c`/`rules.c`, unrefined output kept as `room-raw.txt` + `room-mesh-raw.bin`, head path/settings/report/labels/door suggestions in `scan.json`, `--refine-only <dir>` re-runs it, `--refine 0` = old output; docs/mr/scan.md "Refinement") in `~/.local/share/frameport/rooms/<universe>/`, copied next to settings.conf (`_room_sync`); FrameBridge (`scene_room.c/scene_meta.c/scene_anchors.c`, all through xrshim) serves walls, volumes, planes, the room mesh, META discovery/persistence, saved anchors and `XR_META_boundary_visibility`; `scene_emul` + `frame.meta_permissions` for every USE_SCENE/USE_ANCHOR_API game (migrations `scene_emul_all`, `scene_permissions`); per-game `scene_hide_bounds` (Demeter). → docs/DEVICE_NOTES.md#mixed-reality-scanned-rooms
**Unreal's self-restart:** UE 4.21+ restarts itself after the first shader precompile and Lepton ends the container → launch.sh RESTART_BLOCK starts Lepton once more (`upgrade_launchers`; `FRAMEPORT_NO_RESTART=1` off). → docs/DEVICE_NOTES.md#unreals-self-restart
**xrWaitFrame runs ahead:** the runtime sometimes returns a display time <1 refresh after the last submit and rejects the second submission (`VRCompositorError_AlreadySubmitted`) → the VrApi bridge re-waits (`pacing 2s:` counters). → docs/DEVICE_NOTES.md#xrwaitframe-runs-ahead-journey-of-the-gods
**Lepton's logcat mirror dies** (EOF, read failure, or silent) → launch.sh `_logcat_keeper` reads `podman exec <container> logcat` itself into launch.log (log `<base>/logcat-keeper.log`). → docs/DEVICE_NOTES.md#leptons-logcat-mirror-dies
**Graceful stop (#480, agent v120):** killing the container never paused the app (saves in `OnApplicationPause` lost: Just Dance VR) → launch.sh `pause_game` / agent `stop` / End game first `am start` the HOME intent in the container (`input keyevent` does nothing headless) and wait ≤3 s for STOPPED (`PAUSE_SCRIPT`, `<base>/stop-pause.log`). Steam's own Exit game signals the whole process tree (conmon is re-parented to the reaper) at once → agent v121: launch.sh's `_exit_hook` worker (`exit_hook_worker`, `EXIT_HOOK_JS`) wraps `SteamClient.Apps.TerminateApp` in SharedJSContext with a CDP binding of its own: Exit game for that game's ids waits for the worker's pause (cap 3 s, 0.8 s without an answer, lease 10 s), other ids pass straight through; End game calls `terminate_app_js` (past the hook). → docs/DEVICE_NOTES.md#graceful-stop-the-game-is-paused-before-it-ends-github-480-agent-v120
**Double launch:** launch.sh takes `flock` on `<base>/.launch.lock` (fd 9); a second launch exits 0 and logs to `<base>/launch-dup.log` (`upgrade_launchers` adds it). → docs/DEVICE_NOTES.md#double-launch
**Issue triage round 2026-10-06:** FrameBridge turns haptic amplitude 0 into xrStopHapticFeedback, per-game `haptic_scale`; Lambda1VR → `frame.tbxr_vendor`; Jurassic World → `frame.vrapi_stub`; Metro Awakening / Pinball FX → `hide_space_warp`; `frame.ovr_trace` can't trace Unity games; the VrApi bridge's 30 s head-pose deadline ends headless VR mode. → docs/DEVICE_NOTES.md#issue-triage-round-2026-10-06
**Lepton storage:** each app's /sdcard has `Movies`/`Download`/`Documents` symlinked to the Frame's `~/Videos`/`~/Downloads`/`~/Documents` (agent `storage_targets`); the media index never works; Lepton grants all runtime permissions. → docs/DEVICE_NOTES.md#lepton-storage
@@ -596,6 +638,8 @@ Toy Master doesn't request a model after that (it uses its own), so the glb load
**Cube swapchains:** the runtime refuses `faceCount=6` → FrameBridge `cube_standin` (default on, GLES only, `native/adapter/cube_standin.c`). → docs/DEVICE_NOTES.md#cube-swapchains
**Hardware video decoding:** `native/hevc` OMX plugin (`OMX.frameport.{avc,hevc,vp9}.decoder`), installed once per Frame (`ensure_video_codec`, agent `video_codec_status`/`install_video_codec`/`video_codec_switch`); **bump `revision` in native/hevc/build.py with every artifact change**; per game `frame.hw_video_decode` (analysis `media_codec`), Settings `video.hw_decode`, `FRAMEPORT_NO_HW_VIDEO=1`; Batman migration `batman_video_patches` + `surface_native`. → docs/DEVICE_NOTES.md#hardware-video-decoding
**Vulkan shader dump:** adapter `vk_shader_dump=1` (`native/vkshim/shader_dump.h`) writes SPIR-V modules + `index.txt` to `files/fp_vk_shaders/`; `collect_diag` returns the newest session's modules (`shader_dumps`); triage `gpu-hang`, `triage.graphics_api`. → docs/DEVICE_NOTES.md#vulkan-shader-dump
**Foveation centre (#394):** Valve's FDM layer centres its density map on the whole swapchain (not the eye's rect or optical axis) and Turnip picks density per GMEM bin (the sharp area snaps to bins, so its size shifts with render resolution: driver design); `VK_LAYER_FRAMEPORT_fdm_centre` (native/foveation/centre.h, below Valve's layer, views from FrameBridge `fdm_views.c`) rewrites the per-eye density-map offsets; FrameBridge `snapshot=N` reads Vulkan eyes back. → docs/DEVICE_NOTES.md#foveation-sharp-area-centre-and-size-394
**Expansion file names (#450/#481):** OBBs with a download's copy suffix (`main.203.com.Armature.VR4-003.obb`) or another case are installed under the game's name (`quest_dump.obb_names`/`frame_manifest`, PC files untouched), other kinds too (#415: Crisis Brigade 2's `office.222.<pkg>.obb`, kind spelling kept, never an "another app" warning); another app's name (#129), duplicates and unclear cases stay warnings. → docs/DEVICE_NOTES.md#expansion-file-names-450-481
**Unreal OBB check (#159):** `frame.unreal_skip_obb_check` (analysis `unreal_verify_obb`) turns off Epic's OBB CRC pass; triage `unreal-obb-check-stuck`. → docs/DEVICE_NOTES.md#unreal-obb-check
**Issue round 2026-10-12:** Lepton breaks on unquoted paths with spaces → launchers give Lepton a `~/.local/share/frameport/lepton-paths/<pkg>` link (`app_dir_lines`/`set_app_dir`/`launcher_base`); `frame.eos_keychain_loop`, `frame.unity_tls_key_pool` (`libfp_tkeys.so`, `elf.rename_imports`), `frame.vermillion_scene_canvas`; `tools/cpp2il.py` falls back to Cpp2IL's dev build for metadata v107; Linux `desktop_icon`; `scripts/upload_bench.py`. → docs/DEVICE_NOTES.md#issue-round-2026-10-12
**OpenSSH uploads (#324/#242):** `native_upload.quote` escapes only backslash and `"`, Win32 local paths go as `C:/…`; `Frame.auth` records the login that worked (app_key / user_key from `ssh.extra_keys`, `frame ssh-keys`, agent, password); strict IdentitiesOnly first, relaxed retry. → docs/DEVICE_NOTES.md#openssh-uploads
@@ -699,7 +743,8 @@ short recap of the thread so far; read **all** comments on a thread first (a lat
- **How a change reaches users** (decide this before promising a fix):
- *Catalog / recipe / triage* changes reach **installed** apps within ~6 h with no build — apps fetch
`catalog/games/*.yaml` + `triage.yaml` from `main` (`catalog.refresh_remote`), recipes follow via `catalog_rev` →
"Update on Frame". So accepting a recipe or adding a triage signature is "live" once pushed.
"Update on Frame". So accepting a recipe or adding a triage signature is "live" once pushed (a signature that
suggests a patch/setting the installed app doesn't have yet is skipped there: needs a release; `min_app` gates it).
- *Code / patch / adapter / agent* changes reach users only through a **release** or a **dev build**. For a per-game
fix a reporter should try now: push to `main`, cut a dev build (Actions → build → `dev` ticked, with `notes`), tell
them to install it via **Settings → Updates → "Install the latest dev build…"** and then rebuild the game on the
@@ -761,3 +806,21 @@ the unresolved eye distortion, and testing the release bundles on real Windows/m
(regenerates docs/PATCHES.md + site/src/data/patches.json, the site's id → anchor map; a test runs `--check`).
- Known-good backups of every working APK and the signing keys: `PATCHED/_known-good-2026-09-28/` (don't delete).
- Your development Frame: `frameport frame info` (remembered in `<user data>/frames.json`); SSH as `steamos@<frame>`.
Steam library scheduling (#305, agent v99): `install.steam_library` = now/later/off; agent `library_mode` persists it.
Automatic restarts also hold on a fresh local `frameport-app/gui.alive` (10 s; existing 12 h cap).
Later journals changes and installs steam.service ExecStartPre/ExecStartPost hooks to reapply after Steam's exit
writes and verify before clearing; preserve this ordering and avoid locking across systemctl's startup hooks.
Off Play (also pending Later Play) uses detached systemd-run launch.sh, with no shortcut/devkit registration;
Steam's per-game controller/overlay/Exit game integration is lost. Restart Steam now explicitly bypasses holds,
asks before ending a running game, and closes local FramePort/Desktop Mode. Purge removes the startup hook.
Hook hardening: both lines `-` + `/usr/bin/timeout -k 5 20`; ExecStartPost only `systemd-run --no-block`s the
verify (unit frameport-library-verify) so Steam's start never waits; drop-in removed once mode != later and nothing
pending (`drop_library_hooks_if_idle`). Steam = static user unit steam.service (Type=simple, Restart=always, 90 s).
Agent v124: a waiting `now` worker holds the shortcut lock (`shortcut_lock`) for up to 12 h, so nothing an SSH command
reaches blocks on it (an install's `library_mode` hung until the 600 s agent timeout): `library_mode` tries once and
skips the hook cleanup; `cmd_shortcuts` journals into the waiting worker (`pending_lock`, a short separate lock;
the worker writes "running" under it before merging the journal after stop_steam, one restart for all; the PC
shows the same "waiting" reason); `queue_library` waits ≤30 s, else journal only; runs drop what they applied
(`consume_pending`), never later entries.
+28 -30
View File
@@ -2,12 +2,17 @@
Thanks for helping. The quickest contributions:
- **A game works on the Frame?** In FramePort: the game's menu → **Share working config…** opens a prefilled issue
with its recipe. Accepted configs become built-in recipes.
- **Something doesn't work?** The game's menu → **Report a problem…** saves a diagnostics zip (personal data
removed) and opens a prefilled issue to attach it to.
- **A game works on the Frame?** Game menu → **Recipe → Share working recipe…** opens a prefilled issue. After
review the recipe becomes a built-in recipe (`catalog/games/<package>.yaml`), and installed copies of FramePort get
the recipe within 6 hours.
- **Something doesn't work?** Game menu → **Troubleshoot → Report a problem…** saves a diagnostics zip (personal data
removed) and opens a prefilled issue to attach the zip to.
Without the app: [working recipe form](https://github.com/spoopyghosty0/frameport/issues/new?template=working-config.yml)
· [problem report form](https://github.com/spoopyghosty0/frameport/issues/new?template=bug-report.yml).
## Development
```
uv sync --extra dev # Python 3.11+, uv (https://docs.astral.sh/uv/)
uv run frameport-gui # the app
@@ -15,39 +20,32 @@ uv run frameport --help # the command line
uv run pytest # tests (no headset or game files needed)
uv run ruff check . # lint
```
- Code and architecture: `CLAUDE.md`, `docs/ARCHITECTURE.md`; per-game symptoms and fixes: `docs/PLAYBOOK.md`.
- Interface wording: `docs/STYLE.md`. GUI texts go through `tr()`; after changing them run
`python scripts/i18n_extract.py`.
- Translations: see [Translating FramePort](#translating-frameport) below.
- New fixes are patch modules (`src/frameport/patches/`), with a triage signature (`catalog/triage.yaml`), a PLAYBOOK
row and a unit test.
- Native binaries in `artifacts/` are rebuilt with `python native/build.py` (downloads the NDK).
## Adding a tested game
Tested a game on the Steam Frame? The easiest way is in FramePort: open the game → **…** → **Share working config…**.
It opens a prefilled GitHub issue with the exact recipe; after review a workflow turns it into
`catalog/games/<package>.yaml`. Without the app: [working config form](https://github.com/spoopyghosty0/frameport/issues/new?template=working-config.yml). Something doesn't run: the game's
**Report a problem…** (diagnostics zip, personal data removed) or the [problem report form](https://github.com/spoopyghosty0/frameport/issues/new?template=bug-report.yml).
After catalog changes, regenerate the games list: `python scripts/compat_list.py`.
- Where things are: `docs/ARCHITECTURE.md` (module notes in `CLAUDE.md`), `docs/PLAYBOOK.md` (symptoms and fixes),
`docs/FRAME_RUNTIME.md` (runtime facts).
- A new fix = a patch module (`src/frameport/patches/`) + a triage signature (`catalog/triage.yaml`) + a PLAYBOOK row
+ a unit test.
- After changing a patch, game setting, recipe or triage signature: `python scripts/patch_docs.py`. After catalog
changes also `python scripts/compat_list.py`.
- GUI texts go through `tr()`; after changing them run `python scripts/i18n_extract.py`. Wording rules:
`docs/STYLE.md`.
- Docs screenshots and videos are rendered, never taken by hand: `docs/SHOWCASE.md`.
- Native binaries in `artifacts/`: `python native/build.py` (downloads the NDK).
## Translating FramePort
The app's texts (screens, help, patch and setting descriptions) can be translated; the command line, logs and
diagnostics stay English. No programming needed:
1. Copy `src/frameport/locales/template.json` to `src/frameport/locales/<code>.json`, where `<code>` is the language
code (`de`, `fr`, `pt`, `ja`, …).
2. Add `"_language": "<the language's own name>"` (e.g. `"Deutsch"`); it's shown in Settings → Language.
3. Fill in the values. Each key is the English text; leave a value empty to keep the English text. Plural entries
have a list value: `["<one>", "<other>"]`. Keep `{placeholders}` such as `{title}` or `{n}` exactly as they are,
and keep `…`, `·` and line breaks where the English has them.
4. Try it: `uv run frameport-gui`, choose the language in Settings → Language, restart FramePort.
5. Open a pull request with the file. When the English texts change, `python scripts/i18n_extract.py` refreshes the
template; new texts then show in English until they're translated.
The app's texts can be translated, no programming needed. The command line, logs and diagnostics stay English.
Wording rules for English (and a guide for tone) are in `docs/STYLE.md`.
1. Copy `src/frameport/locales/template.json` to `src/frameport/locales/<code>.json` (`de`, `fr`, `pt`, `ja`, …).
2. Add `"_language": "<the language's own name>"`, for example `"Deutsch"`.
3. Fill in the values. Each key is the English text; an empty value keeps the English. Plural entries take a list:
`["<one>", "<other>"]`. Keep `{placeholders}` such as `{title}` exactly, and `…`, `·` and line breaks where the
English has them.
4. Try the translation: `uv run frameport-gui`, pick the language in Settings → Appearance → Language, restart FramePort.
5. Open a pull request with the file. New English texts show in English until they're translated.
## Ground rules
- Use only games you own. Contributions that help bypass DRM, licence or entitlement checks, or that add game files,
are not accepted.
- Never commit personal data (IP addresses, user names, home paths, Steam IDs).
+47 -49
View File
@@ -8,78 +8,73 @@
![Steam Frame](https://img.shields.io/badge/Steam%20Frame-supported-1b2838?logo=steam&logoColor=white)
Install Quest games, Android apps, Linux apps and PC VR games on the **Valve Steam Frame**. FramePort sets up the
Frame, patches each game so it runs there, uploads it and adds it to your Steam library with artwork.
Frame, patches each game to run there, uploads the game and adds the game to your Steam library with artwork.
[![FramePort: library, one-click install, play, monitor](docs/images/tour-teaser.webp)](docs/media/frameport-tour.mp4)
▶ [Watch the full tour](docs/media/frameport-tour.mp4) · New to FramePort? [Watch the install tutorial](docs/media/frameport-install.mp4)
▶ [Watch the tour](docs/media/frameport-tour.mp4) · [Watch the install tutorial](docs/media/frameport-install.mp4)
(about 90 seconds each)
> **Notice:** FramePort doesn't download, share or unlock games. Use games you got legally, for example from
> [SideQuest](https://sidequestvr.com/). FramePort downloads published open-source tools (see [Built on](#built-on))
> and adds its own patches so games run on the Frame.
> [SideQuest](https://sidequestvr.com/). FramePort downloads published open-source tools ([Built on](#built-on))
> and adds its own patches.
>
> Not every game runs on the Frame: recipes are tested by the community, and some games need Meta's services or
> hardware the Frame lacks.
> Not every game runs on the Frame. Some need Meta's services or hardware the Frame lacks.
## Features
![Library](docs/images/library.png)
- **Easy setup:** one line in the Frame's terminal. No root, no password. [What it changes](docs/FRAME_SETUP.md).
- **One click per game:** patch, upload, add to Steam with artwork and test that it starts.
- **Recipes:** tested patches and settings for 120+ games; other games get suggested patches, each explained in
plain words.
- **One click per game:** patch, upload, add to Steam with artwork, test that the game starts.
- **Recipes:** tested patches and settings for hundreds of games. Other games get suggested patches, each explained.
- **Game settings:** sharpness, refresh rate, controllers, 360° video and mixed reality as simple switches.
- **More than Quest games:** Android apps in a window, Linux apps, PC VR games and Windows programs.
- **Install links:** "Install with FramePort" buttons on websites ([frameport.app](https://frameport.app) links) open
in FramePort.
- **Your Frame from your PC:** Type on Frame (your keyboard on the Frame), Files, Screenshots, Live view (what the
headset shows, in your browser) and Monitor (frame rate, temperatures, battery, processes).
- **Install links:** "Install with FramePort" buttons on websites open in FramePort.
- **Your Frame from your PC:** Type on Frame, Files, Screenshots, Live view (what the headset shows) and Monitor
(frame rate, temperatures, battery, processes).
- **Your room for mixed reality (experimental):** scan your room in the headset and fix the scan up in 3D. Try the room with
[Test Quest MR](https://github.com/spoopyghosty0/TestQuestMR).
- **Updates itself**, and reports problems without personal data.
Details for each: [Install and first steps](docs/INSTALL.md).
![Monitor](docs/images/monitor.png)
![Screenshots](docs/images/screenshots.png)
![Room (experimental): the scanned room in 3D, clean-up and labels](docs/images/room.png)
## Quick start
1. [Download](https://github.com/spoopyghosty0/frameport/releases/latest) the build for Windows, macOS (Apple
Silicon) or Linux, unpack it and start FramePort.
2. In FramePort click **Steam Frame → Start setup**. The Frame and your PC must be on the same Wi-Fi (or use a USB
cable).
3. On the Frame open the **SteamVR dashboard → Launch a program → Desktop**, then the app menu → **System →
Konsole**, and run:
1. [Download](https://github.com/spoopyghosty0/frameport/releases/latest) FramePort for Windows, macOS (Apple
Silicon) or Linux, unpack the download and start FramePort.
2. Click **Steam Frame → Start setup**. The Frame and your PC must be on the same Wi-Fi (or use a USB cable).
3. On the Frame open **SteamVR dashboard → Launch a program → Desktop**, then **app menu → System → Konsole**, and
run:
```
curl -fsSL https://frameport.app/s | bash
```
4. Click **Allow** in FramePort when it shows the same 4-digit code as the Frame. Steam restarts once; if it asks to
install **Lepton** (Valve's Android runtime), confirm it.
5. **Add games → Scan a folder…** with your games, open one and click **Install on Frame**. Play it from the Frame's
Steam library.
4. Click **Allow** when FramePort shows the same 4-digit code as the Frame. Steam restarts once. If Steam asks to install
**Lepton** (Valve's Android runtime), confirm.
5. **Add games → Scan a folder…**, open a game and click **Install on Frame**. Play the game from the Frame's Steam library.
Full guide, firewalls and troubleshooting: [Install and first steps](docs/INSTALL.md). How to lay out game folders:
[FAQ](docs/FAQ.md).
Full guide: [Install and first steps](docs/INSTALL.md). Game folders: [FAQ](docs/FAQ.md).
## Compatibility
Tested games use their recipe (the patches and settings that work for them) automatically; for other games FramePort
suggests patches. See the [list of tested games](docs/GAMES.md). Got a game working? Share its recipe from the game's
**…** menu: [how](docs/INSTALL.md#share-a-recipe-or-report-a-problem).
Tested games get their recipe (the patches and settings that work) automatically. Other games get suggested
patches. See the [tested games](docs/GAMES.md). Got a game working?
[Share its recipe](docs/INSTALL.md#share-a-recipe-or-report-a-problem).
## Compared with other tools
FrameDrop and Valve's own tools install an app as it is. FramePort differs in four ways:
FrameDrop and Valve's own tools install an app as it is. FramePort also:
- **Free and open source** (GPL-3.0). FrameDrop is free (donationware) without published source.
- **Quest games that don't run on the Frame as they are** get converted and patched, with a tested recipe for 120+
games. The others install the game unchanged.
- **Windows, macOS and Linux.** FrameDrop is for Windows.
- **Wi-Fi or a USB cable**, and no **Pair new host** step.
- is **free and open source** (GPL-3.0). FrameDrop is free (donationware), without published source.
- **converts and patches Quest games** that don't run as they are, with tested recipes for hundreds of games.
- runs on **Windows, macOS and Linux**. FrameDrop is for Windows.
- connects over **Wi-Fi or a USB cable**, without a **Pair new host** step.
<details>
<summary>All differences</summary>
@@ -88,12 +83,12 @@ FrameDrop and Valve's own tools install an app as it is. FramePort differs in fo
|---|---|---|---|
| Cost and source code | Free, open source (GPL-3.0) | Free (donationware), source not published | Free, from Valve |
| Runs on | Windows, macOS, Linux | Windows | Depends on the tool |
| First connection | One line in the Frame's terminal; it turns on Developer Mode itself. No password | Turn on Developer Mode, then **Pair new host** | Turn on Developer Mode and pair, or use Android's debug tool (adb) |
| First connection | One line in the Frame's terminal; turns on Developer Mode itself. No password | Turn on Developer Mode, then **Pair new host** | Turn on Developer Mode and pair, or use Android's debug tool (adb) |
| Wireless or cable | Wi-Fi, the Frame's hotspot or a USB cable | Same Wi-Fi network | Wi-Fi, or adb |
| Quest games that don't run as they are | Converted and patched for the Frame | Installed as they are | Installed as they are |
| Knows which patches a game needs | Tested recipes for 120+ games, updated without an app update | Not stated | No |
| Knows which patches a game needs | Tested recipes for hundreds of games, updated without an app update | Not stated | No |
| In the Steam library | Yes, with artwork and tags | As a "Devkit Game" shortcut | As "Devkit Game: &lt;title&gt;"; not with adb |
| Android apps, Linux apps, Windows programs | All three; Proton (runs Windows programs) is installed for you | All three; install Proton first | Yes; 2D Android apps need an extra file |
| Android apps, Linux apps, Windows programs | All three; Proton is installed for you | All three; install Proton first | Yes; 2D Android apps need an extra file |
| PC VR games | On your PC; some also on the Frame | Not supported | Not supported |
| "Install with …" buttons on websites | Yes ([frameport.app](https://frameport.app) links) | Its own | No |
| A game doesn't start | A launch test reads the logs and suggests a patch | A log viewer | No help |
@@ -101,10 +96,10 @@ FrameDrop and Valve's own tools install an app as it is. FramePort differs in fo
</details>
Other tools as described on their own pages, checked 2026-10-09:
Based on each tool's own pages, checked 2026-10-09:
[FrameDrop about](https://framedropvr.com/about) · [how-to](https://framedropvr.com/how-to) ·
[Valve: loading games on Steam Frame](https://partner.steamgames.com/doc/steamhardware/steamframe/loadgames).
Out of date? [Report a problem](https://github.com/spoopyghosty0/frameport/issues/new).
Out of date? [Report the problem](https://github.com/spoopyghosty0/frameport/issues/new).
## Built on
@@ -119,14 +114,17 @@ What FramePort adds: [Architecture](docs/ARCHITECTURE.md).
| | |
|---|---|
| [Install and first steps](docs/INSTALL.md) | Install, connect, update, PC VR games, files, problem reports |
| [What the setup changes](docs/FRAME_SETUP.md) | What setup changes on the Frame, networks and firewalls, undoing it |
| [Compatibility](docs/COMPATIBILITY.md) | What runs and how well |
| [Tested games](docs/GAMES.md) | Tested games and how well they run |
| [FAQ](docs/FAQ.md) | Game folders and common questions |
| [Porting playbook](docs/PLAYBOOK.md) | Symptoms and fixes per game |
| [Steam Frame runtime reference](docs/FRAME_RUNTIME.md) | Facts about the Frame's runtime |
| [Architecture](docs/ARCHITECTURE.md) | How the code is organized |
| [Install and first steps](docs/INSTALL.md) | Install, connect, install games, update |
| [What the setup changes](docs/FRAME_SETUP.md) | Changes on the Frame, firewalls, undoing it |
| [FAQ](docs/FAQ.md) | Game folders and fixing problems |
| [Compatibility](docs/COMPATIBILITY.md) · [Tested games](docs/GAMES.md) | What runs, and how well |
| [Controller buttons](docs/CONTROLLERS.md) | Quest buttons on the Frame's controllers |
| [Themes](docs/THEMES.md) | Color themes and making your own |
| [Install button](docs/INSTALL_BUTTON.md) | An "Install with FramePort" button for your download page |
| [Diagnostics](docs/DIAGNOSTICS.md) | What a problem report contains |
| [Patch reference](docs/PATCHES.md) | Every patch and game setting |
| [Porting playbook](docs/PLAYBOOK.md) · [Runtime reference](docs/FRAME_RUNTIME.md) | Symptoms and fixes; facts about the Frame |
| [Architecture](docs/ARCHITECTURE.md) · [Screenshots and videos](docs/SHOWCASE.md) | How the code and the docs' pictures are made |
| [Contributing](CONTRIBUTING.md) | Code, recipes, translations |
## Development
+3 -1
View File
@@ -1,6 +1,6 @@
# Third-party notices
FramePort is GPL-3.0-only (see `LICENSE`). It includes or downloads the following third-party work.
FramePort is GPL-3.0-only (see `LICENSE`). FramePort includes or downloads the following third-party work.
## Included in this repository / the release bundles
| Component | Where | License |
@@ -25,6 +25,8 @@ FramePort's own native code (the FrameBridge adapter, GL/Vulkan/OpenXR shims, th
| Eclipse Temurin JRE | api.adoptium.net | GPL-2.0 with Classpath Exception |
| apksigner (Android build-tools) | dl.google.com Android repository | Apache-2.0 |
| Revive (portable copy, only if Revive isn't installed) | github.com/LibreVR/Revive releases | GPL-3.0 |
| Cpp2IL (only for Unity IL2CPP patches) | github.com/SamboyCoding/Cpp2IL releases | MIT |
| APKEditor (only for app bundles with resource splits) | github.com/REAndroid/APKEditor releases | Apache-2.0 |
Valve's Lepton, Proton and SteamVR, and Meta's software, are used on your devices as installed by Steam / Meta;
FramePort doesn't distribute them.
+3007 -83
View File
File diff suppressed because it is too large. Load diff
+11 -9
View File
@@ -1,16 +1,18 @@
# Announcements
`current.md` is the one announcement FramePort shows as a pop-up in the app. Edit it on `main`: the app reads it
from GitHub `main` (raw.githubusercontent.com) at most every 6 hours, so a push reaches everyone without a release.
`current.md` is the one announcement FramePort shows as a pop-up in the app. Edit `current.md` on `main`: the app
reads the file from GitHub `main` (raw.githubusercontent.com) at most every 6 hours, so a push reaches everyone
without a release.
## Who sees it
- **Only people who already used FramePort before the announcement's `date`.** A new install never shows one, and
nor does an announcement published before FramePort was installed.
- **Once.** Closing it in any way (the X, a click outside it, Escape, or its button) dismisses it for good. The app
remembers dismissals in its settings (`announce.dismissed`).
- **A new announcement = a new `id`.** Fixing a typo with the same `id` doesn't show it again to anyone who closed it.
A new `id` shows to everyone who used FramePort before its `date`, whether they closed the earlier one or not.
- **Only people who used FramePort before the announcement's `date`.** A new install never shows an announcement,
and neither does an announcement published before FramePort was installed.
- **Once.** Closing the pop-up in any way (the X, a click outside, Escape, or the pop-up's button) dismisses the
announcement for good. The app remembers dismissals in its settings (`announce.dismissed`).
- **A new announcement = a new `id`.** A typo fix with the same `id` doesn't show the announcement again to anyone
who closed it. A new `id` shows to everyone who used FramePort before its `date`, whether they closed the earlier
announcement or not.
## The file
@@ -31,7 +33,7 @@ The body, in Markdown: **bold**, *italic*, `code`, [links](https://frameport.app
The body is Markdown (no HTML). A `date` in the future works as a schedule: nobody sees it before then.
Images look best at about 2:1 (e.g. 1200×600). The pop-up is 600 px wide and shows between 140 and 320 px of the
Images look best at about 2:1 (for example 1200×600). The pop-up is 600 px wide and shows between 140 and 320 px of the
picture's height.
`pytest tests/test_announcements.py` checks this file, so a broken announcement fails CI instead of silently showing
+47 -13
View File
@@ -1,32 +1,66 @@
1a4dce5c4a6d0dfc5f20e55ac29e70c73cc2cc124c21ca6a7e1b316e6afb1c79 ./arm64-v8a/libVkLayer_fdm_darken.so
5becb96ee86fbda0ce98c0e0fd064f8ba092314aceaa400e3dcc785705dc3c23 ./arm64-v8a/libVkLayer_fp_shaderfix.so
222727ddabf7eaee08c92e86c64f02edc6639667e9041ab2629032b885c9ae3a ./arm64-v8a/liba32bridge.so
c9c3da5cac224c38e2210b781bd12b7f97e02bd6b0ebb0ef85543e4ea4b76671 ./arm64-v8a/liba32rt.so
dfeee15b52a530aef0fc90f79140249522adf888d1c88fd57935dd8ce5257fa5 ./arm64-v8a/libVkLayer_fdm_darken.so
86974202436e9209e260a690ae3eb0082d7d0f88e17c621dd77c0788ea66bc6d ./arm64-v8a/libVkLayer_fp_shaderfix.so
e63d93e086df3b7b29501188b80fb113879e2fd325d7659f68a31ac5bc87b561 ./arm64-v8a/liba32bridge.so
81b073b0cdf11fdb09d22dff682884c5046fe13801f18db9aed232e86f3bf173 ./arm64-v8a/liba32rt.so
18d8d917e83a6d87008f41908eb478dff635e798844e125abd1e8a5cf31805e2 ./arm64-v8a/liba32stub.so
d6337034fb0bdcca7ef9b7063d85b7586b8508b63b435959e8fffaba0691091c ./arm64-v8a/libfp_langpack.so
845905e8c2da617dddcb9625f4ed38e06f1d85f9c729b55dacb2c59488074c3e ./arm64-v8a/libfp_langpack.so
69102b128e00fa1809489a7308e09c1505f563bf7091bbdd3fe5a58e4cc96c2c ./arm64-v8a/libfp_luajit.so
321da502e0f8f46f0880aad39fe6b84bdef88f925164568814cf704a1b31a577 ./arm64-v8a/libfp_ovrp.so
40defdaddcda53bd2649eb48076fae1622bfc2bfc88e9e03c94fc8b45af2a4f2 ./arm64-v8a/libfp_ovrtrace.so
0167c2fde5dfde62897f9d85afc4fc8e97784e988b5b8df6cea8c407240b3424 ./arm64-v8a/libfp_tkeys.so
468b97ee3c36481d939a87425b15880c7a801d16732350e1e2832b385d63f20a ./arm64-v8a/libfp_vk.so
0055308856070aa7e09d80bcf66ea52dc0a495829b9da64383e38f4350706226 ./arm64-v8a/libfp_vk.so
3c548b567c6984c91bf3f4a2b0bae1336f569f3e9fa9c3204872fd9876f88284 ./arm64-v8a/libfp_xrruntime.so
383054f8b3b41dde76d062c71856cd3163655e50009c08454bc1793f393ead65 ./arm64-v8a/libfpg.so
4a13a33e112c9e4e3c5ff4337ed6e988a9e5b3602f48d654df148ef5fafbf426 ./arm64-v8a/libfpglmv.so
36400eae4ba3807bcfcd54463daa217347032b07218792faa448d8cbbd086a0e ./arm64-v8a/libframe_xrshim.so
19ba5ed3c4b780f5ae46251f6958f552acfc5f13c8bb39f995579593fa8990c6 ./arm64-v8a/libglshim.so
b1ec76d3c93862ef2e5dcffab44b4b45cdbd791df3c6870350a04be44a0e0137 ./arm64-v8a/libopenxr_loader_generic.so
dc8b8dd017934077ad181da0cd08b03581561822b189b580faa2b495e20eec7d ./arm64-v8a/libopenxr_loader_generic.so
1feaeafad467c4cafdf2b018a4d84b0bee200c3f711697b4ce97e66a3ba256ca ./arm64-v8a/libovrplatformcompat.so
a4ed80ae45ca90758239f152ea5a2e8c127d491e1e697ea5680db6fd7f72db07 ./arm64-v8a/libvrapi.so
a4ed80ae45ca90758239f152ea5a2e8c127d491e1e697ea5680db6fd7f72db07 ./arm64-v8a/libvrapi_foveation.so
b35a45e3e4948352a5433553420848eb7a8837afbe114edb1e95979872e25426 ./armeabi-v7a/libopenxr_loader_generic.so
c7a14d34e4ddf20ec943641f6431525867d6f030cd01160df1b24afd441af39f ./arm64-v8a/libvrapi.so
c7a14d34e4ddf20ec943641f6431525867d6f030cd01160df1b24afd441af39f ./arm64-v8a/libvrapi_foveation.so
200525569cd37551e606be93fc76e8ac41e9516b3ffa922a3d4ebe40ba6a3824 ./armeabi-v7a/libopenxr_loader_generic.so
6fd59e6c6e533c0a17204e4f12adaf992ffa6cf58d6280aa9b37ca7ba20299d4 ./dex/browser-handoff.dex
1871eae093432d277da4bc751bf5f3269dfcf11f9168260b0c3caadb0dedb19d ./dex/oculusos-stubs.dex
b634ab5640e258563c536e658cad87080553df6f34f62269a21d554844e58bfe ./hevc/COPYING.FFmpeg
141de01f0d40b97d4f9a720db5ab8ea442f6aa35db5272048899292884994a1c ./hevc/libstagefrighthw.so
4516971bbb2b635e19b14d2d37b9353962876f7de02043e7457327052c1fcbc0 ./hevc/manifest.json
55aae57d292e9536701f2f8a9dbaf1edcfdd766c5748d07a34da2f5ef197f212 ./hevc/libstagefrighthw.so
389352bf10c03ab54e784a43c9b217451dd814cacec1d7178777e337c9d6f7de ./hevc/manifest.json
46c3dcad2c43cc30bea3b3680b362ed84a99c15d60714bbbbb422c80ecf90405 ./hevc/media_codecs_frameport.xml
529ea35d5d82474afe9e09ad1216d269317f56dd24a05fb100fced52b7b4dbca ./hevc/podman.py.txt
6cda3076a8c09b31bb1f90da614ea89e7ee194589626eeac613e522849604e47 ./licenses/LuaJIT.txt
2cc16b90abcd3d359f1658c581172bd650017bf2725e24268915f50904c000ec ./linux-arm64-bin/fp_roomscan
b10b3a5c10c3339fc63fd9f6cb4d01ea29be11a863d0ebad1389ea69fd471940 ./linux-arm64-bin/fp_venc
1aa733117cf57ccff7cf23f0425dbfd73b0332a3ef1c905ceeca0ccd0449c4e0 ./linux-arm64/XR_APILAYER_FRAMEPORT_timefix.json
28c2430a02bbd8902c5bfb9562c6fd0e318654f9e05c095bfeb94b0450ab1b07 ./linux-arm64/libxr_frameport_timefix.so
b10b3a5c10c3339fc63fd9f6cb4d01ea29be11a863d0ebad1389ea69fd471940 ./linux-arm64-bin/fp_venc
00c2dead0fd7497929833467f0e55699d57d26be1b85dce35402993852f7b111 ./roomscan/ceiling.png
c1962de31ed2810d31c760cf9ee63316ac2b8c9528ccbcd9299ebf5ba39b2995 ./roomscan/done.png
0dfaea4c68979b0a45a9fef06fdf1a92468ffc8f46f80a3a014fce1d805972d5 ./roomscan/failed.png
f2bae84f1d1512f87b25e688acdddb29b3f360f3f0d0cd4fdeeb741a79e7b19a ./roomscan/finish_00.png
9be7720c45f162e99813cb9a7a03e026fed53b41f06637b30ded309eeac91759 ./roomscan/finish_01.png
220d699f879b3a8669cfaf4dc714496e8c1db7e7878e7cd12b1a41aec9b62faa ./roomscan/finish_02.png
42871b440b77449d4fe41be1c809a930148a874caa8bc92b13b5d25bb6effa83 ./roomscan/finish_03.png
a470f62624c94ed6791cc7ee03066e1ffb0a676d520658a0a8b02a6af1605b3b ./roomscan/finish_04.png
195ff1c649fd9b42bfa6eea29c43a8b67116fd6ffe9b0fe53dcbdb1074bd34fa ./roomscan/finish_05.png
a45accab86b02d7b78327a17b84a6fea543ecc549282055dd3182c686fc2b1b8 ./roomscan/finish_06.png
b88d6c590ea839a9d11b3a4de8c3effb39752f7114318966fddae09995e0fd37 ./roomscan/finish_07.png
4a3615db26cf765b855a997be3e067aed58464894dab4a6700fdec5c2b854501 ./roomscan/finish_08.png
f532a83044e707c66dbc74787ce7b844890bc05829d3e9c8f7e33dae9db246a5 ./roomscan/finish_09.png
ffce61a9f13bbb250fad3582396a5bec82a1bad1d585b7ef9b8f65d343806b26 ./roomscan/finish_10.png
4a63772adacb31004749ab04b592076bd36cda61eef52f59037d5abdc9e527db ./roomscan/finish_11.png
f373e7021cfce0d1078227f473425a10035ee426102b78f13e0fea4833b736d5 ./roomscan/finish_12.png
1147391822be3f1aa5351374b8fd9ec85f8b5ce40e3cb9f3146d778e6fbc652a ./roomscan/floor.png
eb3c8b55a9dbafa030797ca9f06a22c3ee3bbef96cb7adea26d433ebad43d43f ./roomscan/look_00.png
6ba965ff6d22a469c558f2a68229bd2ff48fc28badb95889ca245310d1dd3e96 ./roomscan/look_01.png
0a11cec25ebc76fe11d505d1f2ec162c9b4a6754393065800e73b1f81e2d94c8 ./roomscan/look_02.png
fa5a4c94d20af56797b9fcc111148767847a6633ade9217cab373de232efad90 ./roomscan/look_03.png
e80fa493e380fba39084be2ee62859adcff4e39aa66566abee10a4d6339c52e9 ./roomscan/look_04.png
133617f0d8d1e69c37408aac80033f71856b592b62e3b780cc12b446bd974680 ./roomscan/look_05.png
d5dd296ff23641c6973c57ac139147e99c7b783316ab60537adb2155dd196880 ./roomscan/look_06.png
c08570aa78f966ae937b2e21d0bad887c5352fbca56aa579a2a7ef8541fb96ad ./roomscan/look_07.png
3767e7db5fb6babc872fa62c42604f749c65936717d332101745b201cd450cd5 ./roomscan/look_08.png
2924dc65e5c497545340209edc16060e12e1834d11af6871d1c1baa50b7b2562 ./roomscan/look_09.png
cd0150dfc10b2aea39403c74eff72fd05fb0111178ef39b4c98657a6d16d105e ./roomscan/look_10.png
011355e412f73ade3896e9037490e607c4365d0cf8ceb807d236bf68b414d3ed ./roomscan/look_11.png
1b8b47ffb47568d540921f065b5958eeb44a6489498d58e0f33f5d1f535154e2 ./roomscan/look_12.png
926c7bc6a103adee5b9bf938f5d4e39095ab77fd6270b5301be3b0428edd9ae6 ./roomscan/start.png
c2c70f4af1a5c3e6089dff1130161dd417f8044f99ec639eeecf1083930aab16 ./win-x64/fp_oculushmd.exe
60ebc5fea05b8945082e2ca8b9f2eb74616012a26eb50133af273dff0fcddc42 ./win-x64/fp_vrsettings.exe
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -1,8 +1,8 @@
{
"revision": 8,
"revision": 11,
"runtime_sha256": "456e912c75cd389abcf6a63bc80e2a53bdc334371d00b200c93680388ae955e2",
"files": {
"libstagefrighthw.so": "141de01f0d40b97d4f9a720db5ab8ea442f6aa35db5272048899292884994a1c",
"libstagefrighthw.so": "55aae57d292e9536701f2f8a9dbaf1edcfdd766c5748d07a34da2f5ef197f212",
"podman.py": "529ea35d5d82474afe9e09ad1216d269317f56dd24a05fb100fced52b7b4dbca",
"media_codecs_frameport.xml": "46c3dcad2c43cc30bea3b3680b362ed84a99c15d60714bbbbb422c80ecf90405",
"COPYING.FFmpeg": "b634ab5640e258563c536e658cad87080553df6f34f62269a21d554844e58bfe"
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+7 -4
View File
@@ -1,9 +1,9 @@
package: ScaredBySquares.Game
title: Scared By Squares
status: unknown
status: works
notes: 'Showed black and dropped back to the home environment while the game kept running (sound only, GitHub 323).
Fixed in FramePort 1.2.1 and checked on the Frame without the headset (the game runs at 72 fps and SteamVR keeps it
as the running game); not yet confirmed in the headset. Rebuild and reinstall the game after updating FramePort.'
Fixed in FramePort 1.2.1 (confirmed in the headset by the reporter). Rebuild and reinstall the game after updating
FramePort.'
details: 'The game (Unreal 4.27, OpenXR) creates two controller actions named "turn" (an action mapping and an axis
mapping called Turn). The Frame''s runtime accepts the duplicate, then fails to load the input manifest it builds
from the actions ("SetXrInputConfig failed. Failed to load manifest") and treats the game as closed. FrameBridge''s
@@ -14,6 +14,9 @@ xr: OpenXR
frame:
- frame.hw_video_decode
- frame.unreal_skip_obb_check
updated: '2026-10-16'
verified:
date: '2026-10-17'
issue: 323
updated: '2026-10-17'
min_app: 1.2.1
source_hint: Scared By Squares
@@ -8,19 +8,21 @@ notes: 'Native OpenXR GLES video player. 360 theatres/videos (equirect2 layers,
details: 'Settings: equirect_emul (GLES worker draws 360 layers into a projection layer), stable_local, focus_hold,
scale 0.75; frame.swapchain_limit for its 7680x3840 theatre swapchains. Its hardware decoding mode (Java MediaCodec,
Vr4pMediaPlayer; its own FFmpeg is the software path) gets the Frame''s video hardware with frame.hw_video_decode
(added 2026-10-09, not yet checked in the headset).'
(added 2026-10-09, not yet checked in the headset). swapchain_pool shares extra GLES panel images to avoid the
runtime swapchain count cap (#387); host-tested only, menu interaction needs a headset check.'
tested_version: 2.0.22
engine: Other
xr: OpenXR
frame:
- frame.hw_video_decode
adapter:
swapchain_pool: 1
equirect_emul: 1
stable_local: 1
focus_hold: 1
scale: 0.75
verified:
date: '2026-10-01'
updated: '2026-10-10'
updated: '2026-10-18'
min_app: 0.12.1
source_hint: 4XVR Video Player
@@ -0,0 +1,16 @@
package: com.And7Limited.Hitstream
title: Hitstream
status: works
tested_version: 2.06bQuest
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
adapter:
controller_models: 1
haptic_fix: 1
notes: Fitness rhythm game; uses controller models and haptics fix.
verified:
date: '2026-10-12'
known_good_sha256: ecc9e2eee79073ae97ad5d3f70c21e8f049f899f21b51dfd541430bb7dd04cac
source_hint: Hitstream
@@ -0,0 +1,23 @@
package: com.Appnori.SummerSports
title: Summer Sports
status: works
tested_version: 0.5.1
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.unity_runtime_msaa_off
- frame.unity_gl_shim
device:
- device.text_input_window
adapter:
haptic_fix: 1
verified:
date: '2026-10-17'
known_good_sha256: 582adf5a538eb9565921cc0384e61bf113ab9215c1ad462fade82d06ad3302fa
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 395
source_hint: All in One summer Sports VR
@@ -0,0 +1,29 @@
package: com.BaggyG.JKXR_Companion_App
title: JKXR_Companion_App
status: unknown
notes: 'JKXR''s companion app: it manages JKXR''s mods and start options in /sdcard/JKXR. On the Frame each game
has its own /sdcard, so this recipe shares JKXR''s folder with it (device.shared_folder). Install JKXR first.
Starting JKXR from the companion app can''t work (each game runs in its own container): start JKXR from Steam.
Shared folder not yet confirmed by a player (GitHub 440).'
tested_version: '1.0'
engine: Unity
xr: VrApi
frame:
- frame.unity_text_input
device:
- device.text_input_window
adapter:
haptic_fix: 1
verified:
date: '2026-10-20'
known_good_sha256: 75ee0487ed6253a682b388df7ff06c6f7f35b2ce1b5a71341aed815bf6d60b34
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 109
issue: 440
source_hint: jkxrcompanion_115meta
shared_folder:
game: com.drbeef.jkxr
folder: JKXR
min_app: 1.3.1
@@ -0,0 +1,23 @@
package: com.BanzaiStudios.GAZZLERS
title: GAZZLERS
status: unknown
notes: Stopped at start with "Current Platform is not supported" (GitHub issue 404); the recipe makes the game take
its Meta Quest path. The fix builds and applies offline; not yet checked on the Frame.
details: The game chooses between its Meta Quest and PICO code from SystemInfo.deviceModel and throws for any other
device; Lepton's Android reports Valve Lepton (write-once ro.product properties). frame.gazzlers_quest_platform
makes PlatformDeterminer.GetAndroidPlatform return Platform.Meta.
tested_version: 1.4.1.7857
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.gazzlers_quest_platform
device:
- device.text_input_window
adapter:
haptic_fix: 1
verified:
date: '2026-10-23'
issue: 404
updated: '2026-10-23'
source_hint: Gazzlers
@@ -0,0 +1,23 @@
package: com.BolverkGamesFlat2VR.SurvivingMarsPioneer
title: 'Surviving Mars: Pioneer'
status: works
tested_version: 1.0.14
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.hw_video_decode
device:
- device.text_input_window
adapter:
haptic_fix: 1
scale: 2.0
verified:
date: '2026-10-18'
known_good_sha256: 3a9ff281417c219736ee10969e6ce4f7d8395472cb60718db8839d65edac4777
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 399
source_hint: Surviving Mars Pioneer
@@ -0,0 +1,24 @@
package: com.CarbonStudio.TheWizards
title: The Wizards
status: works
tested_version: '1.11'
engine: Unreal
xr: VrApi
alt_overport:
- patch_remove_unreal_force_quit
use_alt: true
frame:
- frame.unreal_thumb_touch
adapter:
haptic_fix: 1
pose_time_fix: 1
scale: 2.0
verified:
date: '2026-10-18'
known_good_sha256: c1d979d746c2be941e150e948aec755d85034de829abfe30e5bf0761a49135ef
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 397
source_hint: the wizards
@@ -0,0 +1,25 @@
package: com.CortopiaStudios.Spectre
title: Spectre
status: works
notes: Works since 1.2.1 (the loading screen waited for a Meta analytics request).
tested_version: 1.0.1.1354
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.hw_video_decode
- frame.cortopia_org_id
device:
- device.text_input_window
adapter:
haptic_fix: 1
scale: 2.0
verified:
date: '2026-10-17'
known_good_sha256: a37a5400ef58906b575f6da1649b62ac7ce024eab831fae105457c1d5d12c2de
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 390
source_hint: Wonder
@@ -0,0 +1,30 @@
package: com.CyDream.BattleTalent
title: BattleTalent
status: issues
notes: "Plays normally. The mixed-reality mode doesn't appear in the start menu (also with an APK from a Quest 3); MR
progress in #355. LAN multiplayer works; online rooms need Meta's account check (user proof), so online
multiplayer can't work (#408)."
tested_version: '4.7'
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.hw_video_decode
- frame.luajit_pointers
- frame.unity_runtime_msaa_off
- frame.meta_permissions
- frame.unity_multipass
device:
- device.text_input_window
adapter:
haptic_fix: 1
scene_emul: 1
verified:
date: '2026-10-17'
known_good_sha256: 17bbf8d7fc0f24d61986a0c5e1e9175cfe1239de6f8bcb2f588a57f80d83a1d3
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 381
source_hint: com.CyDream.BattleTalent
@@ -0,0 +1,26 @@
package: com.EgerterSoftware.MovieDeckforPlex
title: Movie Deck for Plex
status: works
notes: Works out of the box and absolutely fantastically so.
tested_version: '6.4'
engine: Unity
xr: OpenXR
frame:
- frame.meta_permissions
- frame.unity_text_input
- frame.hw_video_decode
device:
- device.text_input_window
adapter:
controller_models: 1
haptic_fix: 1
scene_emul: 1
verified:
date: '2026-10-20'
known_good_sha256: 397912f98ded90df0dabeb51d097c56de9b70ef99674303fa0efba84d43c4df0
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 109
issue: 435
source_hint: Movie Deck For Plex
@@ -0,0 +1,25 @@
package: com.GexagonVR.HardBullet
title: HardBullet
status: issues
notes: Loading screens (a cube overlay) are missing or corrupted up to FramePort 1.2.1; cube_quads (next release)
shows them as six panels, not confirmed in the headset yet. Level loads stall frame submission for up to ~1 s, so
the view freezes during loads.
tested_version: 1.0.9.704Q
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.hw_video_decode
device:
- device.text_input_window
adapter:
haptic_fix: 1
verified:
date: '2026-10-17'
known_good_sha256: ecbb758d98083a590f100d5ac6efe9490ef74ad39b59217e0b4a11db920ecd51
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 96
issue: 385
source_hint: HARD BULLET
@@ -0,0 +1,20 @@
package: com.Iconik.LittleNightmaresVR
title: Little Nightmares VR
status: works
tested_version: 1.0.31
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.hw_video_decode
device:
- device.text_input_window
verified:
date: '2026-10-18'
known_good_sha256: 171e586bf35ee4494874c6f2c37fb734f718e5b81744b2df9095919398d70839
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 96
issue: 421
source_hint: Little Nightmares VR- Altered Echoes
@@ -0,0 +1,20 @@
package: com.Meta4.TFBeyondReality
title: 'Transformers Beyond Reality: Redux'
status: unknown
notes: Starts and runs at 72 fps in headless launch tests (2026-10-17); not yet checked in the headset. Steam's shader
cache layer is left out and a few shaders the Frame's driver refuses are skipped, so some objects may be missing.
details: Unreal Engine game (Binned3 allocator, GitHub issue 349). Crash 1 - the allocator's 76 GiB up-front
reservation is refused by the Frame's kernel (frame.unreal_noreserve, suggested by analysis). Crash 2 - Unreal's
"Shader compilation failures are Fatal." With Lepton's Fossilize layer loaded every graphics pipeline failed with
VK_ERROR_OUT_OF_HOST_MEMORY, even a constant-colour one (not the pipeline cache, not the CPU allocator, not Valve's
FDM/RPO layers); vk_no_fossilize takes the layer out of the game's instance. A few pipelines with the game's
multiview vertex shaders then still fail in Turnip; vk_pipeline_fallback creates them with blank shaders.
tested_version: 1.495.34291
engine: Unreal
xr: OpenXR
adapter:
vk_no_fossilize: 1
vk_pipeline_fallback: 1
verified:
date: '2026-10-17'
issue: 349
@@ -0,0 +1,19 @@
package: com.MoonMonsterStudios.SpaceControl
title: SpaceControl
status: works
tested_version: 1.1.2
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
device:
- device.text_input_window
verified:
date: '2026-10-20'
known_good_sha256: 60b900a0a73a693426b85d81a489c63fab6cc959939f80efd29632945e0ce559
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 109
issue: 447
source_hint: Space Control
@@ -0,0 +1,23 @@
package: com.MyronSoftware.Deisim
title: Deisim
status: works
tested_version: 1.58.543
engine: Unity
xr: OpenXR
frame:
- frame.bhaptics_permission
- frame.photon_voice_audio_route
- frame.unity_text_input
device:
- device.text_input_window
adapter:
haptic_fix: 1
verified:
date: '2026-10-21'
known_good_sha256: 91bc0a28ff7ca22a877f4f920984c3a6a2c91828a2bccff0c5eb4affb4dc13ae
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 109
issue: 462
source_hint: Deisim
+2 -1
View File
@@ -12,6 +12,7 @@ overport_extra:
- patch_force_passthrough
adapter:
scene_emul: 1
scene_hide_bounds: 1
device:
- device.text_input_window
verified:
@@ -22,4 +23,4 @@ verified:
frame:
- frame.meta_permissions
- frame.unity_text_input
updated: '2026-10-15'
updated: '2026-10-17'
@@ -0,0 +1,20 @@
package: com.ORIGAMEDIGITAL.UmurangiGenerationVR
title: Umurangi Generation VR
status: issues
notes: The game freezes after taking a photo, while it saves it, which makes it hard to play.
tested_version: '1.163'
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
device:
- device.text_input_window
adapter:
haptic_fix: 1
verified:
date: '2026-10-22'
known_good_sha256: c4dfe227c3e33e611f9a4b8ee542912c0891fe600a7d32e56cbe84b0524ec8d9
app: 1.3.0
overport_cli: 1.2.5
issue: 472
source_hint: com.ORIGAMEDIGITAL.UmurangiGenerationVR.output
+4 -1
View File
@@ -6,7 +6,10 @@ engine: Unreal
xr: OpenXR
status: works
notes: Very large data set (~31 GiB). Built with disable_space_warp.
details: Reported working on Pico 4 with overport runtime 3.0.x. 83 OBB/pakchunk files (~32 GB).
details: 'Reported working on Pico 4 with overport runtime 3.0.x. 83 OBB/pakchunk files (~32 GB): besides main and
patch.0, 81 patch.pakchunk<N>-Android_ASTC.com.Sanzaru.Wrath2.obb files (~27 GB). Without them the game hangs at
engine start-up (GitHub #471); up to FramePort 1.3.0 they are only sent from a com.Sanzaru.Wrath2 folder next to
the APK, not loose next to it.'
overport_extra:
- patch_disable_space_warp
alt_overport:
@@ -0,0 +1,24 @@
package: com.TeravisionGames.OrcsMustDie
title: 'Orcs Must Die: By The Blade'
status: works
notes: Perfect at v151
tested_version: 1.0.164237
engine: Unreal
xr: OpenXR
alt_overport:
- patch_remove_unreal_force_quit
frame:
- frame.unreal_ovrp_entrypoints
- frame.hw_video_decode
adapter:
equirect_emul: 1
haptic_fix: 1
verified:
date: '2026-10-21'
known_good_sha256: 11e5d45587277a5edea8be4862c7af19aa5c38445676607c541bc1e471f473ff
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 109
issue: 453
source_hint: OrcsMustDie
@@ -0,0 +1,11 @@
package: com.TriangleFactory.Breachers
title: Breachers
status: unsupported
notes: Online-only multiplayer that needs Meta's online services, which aren't available on the Frame. The game's own
copy of Meta's platform library (libovr_custom.so) quits at start ("Failed to launch SystemActivities").
tested_version: 40.0.23
engine: Unity
xr: OpenXR
verified:
date: '2026-10-17'
issue: 357
+13 -6
View File
@@ -5,16 +5,21 @@ source_hint: Assassins Creed Nexus VR
engine: Unity
xr: OpenXR
status: works
notes: FrameBridge turns its upside-down UI panels upright (flip emulation, in place since FramePort 1.2.0). Ubisoft
login may not work.
frame.unity_text_input and device.text_input_window added from detection (not headset-verified).
notes: 'FrameBridge turns its upside-down UI panels upright (flip emulation, in place since FramePort 1.2.0). Ubisoft
login may not work. frame.unity_text_input added from detection (not headset-verified); no device.text_input_window:
its Android window took the controllers'' input (owner, 2026-10-23).
Keeps the Quest 2 headset identity for now: as a Quest 3 it switches to larger eye images after the intro, which
the Frame''s swapchain limit refused (GitHub #424). With the Vulkan panel pool (swapchain_pool) it runs as a Quest
3 (checked headless 2026-10-23); the Quest 3 identity comes back with the FramePort release that has it.'
details: Ubisoft online login may not work. Data folder holds raw assets (start0..2, .climb, bundles), not .obb
files; install to obb as-is.
overport_extra:
- patch_ac_nexus_no_appsw_90
frame:
- frame.unity_text_input
device:
frame_remove:
- device.headset_model
- device.text_input_window
verified:
date: '2026-09-28'
@@ -23,5 +28,7 @@ verified:
known_good_sha256: 89644a12bf8df956fa3d3a9a40540ba9e1fb62f63494714a05c9f05984383ac8
no_appsw_90: '2026-10-02, OVRPort 1.2.5 (owner: 90 Hz felt better than 72 Hz; same known issues)'
flip_in_place: '2026-10-14, owner in the headset: launch warnings and tutorial pop-ups upright (GitHub #138)'
updated: '2026-10-15'
min_app: 1.2.0
updated: '2026-10-23'
min_app: 1.3.0
adapter:
swapchain_pool: 1
@@ -0,0 +1,21 @@
package: com.WenklyStudio.SurvivalNation
title: Survival Nation
status: works
tested_version: 1.14.1
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
device:
- device.text_input_window
adapter:
scale: 1.8
verified:
date: '2026-10-18'
known_good_sha256: 7903dfee1c9c36d19e1c6c78a1f0ede1f0b25ce6a6065811997297e701009250
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 401
source_hint: survival nation
@@ -0,0 +1,11 @@
package: com.ZarApps.PianoVision
title: PianoVision
status: unsupported
notes: Starts, but needs camera hand tracking (Android games on the Frame only get hands built from the controllers)
and USB MIDI from a piano, which the Frame's Android container doesn't pass through.
tested_version: 3.0.8
engine: Unity
xr: OpenXR
verified:
date: '2026-10-20'
issue: 297
@@ -0,0 +1,22 @@
package: com.astrobotquest.vrhost
title: Astro VR Host
status: works
notes: Runs your own Astro Bot Rescue Mission files (the unpacked CUSA12392 folder, not the .pkg). With the Files
tab, copy the folder to Android/data/com.astrobotquest.vrhost/files/games/ in the game's storage and add Android/data/com.astrobotquest.vrhost/files/vrhost.txt
with the lines language=<your language, e.g. en-US> and refresh_rate=80. Set FoV to 100% in the game.
details: 'Tested with AstroQuest v0.23 (https://github.com/bigmak94/AstroQuest). The port caps the resolution at
1440 px per eye; vrhost.txt can''t change that. Other vrhost.txt options: https://github.com/bigmak94/AstroQuest/blob/main/README-QUEST-VR.md#installing-and-running'
tested_version: '0.23'
engine: Other
xr: OpenXR
adapter:
refresh_rate: 80.0
verified:
date: '2026-10-22'
known_good_sha256: c2e13ab155b947c0037362635bd34112c16b69b804af82b347021f2261ef5bfb
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 109
issue: 464
source_hint: AstroQuest
@@ -0,0 +1,17 @@
package: com.baywilly.crazytaxivr
title: CrazyTaxiVR
status: works
tested_version: CrazyTaxiVR-42
engine: Other
xr: OpenXR
adapter:
scale: 0.85
verified:
date: '2026-10-17'
known_good_sha256: 6801a09fec435776457dd2abd1c60d7db240be26cb846699946303aa94f53b04
app: 1.2.0
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 91
issue: 380
source_hint: CrazyTaxiVR
+3 -2
View File
@@ -16,6 +16,7 @@ frame:
- frame.hw_video_decode
- frame.unity_text_input
adapter:
fixed_resolution: 1
sync_guard: 1
surface_native: 1
fade_quad: 1
@@ -26,6 +27,6 @@ verified:
overport_cli: 1.2.3
overport_runtime: 3.4.3-23204ea
known_good_sha256: 796d1cab08f614d72c50d9702974c719c0908f5de91183cfe02d1fd5eb09551a
updated: '2026-10-15'
min_app: 1.1.0
updated: '2026-10-18'
min_app: 1.2.2
source_hint: Batman- Arkham Shadow
@@ -0,0 +1,26 @@
package: com.com2usroca.Darksword
title: Darksword
status: works
tested_version: 1.6.2.11
engine: Unreal
xr: OpenXR
alt_overport:
- patch_remove_unreal_force_quit
frame:
- frame.unreal_skip_obb_check
- frame.bhaptics_permission
- frame.unreal_ovrp_entrypoints
- frame.hw_video_decode
adapter:
haptic_fix: 1
scale: 1.5
foveation: tracked
verified:
date: '2026-10-18'
known_good_sha256: 47f9968e5fac70a5873b996a4d7b9c01d42d2f0cc1d9dc24013eb2e3b08a8a8e
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 410
source_hint: darksword
@@ -0,0 +1,24 @@
package: com.cosmorama.tabletroopers
title: Table Troopers
status: works
tested_version: 2026.40.4
engine: Unity
xr: OpenXR
frame:
- frame.gms_platform_version
- frame.photon_voice_audio_route
- frame.unity_text_input
device:
- device.text_input_window
adapter:
haptic_fix: 1
scale: 2.0
verified:
date: '2026-10-17'
known_good_sha256: b0a4b0e29855277712b580bd5507721fff137bde77b1911b34cca89c627feef1
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 391
source_hint: Troopers
+19
View File
@@ -0,0 +1,19 @@
package: com.drbeef.jkxr
title: JKXR
status: issues
notes: Tested in the early part of Jedi Outcast. Two players report stutters and freezes after 3-15 minutes of play
(under investigation in issue 441).
tested_version: 1.1.28
engine: Other
xr: OpenXR
frame:
- frame.tbxr_vendor
verified:
date: '2026-10-20'
known_good_sha256: 771e48b22d3a558ea11869aa1e9070b11908b17ab47a9e8866769bb67efc30a5
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 109
issue: 441
source_hint: QuestAPKs
+23
View File
@@ -0,0 +1,23 @@
package: com.drbeef.questzdoom
title: QuestZDoom
status: issues
notes: 'Needs a WAD: put it into QuestZDoom/wads in the game''s storage (Files tab) and set QuestZDoom/commandline.txt
to "qzdoom -iwad /sdcard/QuestZDoom/wads/<name>.wad". Slowed to a crawl after 5-10 minutes before
gl_error_clear (issue 237); not yet confirmed in the headset with it.'
details: GZDoom on OpenGL ES with Team Beef's OpenXR code. The game leaves GL_INVALID_ENUM pending every frame; the
runtime's GL check failed on it at the first swapchain and its GL interop then created about 100 GPU objects a
second that were never freed (8,000 after 75 s headless). Frames slowed down over the minutes, and in a player's
session the GPU driver crashed after 6 minutes and the Frame restarted. gl_error_clear clears the errors before
FrameBridge calls the runtime; GPU objects then stay flat (headless, 2026-10-24).
tested_version: 1.6.2
engine: Other
xr: OpenXR
frame:
- frame.tbxr_vendor
adapter:
gl_error_clear: 1
verified:
date: '2026-10-24'
issue: 237
updated: '2026-10-24'
source_hint: questzdoom-1.6.2
@@ -0,0 +1,22 @@
package: com.el.blackholepooldemo
title: Black Hole Pool
status: works
tested_version: 5.3.2
engine: Unity
xr: OpenXR
frame:
- frame.vivox_audio_route
- frame.unity_text_input
device:
- device.text_input_window
adapter:
haptic_fix: 1
verified:
date: '2026-10-17'
known_good_sha256: 17c23df3813324250ec1792d8dc0488dadf0df0a7ccbe33157d88f427889a92e
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 396
source_hint: Black Hole Pool
@@ -0,0 +1,24 @@
package: com.fasttravelgames.solero
title: Solero
status: works
tested_version: 1.00.109160
engine: Unreal
xr: OpenXR
alt_overport:
- patch_remove_unreal_force_quit
frame:
- frame.gms_platform_version
- frame.unreal_ovrp_entrypoints
- frame.hw_video_decode
adapter:
equirect_emul: 1
haptic_fix: 1
verified:
date: '2026-10-20'
known_good_sha256: 2d19ac1ed61cc12d0976155fbb6697fb87ec5d60c6601fe1598c965bc3e48377
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 109
issue: 448
source_hint: Action Hero
@@ -0,0 +1,36 @@
package: com.fgol.HungrySharkEvolution
title: Hungry Shark Evolution
status: works
notes: Phone game (2D). Tested with 14.6.0 installed from an .xapk bundle; cloud sync and Google services don't work.
tested_version: 14.6.0
engine: Unity
xr: '?'
overport_remove:
- patch_copy_libraries
- patch_copy_ovrplugin_vrapi
- patch_replace_icon_label
- patch_fix_min_android_sdk
- patch_generate_config
- patch_remove_localized_names
- patch_clean_up_frida
- patch_oculus_unity
- patch_oculus_unreal
- patch_vr_metadata
- patch_launcher_entry
- patch_remove_uses_library
- patch_fix_unreal_crash
- patch_meta_xr_audio
- patch_mark_as_debuggable
- patch_mark_allow_backup
frame:
- frame.unity_text_input
- frame.hw_video_decode
verified:
date: '2026-10-25'
known_good_sha256: d912bc914ea396f19e51d1b35777232cb0a4225a5f288870916744fcaacba9b1
app: 1.3.1.dev675
overport_cli: 1.2.5
frame_build: '20261022.6153909'
agent: 123
issue: 486
source_hint: Hungry+Shark+Evolution_14.6.0_APKPure
+24
View File
@@ -0,0 +1,24 @@
package: com.garage.drumsrock
title: Drums Rock
status: works
notes: Let's Rock!
tested_version: '1.401'
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.oculusos
device:
- device.text_input_window
adapter:
haptic_fix: 1
scale: 2.0
verified:
date: '2026-10-18'
known_good_sha256: 61d724ce51cc5bc17c7f942803922e8606fc5d60bc4ec5134f06754c5172c7eb
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 409
source_hint: drums rock
+16
View File
@@ -0,0 +1,16 @@
package: com.gevr.port
title: GoldenEye VR
status: issues
notes: No sound; otherwise works great.
tested_version: 0.5.8
engine: Other
xr: OpenXR
frame:
- frame.sdl_clipboard
verified:
date: '2026-10-18'
known_good_sha256: 5bd0d5ad71368178f8478193c215459a670d22ca6828bb155d76c5255908759b
app: 1.2.1
overport_cli: 1.2.5
issue: 412
source_hint: GoldenEye-VR-v0.5.8
+4 -2
View File
@@ -5,8 +5,10 @@ source_hint: NOPE CHALLENGE
engine: Unreal
xr: OpenXR
status: works
notes: Meta XR Audio telemetry patch + nodebug. MR "Reality Breach" mode unavailable.
details: The MR 'Reality Breach' mode needs passthrough; standard VR mode used.
notes: "Meta XR Audio telemetry patch + nodebug. MR mode: needs a scanned room."
details: The MR 'Reality Breach' mode needs passthrough and a room; standard VR mode was verified.
adapter:
scene_emul: 1
alt_overport:
- patch_remove_unreal_force_quit
frame:
+23
View File
@@ -0,0 +1,23 @@
package: com.mrf.tvb.cubism
title: cubism
status: works
notes: works and passthrough play works also
tested_version: 1.8.0
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
device:
- device.text_input_window
adapter:
haptic_fix: 1
scene_emul: 1
verified:
date: '2026-10-17'
known_good_sha256: fd1ba8eae19efe0f2a17fc146847de677263125f9ec5437cea5c632f0cd88dcf
app: 1.2.0
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 91
issue: 403
source_hint: Cubism
@@ -0,0 +1,19 @@
package: com.mrf.tvb.laser_dance
title: Laser Dance
engine: Unity
xr: OpenXR
status: works
notes: Mixed reality laser obstacle course; requires spatial data and room layout emulation (scene_emul=1). frame.meta_depth_occlusion keeps close lasers visible (its asset fixes only for the build they were made for); tested version not recorded (PR #246).
details: Mixed reality game that projects lasers across your room; needs Meta scene emulation and spatial data permission.
adapter:
controller_fix: 1
haptic_fix: 1
scene_emul: 1
passthrough_emul: 1
frame:
- frame.meta_permissions
- frame.meta_depth_occlusion
- frame.unity_scene_active_rooms
- frame.unity_text_input
min_app: 1.2.2
updated: '2026-10-18'
+25
View File
@@ -0,0 +1,25 @@
package: com.onehamsa.underdogs
title: UNDERDOGS
status: works
tested_version: 1.5.4.12573
engine: Unity
xr: OpenXR
frame:
- frame.bhaptics_permission
- frame.photon_voice_audio_route
- frame.unity_text_input
- frame.hw_video_decode
device:
- device.text_input_window
adapter:
controller_models: 1
haptic_fix: 1
verified:
date: '2026-10-23'
known_good_sha256: 0b98b5c71855341abc2ad942dbbdd920a6d362f7fee25a598b1a6ca1248fb27a
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261022.6150929'
agent: 109
issue: 474
source_hint: com.onehamsa.underdogs
+2 -1
View File
@@ -18,11 +18,12 @@ engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.pojlib_connection
device:
- device.text_input_window
lepton_env:
LEPTON_ENV_LIBGL_NOERROR: '1'
verified:
date: '2026-10-05'
updated: '2026-10-05'
updated: '2026-10-23'
source_hint: QuestCraft
@@ -0,0 +1,12 @@
package: com.rrrgames.ThiefSimVRQuest
title: Thief Simulator
status: unsupported
notes: Quits at start with the game's own "installed from unknown source" message. Lepton installs the game itself at
every start (there is no Meta store app on the Frame), so the game never sees the Meta store as its source.
tested_version: 1.1.7.3
engine: Unity
xr: OpenXR
verified:
date: '2026-10-17'
issue: 368
updated: '2026-10-17'
@@ -0,0 +1,27 @@
package: com.simpsonsHitAndRun.vr
title: Simpsons Hit and Run VR
status: works
notes: 'Needs the port''s game data: after installing, copy the "SimpsonsHitRun" folder (see the port''s GitHub
instructions) into the game''s storage with FramePort''s Files tab. In-game settings: Vehicle lights off, Enhanced
materials off, CSM shadows off (otherwise it crashes when starting a new game), Render scale 150% at 120 Hz.'
details: 'Tested with v1.2 of https://github.com/kote2345/The-Simpsons-Hit-and-Run-VR. Vehicle lights break entities
and Enhanced materials break textures. Render scale above 150% can''t keep up at 120 Hz (200% runs at about 100
fps). Optional: set the in-game VR tab''s mode to VR to make the menus more comfortable. While paused, a long
black texture can appear from the head when looking up; it goes away when the pause menu closes. Contributed in
issues 443 and 461.'
tested_version: '0.93'
engine: Other
xr: OpenXR
frame:
- frame.sdl_clipboard
adapter:
refresh_rate: 120.0
verified:
date: '2026-10-22'
known_good_sha256: e406a5da1b2f99fc3a9f95af44f458598ad52d1296a8c577bf1f8e2343738ff2
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 109
issue: 461
source_hint: SimpsonsHitRun_1.2
+22
View File
@@ -0,0 +1,22 @@
package: com.smtrandom.toytrain
title: ToyTrains
status: works
tested_version: 01.008.009
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
- frame.hw_video_decode
device:
- device.text_input_window
adapter:
haptic_fix: 1
verified:
date: '2026-10-17'
known_good_sha256: f8665ccd5ce9907164e0700c6924e78821918df550154f3b869cb9907aa50ede
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261015.6141207'
agent: 96
issue: 384
source_hint: Toy Trains
+22
View File
@@ -0,0 +1,22 @@
package: com.stalwart.barbaria
title: Barbaria
status: works
tested_version: 1.10.1.22383.158.OBERON.Quest.release
engine: Unity
xr: OpenXR
frame:
- frame.unity_text_input
device:
- device.text_input_window
adapter:
haptic_fix: 1
scale: 2.0
verified:
date: '2026-10-18'
known_good_sha256: e0cd063fc14a2bea5503bf63cf83246527b286915f05186ca5a2c42ce6e7d75a
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 418
source_hint: barbaria
@@ -0,0 +1,26 @@
package: com.team17.killerfrequency
title: KillerFrequency
status: works
tested_version: 1.0.767.38513
engine: Unity
xr: VrApi
frame:
- frame.unity_no_msaa
- frame.unity_text_input
- frame.unity_runtime_msaa_off
- frame.hw_video_decode
- frame.unity_gl_shim
device:
- device.text_input_window
adapter:
haptic_fix: 1
scale: 1.4000000000000001
verified:
date: '2026-10-18'
known_good_sha256: a11b008fcc0f5bc7aa5a3bb04d4267144d5ec60b26529a9b20e6499e12dcf079
app: 1.2.1
overport_cli: 1.2.5
frame_build: '20261007.6125817'
agent: 96
issue: 402
source_hint: killer freq
@@ -0,0 +1,23 @@
package: com.wnas.eternalstarlight
title: Eternal Starlight
status: issues
notes: Voice commands do not appear to work.
tested_version: 1.7.404
engine: Unity
xr: OpenXR
frame:
- frame.bhaptics_permission
- frame.unity_text_input
device:
- device.text_input_window
adapter:
haptic_fix: 1
verified:
date: '2026-10-24'
known_good_sha256: 37a79332a89c974971df30a38adbeafdc2466c3163348ab4215ff93014d5be12
app: 1.3.0
overport_cli: 1.2.5
frame_build: '20261022.6153909'
agent: 109
issue: 479
source_hint: Eternal Starlight
Loaded 100 of 460 files, more files were not shown because too many files have changed in this diff. Show more