vrOS v0.16.4 Patch Notes
Highlights
Reverted the v0.16.1 – v0.16.3 attempts to fix smooth-overlay-dragging fallout and replaced them with a proper set of fixes. The compositor late-latch path introduced in v0.16.0 turned out to leak stale poses into the playspace drag/rotate code paths, drift push/pull along the wrong axis, and let keyboard recenter/no-op-grab events corrupt saved placement memory. This release addresses each of those regressions at the source — playspace pose sampling now time-aligns with scene-app frame reads, push/pull moves along the perceptual forward again, and keyboard placement memory only updates on real, intentional changes.
Bug Fixes
- Fixed VR playspace drag and rotate jitter on high-refresh HMDs (120 / 144 / 240 Hz). Three separate aliasing problems were stacking: the playspace commit gate was capped at 11 ms while the poll loop ran at the headset refresh rate, the cached controller pose only advanced when the compositor rendered a new frame (so consecutive polls saw the same pose followed by a doubled delta), and the drag-cadence protection that pauses GPU work during grabs only ran for overlay grabs, not playspace. The commit gate now follows poll cadence, playspace pose sampling reads predict-to-now from the per-poll pose array, and the cadence protection now also gates on active playspace drag/rotate.
- Eliminated the residual stepping seen in VRChat-style mirrors during fast playspace drags. Playspace controller pose sampling now uses GetPoseActionDataForNextFrame, which auto-predicts to the moment the next frame's photons emit — the same instant a scene app reads its poses on its next WaitGetPoses — closing the 11–22 ms temporal offset that was visible in mirrors but masked in the headset view by compositor reprojection.
- Fixed vertical drift while pushing or pulling a held overlay with the joystick. Push/pull was mutating both the aim-frame and the raw-frame controller offsets by the same delta, which (after the v0.16.0 late-latch change) moved the overlay along the controller body axis — tilted roughly 40° up under natural grip — instead of along the perceptual forward direction. Push/pull now only mutates the aim-frame offset and re-derives the raw-frame offset from a shared aim-pitch constant.
- Fixed the keyboard's saved placement getting overwritten with strange orientations. Manually toggling the keyboard while looking at the floor or with a head tilt no longer copies the full HMD pitch and roll into memory — the manual-toggle recenter is now yaw-only — and a brief accidental grab + release that doesn't actually move the keyboard no longer overwrites the previous intentional placement. Manual-toggle hide and grab-release now compare against a captured baseline and skip persisting when nothing changed (1 mm position / 1 mm width / 0.001 rad rotation epsilon).
- Fixed duplicate badge clusters on your own messages in Twitch shared-chat sessions. The source-badge enrichment loop now lives inside the existing cross-channel guard, so own-channel echoes no longer produce both a normal badges set and a source:-prefixed copy of the same badges. Cross-channel shared-chat rendering is unaffected.
Improvements
- Internal: extracted the new GetPoseActionDataForNextFrame call into its own pose_action_for_next_frame helper so any pose action handle can use it, not just the playspace path. Removes two levels of nesting from the raw-pose getter; behavior is unchanged.
