@ssheleg/xr-dev 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +143 -0
- package/LICENSE +21 -0
- package/README.md +98 -0
- package/SECURITY.md +39 -0
- package/bin/xr-dev.js +186 -0
- package/package.json +56 -0
- package/plugins/xr-dev/.claude-plugin/plugin.json +37 -0
- package/plugins/xr-dev/skills/quest-lifecycle/SKILL.md +98 -0
- package/plugins/xr-dev/skills/quest-lifecycle/references/engine-paths.md +38 -0
- package/plugins/xr-dev/skills/quest-lifecycle/references/immersive-design.md +45 -0
- package/plugins/xr-dev/skills/quest-lifecycle/references/stage-map.md +60 -0
- package/plugins/xr-dev/skills/quest-native/SKILL.md +191 -0
- package/plugins/xr-dev/skills/quest-native/references/doc-map.md +90 -0
- package/plugins/xr-dev/skills/quest-native/references/frame-loop.md +92 -0
- package/plugins/xr-dev/skills/quest-native/references/manifest-and-gradle.md +111 -0
- package/plugins/xr-dev/skills/quest-native/references/mixed-reality.md +46 -0
- package/plugins/xr-dev/skills/quest-native/references/project-playbook.md +56 -0
- package/plugins/xr-dev/skills/quest-perf/SKILL.md +128 -0
- package/plugins/xr-dev/skills/quest-perf/references/capture-playbook.md +102 -0
- package/plugins/xr-dev/skills/quest-perf/references/mobile-rendering.md +56 -0
- package/plugins/xr-dev/skills/quest-perf/references/rendering-playbook.md +51 -0
- package/plugins/xr-dev/skills/quest-spatial/SKILL.md +170 -0
- package/plugins/xr-dev/skills/quest-spatial/references/budgets-and-traps.md +73 -0
- package/plugins/xr-dev/skills/quest-spatial/references/build-and-audit.md +36 -0
- package/plugins/xr-dev/skills/quest-spatial/references/docs-map.md +91 -0
- package/plugins/xr-dev/skills/quest-spatial/references/hybrid-activities.md +31 -0
- package/plugins/xr-dev/skills/quest-spatial/references/samples-map.md +60 -0
- package/plugins/xr-dev/skills/quest-store/SKILL.md +145 -0
- package/plugins/xr-dev/skills/quest-store/references/launch-and-growth.md +96 -0
- package/plugins/xr-dev/skills/quest-store/references/production-readiness.md +56 -0
- package/plugins/xr-dev/skills/quest-store/references/store-asset-production.md +48 -0
- package/plugins/xr-dev/skills/quest-store/references/vrc-checklist.md +193 -0
- package/plugins/xr-dev/skills/quest-tooling/SKILL.md +158 -0
- package/plugins/xr-dev/skills/quest-tooling/references/research-navigation.md +47 -0
- package/plugins/xr-dev/skills/quest-tooling/references/source-research.md +58 -0
- package/plugins/xr-dev/skills/quest-tooling/references/tool-matrix.md +54 -0
- package/plugins/xr-dev/skills/quest-webxr/SKILL.md +141 -0
- package/plugins/xr-dev/skills/quest-webxr/references/pwa-packaging.md +85 -0
- package/plugins/xr-dev/skills/quest-webxr/references/runtime-delivery.md +40 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quest-spatial
|
|
3
|
+
description: >-
|
|
4
|
+
Use when a Meta Quest app is built with Meta Spatial SDK — Kotlin and Android
|
|
5
|
+
rather than Unity or raw OpenXR: whether that lane is right, the toolchain it
|
|
6
|
+
demands, the ECS model, panels as real Android views, hybrid apps, the runtime
|
|
7
|
+
budgets that decide a design, the known issues that waste a day, and which
|
|
8
|
+
sample or documentation page answers a given question. Triggers - "Spatial SDK" /
|
|
9
|
+
"Спатиал SDK", "Meta Spatial SDK", "Kotlin app for Quest" / "приложение на
|
|
10
|
+
Kotlin для Quest", "spatial panels" / "панели в VR", "Spatial Editor",
|
|
11
|
+
"hybrid app" / "гибридное приложение", "glXF", "MRUK", "com.meta.spatial",
|
|
12
|
+
"how many panels can I open" / "сколько панелей выдержит", "Spatial SDK
|
|
13
|
+
samples" / "примеры Spatial SDK". NOT for native C++ OpenXR (quest-native),
|
|
14
|
+
Unity (Meta's hz-unity-* skills), WebXR (quest-webxr), profiling a build
|
|
15
|
+
(quest-perf), or Store submission (quest-store).
|
|
16
|
+
license: MIT
|
|
17
|
+
compatibility: Any agent can read this workflow. Live source checks need network; build, device, profiling and Store actions need the named installed tools and accounts. Missing capabilities use the inline fallback and leave dependent checks unverified.
|
|
18
|
+
metadata:
|
|
19
|
+
version: "0.3.0"
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Meta Spatial SDK: the Android lane onto Horizon OS
|
|
23
|
+
|
|
24
|
+
Spatial SDK lets an **Android** team ship an immersive app in Kotlin: Android
|
|
25
|
+
Studio, Gradle, Jetpack Compose, the libraries they already use — with OpenXR
|
|
26
|
+
underneath and an ECS data model on top. A panel in the scene is a real Android
|
|
27
|
+
view, not a texture someone drew to look like one.
|
|
28
|
+
|
|
29
|
+
For a whole-product roadmap or stage audit, use `quest-lifecycle`; a single technical task stays with this owner. If absent, identify the current stage, its evidence and the next prerequisite inline.
|
|
30
|
+
|
|
31
|
+
Read `references/hybrid-activities.md` when mixing panel and immersive activities: exclusive/cooperative modes, state ownership and transition tests.
|
|
32
|
+
|
|
33
|
+
## Step 0 — is this the right lane?
|
|
34
|
+
|
|
35
|
+
| The team and the app | Lane |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Android developers; panels, 2D UI, media, an app that is *also* a 2D app | **Spatial SDK** — this skill |
|
|
38
|
+
| Maximum control of the renderer, custom Vulkan, a game engine of your own | `quest-native` (C/C++ OpenXR) |
|
|
39
|
+
| Existing Unity content, a Unity team, asset-store pipeline | Meta's `hz-unity-*` skills |
|
|
40
|
+
| Ships on the web, or must run outside a headset too | `quest-webxr` |
|
|
41
|
+
| An existing 2D Android app that only needs to run on Quest | Meta's `hz-android-2d-porting` — porting, not rebuilding |
|
|
42
|
+
|
|
43
|
+
Spatial SDK is built around panels and an ECS scene. Use the runtime estimates
|
|
44
|
+
below to choose a representative workload early, not as hard API ceilings.
|
|
45
|
+
Read `references/build-and-audit.md` when implementing or auditing a project;
|
|
46
|
+
it provides the inline procedure when Meta's companion is absent.
|
|
47
|
+
|
|
48
|
+
## Step 1 — inspect the actual toolchain
|
|
49
|
+
|
|
50
|
+
Sample snapshot read on 2026-09-20 (`meta-quest/Meta-Spatial-SDK-Samples`, MIT).
|
|
51
|
+
Read the consumer wrapper/catalog first; do not upgrade an existing project
|
|
52
|
+
to these values without checking its SDK and build compatibility:
|
|
53
|
+
|
|
54
|
+
| Piece | Version |
|
|
55
|
+
|---|---|
|
|
56
|
+
| Headset | Quest 2 / 3 / 3S / Pro on Horizon OS **v69 or newer** |
|
|
57
|
+
| Android Studio | **Narwhal (2025.1.1) or newer** — required by AGP 8.11 |
|
|
58
|
+
| Gradle | **9.4.1** (wrapper) |
|
|
59
|
+
| Android Gradle Plugin | **8.11.1** |
|
|
60
|
+
| Kotlin | **2.1.0** |
|
|
61
|
+
| JDK | **17** (bundled with Android Studio; separate only for command-line builds) |
|
|
62
|
+
| Meta Spatial Editor | required by every sample **except** `MrukSample` and `PremiumMediaSample` |
|
|
63
|
+
| NDK | only for custom shaders (`MediaPlayerSample`, `PremiumMediaSample`) |
|
|
64
|
+
|
|
65
|
+
**The upgrade trap, stated by Meta:** AGP 8.5 or earlier running the Gradle 9.x
|
|
66
|
+
wrapper fails during native/CMake model sync, because that AGP calls a Gradle
|
|
67
|
+
API removed in Gradle 9. Moving AGP to 8.11.1 resolves it — the error message
|
|
68
|
+
does not point there.
|
|
69
|
+
|
|
70
|
+
Dependencies are modular; take what the app uses:
|
|
71
|
+
`com.meta.spatial:meta-spatial-sdk` (core, always), `-vr` (immersive
|
|
72
|
+
functionality, most apps), `-toolkit` (the common components and systems),
|
|
73
|
+
`-physics`, `-ovrmetrics`, and the rest listed in
|
|
74
|
+
`documentation/spatial-sdk/spatial-sdk-packages`.
|
|
75
|
+
|
|
76
|
+
## Step 2 — the budgets, before the architecture
|
|
77
|
+
|
|
78
|
+
Meta publishes workload estimates and recommendations
|
|
79
|
+
(`spatial-sdk-runtime-guidelines`, rechecked 2026-09-21). Use them in the first
|
|
80
|
+
sketch, retaining their device/content/refresh assumptions:
|
|
81
|
+
|
|
82
|
+
| Measured/recommended item | Snapshot estimate |
|
|
83
|
+
|---|---|
|
|
84
|
+
| Entity operations per tick (a read or write in a system) | **2,000** |
|
|
85
|
+
| Physics objects | **500** |
|
|
86
|
+
| 3D GLB objects in view | **100** when they cover >50% of the viewport; more only if they cover less |
|
|
87
|
+
| Scene-graph entities | **~1,000** |
|
|
88
|
+
| Panel resolution cost | each extra **480,000 pixels ≈ +1% GPU** |
|
|
89
|
+
|
|
90
|
+
The panel tables describe isolated test workloads and differ by *kind*:
|
|
91
|
+
|
|
92
|
+
| Panel type | FPS dips below 90 | FPS stays below 90 |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| Empty view | 20 | 40 |
|
|
95
|
+
| UI-only view | 15 | 40 |
|
|
96
|
+
| Image view | 15 | 40 |
|
|
97
|
+
| Web view | 5 | 30 |
|
|
98
|
+
| **Video view** | **3** | 5 |
|
|
99
|
+
| **Activity-based** | **2** | 2 |
|
|
100
|
+
| Panel with layers | 5 | 15 |
|
|
101
|
+
|
|
102
|
+
These measurements do not establish a hard three-video/two-activity limit or
|
|
103
|
+
guarantee that mixed workloads fit. Test the real panel/media/object mix in a
|
|
104
|
+
release build; consider reuse/virtualization instead of scaling panels with items.
|
|
105
|
+
|
|
106
|
+
## Step 3 — the traps that cost a day each
|
|
107
|
+
|
|
108
|
+
Full text and workarounds: `references/budgets-and-traps.md`.
|
|
109
|
+
|
|
110
|
+
- **Debug builds are much slower than release** — Meta lists it as a known
|
|
111
|
+
issue, not as a surprise. Judge performance on the **release** variant, or
|
|
112
|
+
the numbers mean nothing.
|
|
113
|
+
- **Entering immersive can kill other apps' audio.** Request
|
|
114
|
+
`AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK` unless exclusive audio is genuinely
|
|
115
|
+
required, and handle `OnAudioFocusChangeListener`.
|
|
116
|
+
- **`finish()` on an immersive activity may not bring the 2D panel back**, and
|
|
117
|
+
with panels on `enableLayer = true` it can crash inside
|
|
118
|
+
`libMetaSpatialSDK.so`. `enableLayer` is deprecated — use `layerConfig`.
|
|
119
|
+
- **`PanelRenderMode.Mesh()` still creates a compositor layer**; the workaround
|
|
120
|
+
is `panelConfig.layerConfig = null` after converting the settings.
|
|
121
|
+
- **Layers sharing one `SceneSwapchain` ignore per-layer `setClip()`** — all
|
|
122
|
+
show the last clip set.
|
|
123
|
+
|
|
124
|
+
## Step 4 — where to read
|
|
125
|
+
|
|
126
|
+
The index is `documentation/spatial-sdk/llms.txt/`, and every page has a
|
|
127
|
+
Markdown twin at `documentation/spatial-sdk/<slug>.md`. The prefix says which
|
|
128
|
+
question a page answers. Counts below are the dated source snapshot, not a live inventory:
|
|
129
|
+
|
|
130
|
+
| Prefix | Count | Holds |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `spatial-sdk-*` | 97 | the SDK itself: `-ecs`, `-component`, `-systems`, `-queries`, `-2dpanel-*` (8), `-isdk-*` (5, interaction), `-ui-*` (10, the Horizon OS UI Set), `-mruk`, `-physics`, `-animations`, `-glxf`, `-gltfs`, `-custom-shaders`, `-hot-reload`, `-known-issues`, `-runtime-guidelines` |
|
|
133
|
+
| `spatial-editor-*` | 20 | the visual editor, its CLI, asset library, compositions |
|
|
134
|
+
| `ps-*` | 43 | platform services: entitlement, IAP, leaderboards, achievements, cloud backup, attestation |
|
|
135
|
+
| `ts-*` | 24 | troubleshooting: adb, logcat, profilers, device setup |
|
|
136
|
+
| `os-*`, `po-*`, `platform-*` | 5 | compositor, CPU/GPU levels, memory, audio |
|
|
137
|
+
| `hybrid-*`, `horizon-billing-*`, `add-spatial-sdk-to-app` | 5 | hybrid apps and Google-Play-billing compatibility |
|
|
138
|
+
|
|
139
|
+
Slug tables worth keeping open: `references/docs-map.md`.
|
|
140
|
+
|
|
141
|
+
## Step 5 — the samples answer faster than the prose
|
|
142
|
+
|
|
143
|
+
`github.com/meta-quest/Meta-Spatial-SDK-Samples` (MIT). Enumerate its current
|
|
144
|
+
sample directories rather than relying on a prose count. Open the one
|
|
145
|
+
that already does what is being built — `references/samples-map.md` maps each
|
|
146
|
+
sample to the question it answers, and notes that the repository ships its own
|
|
147
|
+
`AGENTS.md`, `.mcp.json` and per-agent configuration, so an agent can be
|
|
148
|
+
pointed straight at a clone.
|
|
149
|
+
|
|
150
|
+
## Hybrid apps, in one paragraph
|
|
151
|
+
|
|
152
|
+
A hybrid app moves between 2D panel activities and immersive activities in one
|
|
153
|
+
package. Panel activities run in three contexts — **Home**, **Overlay** (the
|
|
154
|
+
Quest-button menu) and **Embedded** inside an immersive activity. Two
|
|
155
|
+
interaction models: **exclusive** (one at a time; terminate the old activity
|
|
156
|
+
*after* starting the new one) and **cooperative** (several concurrent).
|
|
157
|
+
`HybridSample` is the reference implementation.
|
|
158
|
+
|
|
159
|
+
## What this skill hands off
|
|
160
|
+
|
|
161
|
+
| Next question | Where |
|
|
162
|
+
|---|---|
|
|
163
|
+
| Write the ECS code, panels, gradle wiring | Meta's `hz-spatial-sdk` when present; otherwise this skill's build/audit procedure |
|
|
164
|
+
| It runs but drops frames | `quest-perf` |
|
|
165
|
+
| Get it onto a headset, read logs, capture | `quest-tooling` |
|
|
166
|
+
| Ship it | `quest-store` |
|
|
167
|
+
|
|
168
|
+
*Versions, budgets and known issues above were read from the samples repository
|
|
169
|
+
and `developers.meta.com` on 2026-09-20; both move — re-check with
|
|
170
|
+
`metavr docs search "spatial sdk runtime guidelines"` before quoting a number.*
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Budgets, and the issues Meta lists against itself
|
|
2
|
+
|
|
3
|
+
**Read this when** sizing a Spatial SDK design, or when something behaves
|
|
4
|
+
strangely and the cause might already be documented.
|
|
5
|
+
|
|
6
|
+
Sources, read 2026-09-20: `spatial-sdk-runtime-guidelines` (page dated
|
|
7
|
+
2025-10-06) and `spatial-sdk-known-issues` (dated 2026-04-02). Both move —
|
|
8
|
+
re-fetch before quoting a number onward.
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- CPU budgets
|
|
13
|
+
- GPU budgets
|
|
14
|
+
- Memory
|
|
15
|
+
- Known issues and their workarounds
|
|
16
|
+
|
|
17
|
+
## CPU budgets
|
|
18
|
+
|
|
19
|
+
| Item | Workload estimate at 90 FPS |
|
|
20
|
+
|---|---|
|
|
21
|
+
| EOPT — entity operations per tick (a read or write to the data model inside a system) | 2,000 |
|
|
22
|
+
| Physics objects (a simple GLB with Physics) | 500 — graphics usually binds first |
|
|
23
|
+
|
|
24
|
+
Panels, by kind. "Dips" is the count at which spawning one more drops the frame
|
|
25
|
+
rate temporarily; "stays" is where it no longer recovers:
|
|
26
|
+
|
|
27
|
+
| Panel type | FPS dips below 90 | FPS stays below 90 |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| Empty view | 20 | 40 |
|
|
30
|
+
| UI-only view | 15 | 40 |
|
|
31
|
+
| Image view | 15 | 40 |
|
|
32
|
+
| Web view | 5 | 30 |
|
|
33
|
+
| Video view | 3 | 5 |
|
|
34
|
+
| Activity-based | 2 | 2 |
|
|
35
|
+
| Panel with layers | 5 | 15 |
|
|
36
|
+
|
|
37
|
+
These are measured/recommended planning figures, not enforced API maximums.
|
|
38
|
+
Do not add isolated table capacities or assume linear mixing; measure the actual
|
|
39
|
+
panels, media, physics and scene content together.
|
|
40
|
+
|
|
41
|
+
## GPU budgets
|
|
42
|
+
|
|
43
|
+
Retain the source workload assumptions; the following figures are estimates,
|
|
44
|
+
not guaranteed capacities for arbitrary GLBs, shaders or devices.
|
|
45
|
+
|
|
46
|
+
- Up to **100 GLB objects in view** when they cover more than 50% of the
|
|
47
|
+
viewport; fewer objects if they fill more of it.
|
|
48
|
+
- Panel resolution scales roughly linearly while fill-bound: a default panel at
|
|
49
|
+
about half the screen is ~1000×750, and **every additional 480,000 pixels
|
|
50
|
+
costs about 1% of the GPU**. Production apps have reached ~25 million pixels
|
|
51
|
+
by that arithmetic.
|
|
52
|
+
|
|
53
|
+
## Memory
|
|
54
|
+
|
|
55
|
+
About **1,000 entities in the scene graph**, provided the CPU and GPU limits
|
|
56
|
+
above are respected.
|
|
57
|
+
|
|
58
|
+
## Known issues and their workarounds
|
|
59
|
+
|
|
60
|
+
| Issue | What happens | Workaround |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| **Debug-build performance** | debug variants run markedly slower than release | profile and judge UX on the **release** variant (Build Variants → release) |
|
|
63
|
+
| **Audio focus** | entering immersive stops or de-spatialises other apps' audio; it may not resume | request `AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK` unless exclusive audio is required; implement `AudioManager.OnAudioFocusChangeListener`; test with music playing |
|
|
64
|
+
| **2D panel does not return** | `finish()` on an immersive activity can leave the panel activity gone; with `enableLayer = true` panels it can crash (`SIGSEGV`) in `libMetaSpatialSDK.so` | `enableLayer` is deprecated — configure `layerConfig: LayerConfig?`; follow the page's transition sequence rather than calling `finish()` blind |
|
|
65
|
+
| **Mesh render mode still makes a layer** | `PanelRenderMode.Mesh()` creates a compositor layer as well, costing GPU memory | after `panelSettings.toPanelConfigOptions()`, set `panelConfig.layerConfig = null` |
|
|
66
|
+
| **Shared swapchain clipping** | several `SceneQuadLayer`s on one `SceneSwapchain` all show the last `setClip()` region | Meta suggests pinning SDK 0.7.2 where this matters; otherwise give each layer its own swapchain |
|
|
67
|
+
|
|
68
|
+
## The toolchain failure that reads as something else
|
|
69
|
+
|
|
70
|
+
AGP **8.5 or earlier** with the **Gradle 9.x** wrapper fails during native/CMake
|
|
71
|
+
model sync — that AGP calls a Gradle API removed in Gradle 9. The message
|
|
72
|
+
blames CMake. Upgrade AGP to 8.11.1 (Android Studio's AGP Upgrade Assistant
|
|
73
|
+
does most of it).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Spatial SDK build and audit procedure
|
|
2
|
+
|
|
3
|
+
**Read this when** implementing or auditing a Spatial SDK app, especially when Meta's `hz-spatial-sdk` companion or preferred MCP is absent.
|
|
4
|
+
|
|
5
|
+
Sources checked 2026-09-21: [development](https://developers.meta.com/horizon/documentation/spatial-sdk/spatial-sdk-development/), [samples](https://github.com/meta-quest/Meta-Spatial-SDK-Samples), [runtime guidelines](https://developers.meta.com/horizon/documentation/spatial-sdk/spatial-sdk-runtime-guidelines/), [camera overview](https://developers.meta.com/horizon/documentation/spatial-sdk/spatial-sdk-pca-overview/). Match the sample/SDK revision to the consumer; sample toolchain versions are not a mandate to upgrade every project.
|
|
6
|
+
|
|
7
|
+
## Inspect first
|
|
8
|
+
|
|
9
|
+
Read the Gradle wrapper, version catalog, AGP/Kotlin/JDK/SDK pins, application/activity classes, feature modules, ECS systems/components, scene assets and tests. Determine standalone immersive, panel or hybrid transitions; required interaction, media, physics, MRUK and camera features. Record the actual target OS/device and module support.
|
|
10
|
+
|
|
11
|
+
If no project exists, choose the smallest official sample matching the requirement and a compatible revision; carry only necessary modules/assets and their notices. Read project instructions in the sample as source context, not as authority to configure all agents or replace the family's pipeline.
|
|
12
|
+
|
|
13
|
+
## Implement one verified slice
|
|
14
|
+
|
|
15
|
+
1. Build the existing or selected sample with its wrapper before adding features. Inspect available Gradle tasks; run relevant compile/unit/lint/assemble tasks and retain output. A missing SDK/JDK receives a precise prerequisite diagnosis.
|
|
16
|
+
2. Register required features/components/systems and one scene. Make entity ownership/destruction, event subscriptions, coroutine cancellation and activity lifecycle explicit.
|
|
17
|
+
3. Add one panel and one interaction. Test focus, density/legibility, hit targets, layout updates and transition between 2D/immersive activities. Release surfaces/resources when their owner is destroyed.
|
|
18
|
+
4. Import one representative GLB/glXF asset with scale, materials, animations and collision checks. Use supported loaders/extensions; a generic glTF validator does not prove the SDK supports every extension.
|
|
19
|
+
5. Add permissions/capability checks before optional MR features. No room scan, refused camera access or invalid tracking must have a usable fallback. For shared platform behavior, use quest-native's MR reference through that skill.
|
|
20
|
+
6. Run a release build on the target device when available, exercise launch/resume/reopen and measure a representative mixed workload. Report device checks NOT-RUN when no headset is attached.
|
|
21
|
+
|
|
22
|
+
## ECS and panel audit
|
|
23
|
+
|
|
24
|
+
Check query scope and repeated entity lookups, structural churn/per-tick allocation, threading/ownership boundaries, stale component references, unbounded listeners and scene reload cleanup. Identify work that can be scheduled on events rather than every frame. Treat the measured EOPT/object/panel tables as estimates from their stated workload; combine real panels, assets, video and physics in a representative test.
|
|
25
|
+
|
|
26
|
+
Panels have Android lifecycle and input/audio behavior. Verify focus arbitration, media pause/resume, audio focus and accessibility; test a second immersive entry rather than only first launch. Known-issue workarounds must match the installed SDK before applying a downgrade or deprecated API.
|
|
27
|
+
|
|
28
|
+
## Advanced feature plan
|
|
29
|
+
|
|
30
|
+
For MRUK, anchors, camera/CV, custom shaders, media/DRM, animation, physics or shared sessions, name an official sample, supported API/version, failure case and verification scene. Validate only the modules required by the brief. Preserve platform capability checks separately from runtime permission grants and account restrictions.
|
|
31
|
+
|
|
32
|
+
Enumerate actual sample directories and build targets rather than trusting a README's prose count. Use the current SDK index to discover new modules; retrieve the relevant page and versioned API signature before implementation. A navigation skill should close a small task even when its accelerator is missing.
|
|
33
|
+
|
|
34
|
+
## Audit result
|
|
35
|
+
|
|
36
|
+
Return source-addressed findings with impact, reproduction and bounded fix; include target/dependency inventory, commands and unavailable checks. Build success, structural asset validity, visual correctness and headset performance are separate results. Hand performance to quest-perf and release evidence to quest-store.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Navigating 197 Spatial SDK pages
|
|
2
|
+
|
|
3
|
+
**Read this when** a Spatial SDK question needs the authoritative page and
|
|
4
|
+
guessing the slug would waste a round trip.
|
|
5
|
+
|
|
6
|
+
Index (plain Markdown, no login):
|
|
7
|
+
`https://developers.meta.com/horizon/llmstxt/documentation/spatial-sdk/llms.txt/`
|
|
8
|
+
Any page: same path with `<slug>.md`. Counted 2026-09-20: 197 pages.
|
|
9
|
+
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- Core model
|
|
13
|
+
- Panels
|
|
14
|
+
- Interaction, UI and input
|
|
15
|
+
- Scene, assets and rendering
|
|
16
|
+
- The room, tracking and media
|
|
17
|
+
- Tooling and debugging
|
|
18
|
+
- Spatial Editor
|
|
19
|
+
- Platform services, billing and the Store
|
|
20
|
+
- Performance and limits
|
|
21
|
+
|
|
22
|
+
## Core model
|
|
23
|
+
|
|
24
|
+
| Question | Slug |
|
|
25
|
+
|---|---|
|
|
26
|
+
| What is the architecture | `spatial-sdk-architecture`, `spatial-sdk-explainer` |
|
|
27
|
+
| The ECS data model | `spatial-sdk-ecs`, `spatial-sdk-component`, `spatial-sdk-builtin-components`, `spatial-sdk-systems`, `spatial-sdk-writing-new-system` |
|
|
28
|
+
| Querying the data model | `spatial-sdk-queries`, `spatial-sdk-changedsince-query`, `spatial-sdk-childrenof-query`, `spatial-sdk-filters`, `spatial-sdk-attributes` |
|
|
29
|
+
| Activity lifecycle and the scene | `spatial-sdk-activity-lifecycle`, `spatial-sdk-scene`, `spatial-sdk-understand-scenes` |
|
|
30
|
+
| Reusable feature modules | `spatial-sdk-spatialfeature` |
|
|
31
|
+
| Events | `spatial-sdk-events` |
|
|
32
|
+
|
|
33
|
+
## Panels
|
|
34
|
+
|
|
35
|
+
`spatial-sdk-2dpanel` and its seven siblings: `-registration`, `-spawn`,
|
|
36
|
+
`-communication`, `-compose` (Jetpack Compose inside a panel), `-resolution`,
|
|
37
|
+
`-layers` (layer versus mesh rendering), `-drm`. Plus `spatial-sdk-panel-tutorial`
|
|
38
|
+
and `spatial-sdk-resize-panel`.
|
|
39
|
+
|
|
40
|
+
## Interaction, UI and input
|
|
41
|
+
|
|
42
|
+
`spatial-sdk-isdk-overview` and four more (`-grabbable`, `-panels`,
|
|
43
|
+
`-listen-to-input-events`, `-supporting-systems`); `spatial-sdk-inputs-controllers`;
|
|
44
|
+
the Horizon OS UI Set as ten component pages (`spatial-sdk-ui-button`, `-card`,
|
|
45
|
+
`-control`, `-dialog`, `-dropdown`, `-input`, …).
|
|
46
|
+
|
|
47
|
+
## Scene, assets and rendering
|
|
48
|
+
|
|
49
|
+
`spatial-sdk-3dobjects`, `spatial-sdk-gltfs`, `spatial-sdk-glxf` (the scene
|
|
50
|
+
composition format), `spatial-sdk-animations`, `spatial-sdk-physics`,
|
|
51
|
+
`spatial-sdk-custom-shaders`, `spatial-sdk-custom-components`,
|
|
52
|
+
`spatial-sdk-blend-modes`, `spatial-sdk-sorting`, `spatial-sdk-environment`,
|
|
53
|
+
`spatial-sdk-splats` (Gaussian splats), `spatial-sdk-passthrough`.
|
|
54
|
+
|
|
55
|
+
## The room, tracking and media
|
|
56
|
+
|
|
57
|
+
`spatial-sdk-mruk` and `spatial-sdk-mruk-hifi-scene` (Mixed Reality Utility
|
|
58
|
+
Kit), `spatial-sdk-scanner-overview` + `-api`, `-llama`, `-ot` (object
|
|
59
|
+
tracking), `spatial-sdk-pca-overview` + `-kotlin-api` (passthrough camera
|
|
60
|
+
access), `spatial-sdk-media-playback`, `spatial-sdk-audio`,
|
|
61
|
+
`spatial-sdk-spatial-audio`.
|
|
62
|
+
|
|
63
|
+
## Tooling and debugging
|
|
64
|
+
|
|
65
|
+
`spatial-sdk-development`, `spatial-sdk-hot-reload`, `spatial-sdk-android-studio-plugin`,
|
|
66
|
+
`spatial-sdk-validate-xml`, `spatial-sdk-tooling-dmi`,
|
|
67
|
+
`spatial-sdk-tooling-castinputforward`, `spatial-sdk-ovrmetrics`,
|
|
68
|
+
`spatial-sdk-known-issues`, plus 24 `ts-*` pages shared with the rest of the
|
|
69
|
+
platform (`ts-adb`, logcat, profilers, device setup).
|
|
70
|
+
|
|
71
|
+
## Spatial Editor
|
|
72
|
+
|
|
73
|
+
20 `spatial-editor-*` pages: `-download-setup`, `-overview`, `-components`,
|
|
74
|
+
`-compositions`, `-asset-library`, `-assetlib`, `-create-app-content` (the
|
|
75
|
+
codelab), `-command-line-interface`, `-ai-scene-manipulation`, `-bug-report`.
|
|
76
|
+
|
|
77
|
+
## Platform services, billing and the Store
|
|
78
|
+
|
|
79
|
+
43 `ps-*` pages — `ps-get-started`, `ps-entitlement-check`, `ps-iap` (+ `-s2s`,
|
|
80
|
+
`-test`), `ps-leaderboards`, `ps-achievements`, `ps-challenges`,
|
|
81
|
+
`ps-cloud-backup`, `ps-attestation-api`, `ps-deep-linking`, `ps-language-packs`,
|
|
82
|
+
`ps-presence`, `ps-ownership`. Google-Play-billing compatibility has three of
|
|
83
|
+
its own: `horizon-billing-compatibility-sdk`,
|
|
84
|
+
`horizon-billing-implement-google-play-billing-interface`,
|
|
85
|
+
`horizon-billing-known-limitations`. Submission itself is `quest-store`.
|
|
86
|
+
|
|
87
|
+
## Performance and limits
|
|
88
|
+
|
|
89
|
+
`spatial-sdk-runtime-guidelines` (the budgets), `spatial-sdk-design-tips`,
|
|
90
|
+
`os-compositor`, `os-compositor-layers`, `os-cpu-gpu-levels`, `po-memory-ram`,
|
|
91
|
+
`platform-audio`. Reading a capture is `quest-perf`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Hybrid panel and immersive activities
|
|
2
|
+
|
|
3
|
+
**Read this when**: one app must move between 2D panels and immersion or keep both active.
|
|
4
|
+
Primary source: [hybrid apps](https://developers.meta.com/horizon/documentation/spatial-sdk/hybrid-apps-overview/),
|
|
5
|
+
read 2026-09-21. Use its activity/intent details with the actual SDK; its example
|
|
6
|
+
OS target is not a mandate to downgrade or freeze a current application.
|
|
7
|
+
|
|
8
|
+
1. Model entry from Home, launch over another app, return to Home and reopening
|
|
9
|
+
after process death. Decide **exclusive** (one active experience) versus
|
|
10
|
+
**cooperative** (panel and immersive visible/interactable together).
|
|
11
|
+
2. Exclusive transitions may finish the prior activity after the next starts.
|
|
12
|
+
Do not apply that pattern to a cooperative overlay: it destroys the panel
|
|
13
|
+
the user asked to keep. Scope each cleanup to the transition that owns it.
|
|
14
|
+
3. Inspect the final manifest and activity graph. The source distinguishes
|
|
15
|
+
`com.oculus.intent.category.2D` / `.VR`, a standard Android launcher fallback,
|
|
16
|
+
`VR_HOME_LAUNCHER` and `OVERLAY_LAUNCHER`. Verify OS/SDK support and exact
|
|
17
|
+
intent/PendingIntent contract in current docs before implementing.
|
|
18
|
+
4. Own persistent domain state outside Activity lifetime. Save serializable
|
|
19
|
+
content/selection/work progress, not surfaces or XR handles. Use explicit
|
|
20
|
+
cross-activity state/intent contracts, reject stale messages and prevent
|
|
21
|
+
concurrent writes. Reconstruct runtime resources on resume.
|
|
22
|
+
5. Budget active panels and immersive work together. Suspend only work no longer
|
|
23
|
+
visible/needed; assign camera/audio/input ownership deliberately. Distinguish
|
|
24
|
+
Android activity lifecycle from OpenXR session/focus lifecycle.
|
|
25
|
+
6. Test Home/default launch, cooperative overlay, exclusive return, repeated
|
|
26
|
+
transitions, back/menu, headset sleep, tracking/permission loss, activity
|
|
27
|
+
recreation, process kill and task restoration. Check unsaved-work recovery,
|
|
28
|
+
no duplicate sessions/audio, focus routing and no stranded blank view.
|
|
29
|
+
|
|
30
|
+
No headset: implement state-transition tests and inspect merged manifest, but mark
|
|
31
|
+
OS presentation, compositor/input behavior and combined performance NOT_RUN.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# The 15 official samples, mapped to the question each answers
|
|
2
|
+
|
|
3
|
+
**Read this when** starting anything in Spatial SDK: the sample that already
|
|
4
|
+
does it is faster to read than the prose about it, and it compiles.
|
|
5
|
+
|
|
6
|
+
`github.com/meta-quest/Meta-Spatial-SDK-Samples` — MIT, 276 stars, read
|
|
7
|
+
2026-09-20. Each directory is a standalone Gradle project.
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- The map
|
|
12
|
+
- What a clone brings with it
|
|
13
|
+
- Running one
|
|
14
|
+
|
|
15
|
+
## The map
|
|
16
|
+
|
|
17
|
+
| I need to… | Sample |
|
|
18
|
+
|---|---|
|
|
19
|
+
| start from the smallest working app | `StarterSample` (the Getting Started / hello-world project) |
|
|
20
|
+
| move between a 2D panel app and an immersive one | `HybridSample` |
|
|
21
|
+
| define my own component shared across app instances | `CustomComponentsSample` (+ `CodelabStarters/CustomComponentsStarter`, the same app with the logic removed for the codelab) |
|
|
22
|
+
| play animation clips, drive animation from code | `AnimationsSample` |
|
|
23
|
+
| put 3D objects in a scene and tune them in Spatial Editor | `Object3DSample` |
|
|
24
|
+
| do the same with Interaction SDK grabbing | `Object3DSampleIsdk` |
|
|
25
|
+
| add physics and tune it in the editor | `PhysicsSample` |
|
|
26
|
+
| build an immersive video player | `MediaPlayerSample` (custom shaders — needs the NDK) |
|
|
27
|
+
| stream DRM-protected or 180° video, reflect panels into the room | `PremiumMediaSample` (needs no Spatial Editor) |
|
|
28
|
+
| play video with spatialised audio | `SpatialVideoSample` |
|
|
29
|
+
| react to the user's real room | `MixedRealitySample`, `MrukSample` (MRUK; needs no Spatial Editor) |
|
|
30
|
+
| read body-tracking skeleton joints | `BodyTrackingSample` |
|
|
31
|
+
| use the Horizon OS UI Set for consistent UI | `UISetSample` |
|
|
32
|
+
| render Gaussian splats | `SplatSample` |
|
|
33
|
+
| package reusable `SpatialFeature` library modules | `FeatureDevSample` |
|
|
34
|
+
| see complete apps rather than features | `Showcases/` |
|
|
35
|
+
|
|
36
|
+
## What a clone brings with it
|
|
37
|
+
|
|
38
|
+
The repository is **agent-configured**: `AGENTS.md` at the root and one per
|
|
39
|
+
sample, plus `.claude/`, `.cursor/`, `.opencode/`, `.roo/`, `.clinerules`,
|
|
40
|
+
`.windsurfrules`, `GEMINI.md` and `.aider.conf.yml`. Its root `AGENTS.md`
|
|
41
|
+
points at the same `llms.txt` index this pack uses.
|
|
42
|
+
|
|
43
|
+
**One trap in that convenience:** the repo's `.mcp.json` declares an MCP server
|
|
44
|
+
`hzdb` running `npx -y @meta-quest/hzdb mcp server` — the CLI's older name. On
|
|
45
|
+
a machine that already has `metavr` wired, opening a clone gives an agent **two
|
|
46
|
+
registrations of the same tool**, with the older package behind one of them.
|
|
47
|
+
Decide which one the session should use; do not run both (`quest-tooling` has
|
|
48
|
+
the rule).
|
|
49
|
+
|
|
50
|
+
## Running one
|
|
51
|
+
|
|
52
|
+
1. Clone, open the **specific sample directory** in Android Studio — not the
|
|
53
|
+
repository root.
|
|
54
|
+
2. Plug in the headset (Developer Mode on), press Run.
|
|
55
|
+
3. Every sample except `MrukSample` and `PremiumMediaSample` needs **Meta
|
|
56
|
+
Spatial Editor** installed.
|
|
57
|
+
4. `MediaPlayerSample` and `PremiumMediaSample` need the NDK, pinned in
|
|
58
|
+
`app/build.gradle.kts` (`ndkVersion`).
|
|
59
|
+
5. The samples ship Meta's OVRMetrics integration — enable it to read frame
|
|
60
|
+
numbers in the headset rather than guessing.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quest-store
|
|
3
|
+
description: >-
|
|
4
|
+
Use when preparing Meta Quest testing, Meta Horizon Store submission, monetization,
|
|
5
|
+
launch assets or post-launch commercial operation. Covers release channels,
|
|
6
|
+
applicable VRCs, signing/manifest, account and data tasks, purchases/subscriptions,
|
|
7
|
+
pre-launch listings, capture provenance and analytics. Triggers - "publish to
|
|
8
|
+
the store" / "выложить в стор", "Horizon Store", "App Lab", "release channel" /
|
|
9
|
+
"релизный канал", "VRC", "app review" / "ревью приложения", "Data Use Checkup",
|
|
10
|
+
"DUC", "store assets" / "ассеты для стора", "test user" / "тестовый аккаунт",
|
|
11
|
+
"Quest monetization" / "монетизация Quest", "pre-order" / "предзаказ".
|
|
12
|
+
NOT for a whole-product roadmap (quest-lifecycle), app implementation,
|
|
13
|
+
profiling (quest-perf), machine setup (quest-tooling), or PWA packaging (quest-webxr).
|
|
14
|
+
license: MIT
|
|
15
|
+
compatibility: Any agent can read this workflow. Live source checks need network; build, device, profiling and Store actions need the named installed tools and accounts. Missing capabilities use the inline fallback and leave dependent checks unverified.
|
|
16
|
+
metadata:
|
|
17
|
+
version: "0.3.0"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Shipping to the Meta Horizon Store
|
|
21
|
+
|
|
22
|
+
Two facts decide most of the schedule. **Every upload — alpha included — must
|
|
23
|
+
meet the full release packaging requirements.** And **the Production channel is
|
|
24
|
+
the only one that triggers review**; a build sitting there does nothing until
|
|
25
|
+
the submission info is filled in and "Submit for Review" is clicked.
|
|
26
|
+
|
|
27
|
+
Read `references/production-readiness.md` when planning a release or auditing
|
|
28
|
+
product readiness: artifact identity, manifest conflicts, accounts, purchases,
|
|
29
|
+
saves, social features, privacy, review evidence and recovery after release.
|
|
30
|
+
|
|
31
|
+
For a whole-product roadmap or stage audit, use `quest-lifecycle`; a single technical task stays with this owner. If absent, identify the current stage, its evidence and the next prerequisite inline.
|
|
32
|
+
|
|
33
|
+
Read `references/launch-and-growth.md` for commercial setup, pre-launch decisions, monetization tests, marketing and post-launch operation. Read `references/store-asset-production.md` before capture, listing production or reviewing generated assets.
|
|
34
|
+
|
|
35
|
+
## The four channels
|
|
36
|
+
|
|
37
|
+
| Channel | Audience | Review |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| ALPHA | invite-only, starts **empty — not even you** | none |
|
|
40
|
+
| BETA | invite-only | none |
|
|
41
|
+
| RC | invite-only | none |
|
|
42
|
+
| Production (Store) | everyone entitled | **technical + content review** |
|
|
43
|
+
|
|
44
|
+
- Invite by email, alias or URL, or mark a channel public so users subscribe
|
|
45
|
+
themselves. Default limit **200 users per channel**, up to 2,500 on request.
|
|
46
|
+
- Testers see the build in their Library and under **My Preview Apps**.
|
|
47
|
+
- Copying an approved build into Production updates every entitled user.
|
|
48
|
+
- Distributing to testers in South Korea has its own GRAC rating requirement.
|
|
49
|
+
|
|
50
|
+
The useful consequence: a first playable can reach real testers with **no Meta
|
|
51
|
+
review at all** — as long as it is packaged like a release build.
|
|
52
|
+
|
|
53
|
+
## Review, in the order it happens
|
|
54
|
+
|
|
55
|
+
1. **Technical review** — the Virtual Reality Checks (VRC). A failure comes back
|
|
56
|
+
with review findings; do not assume it enumerates every remaining defect.
|
|
57
|
+
2. **Content review** — completeness, polish and value, after the technical pass.
|
|
58
|
+
3. **Approval** — then a release date can be set, immediately or scheduled.
|
|
59
|
+
|
|
60
|
+
Plan **at least two weeks** before a target launch date. In saturated categories
|
|
61
|
+
review may stop at the first violation found, so self-checking is cheaper than
|
|
62
|
+
a round trip. Apps using platform features must file a **Data Use Checkup**
|
|
63
|
+
before submission; without a current DUC, platform features stay limited to
|
|
64
|
+
test users.
|
|
65
|
+
|
|
66
|
+
## What gets checked, grouped by what it costs to fix late
|
|
67
|
+
|
|
68
|
+
| Group | The ones that fail builds |
|
|
69
|
+
|---|---|
|
|
70
|
+
| Packaging | manifest conforms to the **release** spec (`.1`), **v2 signature** (`.2`), no unsupported Android features (`.3`), supported SDK/engine (`.4`), APK < 1 GB and OBB < 4 GB (`.5`), **64-bit only** (`.6`) |
|
|
71
|
+
| Performance | runs at the declared refresh rate (`.1`), head-tracked graphics or a VR loading indicator **within 4 s** (`.3`), ≥85% render scaling recommended (`.4`) |
|
|
72
|
+
| Functional | no crashes or freezes, pauses when the OS asks, never strands the user, no data loss, positional tracking honoured, works for **multiple entitled users**, passthrough loading screen when launched from MR Home |
|
|
73
|
+
| Input | **focus-aware** — keep rendering, hide hands, ignore input (`.4`); hand-tracking apps must respect the reserved system gesture |
|
|
74
|
+
| Security | minimum permissions and no unsupported ones (`.2`); an entitlement check within 10 s is a **recommendation**, not a requirement (`.1`) |
|
|
75
|
+
| Assets | logo on transparent background, no text in the top or bottom 20% of cover art, screenshots representative and free of other platforms' hardware, trailer **≤ 2 minutes**, text ≥ 24 pt |
|
|
76
|
+
|
|
77
|
+
The full tables, with which apply to immersive versus 2D apps, are in
|
|
78
|
+
`references/vrc-checklist.md`. Fetch the live list before a submission —
|
|
79
|
+
requirements retire and appear (`VRC.Quest.Performance.2` is RETIRED today).
|
|
80
|
+
|
|
81
|
+
## The release manifest is not the development manifest
|
|
82
|
+
|
|
83
|
+
Development requirements and submission requirements are two documents, and
|
|
84
|
+
only the second is enforced at review. Before uploading anything:
|
|
85
|
+
|
|
86
|
+
- `android:debuggable` false or absent — a release build, not a debug one.
|
|
87
|
+
- `installLocation="auto"`, unique `android:label`.
|
|
88
|
+
- Immersive: `android.hardware.vr.headtracking` `required="true"`; a 2D panel
|
|
89
|
+
app omits it or sets `required="false"`.
|
|
90
|
+
- OpenXR apps: the current Meta release page lists
|
|
91
|
+
`com.oculus.intent.category.VR` alongside MAIN/LAUNCHER; inspect the merged
|
|
92
|
+
APK and retain any additional SDK/runtime-required categories deliberately.
|
|
93
|
+
- Release launch activity: `android:excludeFromRecents="true"`.
|
|
94
|
+
- SDK levels: **an app created since 1 March 2026 must target 34**; recommended
|
|
95
|
+
min 32 / target 34 / compile ≥ target for in-lifecycle devices.
|
|
96
|
+
- Sign with **APK signature scheme v2**; keep the keystore out of the repository.
|
|
97
|
+
|
|
98
|
+
`quest-native` carries the same contract from the build side.
|
|
99
|
+
|
|
100
|
+
## Uploading
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
metavr store dist apps # app ids in the organization
|
|
104
|
+
metavr store dist channels --app-id <ID> # channels and their latest builds
|
|
105
|
+
metavr store dist upload --app-id <ID> --channel ALPHA --apk build.apk \
|
|
106
|
+
--notes "what changed" # a DRAFT upload unless --publish
|
|
107
|
+
metavr store dist copy-build ... # promote between channels
|
|
108
|
+
metavr store test-user ... # FRL test accounts for the org
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`LIVE` is the store channel in that flag. The Oculus Platform Command Line
|
|
112
|
+
Utility (`metavr tools install platform-utils`) does the same job with
|
|
113
|
+
delta-patching for large packages, and MQDH is a GUI wrapper over it. Upload
|
|
114
|
+
validation reports packaging problems **after** the upload, so budget a
|
|
115
|
+
correction round.
|
|
116
|
+
|
|
117
|
+
**`versionCode` must increase with every build** or the upload is refused; the
|
|
118
|
+
version the testers see is `versionName`.
|
|
119
|
+
|
|
120
|
+
## A checklist that fits the two gates
|
|
121
|
+
|
|
122
|
+
Before the first ALPHA upload: release manifest, v2 signing, 64-bit, size
|
|
123
|
+
limits, `versionCode` bumped, it launches on a real headset from a cold boot.
|
|
124
|
+
|
|
125
|
+
Before Production: everything above plus the VRC self-pass, DUC filed if
|
|
126
|
+
platform features are used, store assets to spec, screenshots captured **in the
|
|
127
|
+
headset**, trailer under two minutes, age rating questionnaire complete, and the
|
|
128
|
+
privacy policy URL live.
|
|
129
|
+
|
|
130
|
+
## Gotchas that cost a submission round
|
|
131
|
+
|
|
132
|
+
- **"It is only an alpha" is not an exemption** from packaging requirements.
|
|
133
|
+
- **Channels start with nobody in them**, including the developer — an empty
|
|
134
|
+
channel looks like a broken upload.
|
|
135
|
+
- **A Production build is invisible until submitted**; no review starts on
|
|
136
|
+
upload alone.
|
|
137
|
+
- **2D panel apps are a different rule set**: a VRC subset, and a list of
|
|
138
|
+
permissions (precise location, telephony, …) that trigger automatic rejection.
|
|
139
|
+
- **Store assets have their own checks.** Verify current safe areas and
|
|
140
|
+
representative captures; do not infer acceptance from a successful APK upload.
|
|
141
|
+
|
|
142
|
+
*Channel behaviour, review stages, the VRC groups and the SDK-level rule were
|
|
143
|
+
read from developers.meta.com (`resources/publish-release-channels`,
|
|
144
|
+
`publish-app-review`, `publish-quest-req`, `publish-mobile-manifest`) on
|
|
145
|
+
2026-09-20. Re-check before a submission: these pages carry their own dates.*
|