Welcome to the Developer Update for September 24, 2026.
Today’s featured world is uhh… our artist forgot to make a thumbnail, Flare had to make one.
(They think it’s “painfully bad,” but personally I think it owns.)
Announcements
Spookality
The Spookality Jam is ongoing!
We announced it last time, but we just want to keep it fresh in your mind while it’s going on. Here are the important dates:
- Submissions Open: Sept 3 - Oct 1
- Judging Period: Oct 2 - Oct 15
- Showcase Period: Oct 16 - Nov 2
Also, once again, in the spirit of the jam, we’ve decided to feature ALL eligible entries in the Home/Hub world for Spookality, even if they didn’t win a prize.
Steam Frame… Today!
Well, last week. But you get it! Well, maybe you got it. I DIDN’T. GABE.
Regardless, we’ve had a lot of questions about our support for the Frame!
You can find most of your questions answered here!
But to knock out the two biggest ones:
Yes, the standalone version of VRChat is accessible on the Steam Frame.
No, you cannot run “PC” VRChat on the Steam Frame.
The Frame is an impressive device! It runs the standalone (“Android”) version of VRChat very, very well. We also think it provides a fantastic experience for PC users who like to wirelessly stream VRChat to their headset. Seriously. Steam Link with that fancy dongle is magic.
2026.3.3 Beta!
Yup! We’re still in beta. You can read about our progress in the notes here!
We’ve been doing a lot to incorporate your feedback into the new HUD + keyboard. Yes, we brought the old mic icon back.
In the last beta update, we also introduced a new feature… or should I say, a news feature. Ah ah ahahhah ha… I’m sorry. You’ll now see the patch notes (and any other update stuff we throw your way) in the client! With video!
Anyway, this lets us finally talk to most users (you know – the folks that aren’t about to read my yapping in the Discord, or whatever).
There, um, have been a few bugs. This was a particularly rare one that I wanted to share.
I truly mean the next sentence. Seriously. Please. Please listen to me.
EXTREME VOLUME WARNING. NO, SERIOUSLY. ![]()
EXTREME VOLUME WARNING. NO, SERIOUSLY. I’M WARNING YOU DOWN HERE, TOO. NO EXCUSES. ![]()
anyway it’s not supposed to do that but we fixed it i think. my bad if i kill your ears. i didn’t mean to. i just wanted you to know about the patch notes. anyway, on to some Cool Stuff!
High Fidelity Face Tracking
You may be familiar with the “Selfie Expression” feature, which allows you to use your webcam for face tracking (and finger tracking) that animates your avatar. This works by using the old viseme (lipsync) and eyelook support already on many avatars.
While this meant that the feature supported a bunch of old avatars, the old systems weren’t created with full high fidelity face tracking in mind.
That means… it’s time for an upgrade.
Beyond Legacy Selfie Expression
We’re introducing a new “Face Tracking” section to the Avatars SDK which adds support for expressive and creative authoring of avatars that respond to high fidelity face tracking.
This new system allows integrated interaction with visemes, eyelook and eyelids, and the full set of Unified Expressions tracking keys from the standard established by VRCFT.
There’s a lot of detail to cover here, so let’s just dive right in, explaining elements in the screenshot from top to bottom:
- Use All Tracking Keys: this checkbox exposes all of the Unified Expressions keys for use. Checking this box establishes that this avatar is a full face tracking avatar.
- This exists mainly to separate out avatars that are just trying to do advanced eye or viseme control (the new systems are the only way to use multiple meshes with visemes, for example). Without the checkbox those avatars would be surfaced as full face tracking avatars in the avatars UI etc.
- Face Tracking Meshes: you can add multiple meshes to be affected by the face tracking system.
- Also, when visemes are handled via the face tracking system (there’s a dropdown option in the old visemes section to use the advanced face tracking systems instead) this means that you can drive visemes on multiple meshes as well.
- Anything in the system that drives a blendshape will drive blendshapes with that same name across all meshes in this list.
- Viseme Dampen: you can select how visemes driven by audio interact with face tracking driven by tracking (to prevent overdrive issues).
- The options are “Dampen Visemes” (strong mouth tracking activity dampens viseme activity) and “Dampen Tracking” (strong audio viseme activity dampens associated mouth tracking strength). With a slider to tune in how much dampening works best for the avatar
- Blendshapes Sets: You can define multiple entire sets of mappings between the tracking data and blendshapes.
- For example, you could make a “happy set” or “angry set” or just a partial layered set such as “bored eyelids” etc. Each blendshape mapped in a set also gets a “Multiplier” value, so you could make a copy of a set that just drives everything at 10x.
- Blendshapes Sets simultaneously layer together so that “max wins” for anything trying to set a final blendshape value on your meshes. You can dynamically change the weight of an entire set using a new animator state behavior:
- In the example image, when the state behavior is triggered, it would take the value from a “CheekPuff” avatar parameter, remap the range from 0.5~0 into a weight going from 0~1 and smoothly move the blendshapes set named “normal” towards that target weight (speed setting is 3 in the screenshot).
- In this way, you can use the animator as a state machine to control the overall state for how face tracking layers onto the avatar, while leaving the heavy lifting of sampling tracking data and applying blendshapes to faster systems that live outside the animator.
- Parameter Behaviors: these allow you to avoid complicated animator setups for combining and mathematically manipulating face tracking input. On the left, you can choose a target. Options are:
- Forward to Animator: sends the result of the calculation to an animator parameter to use in the animator however you’d like. In this example, we’re taking the maximum of CheekPuffLeft and CheekPuffRight tracking keys, and combining that into a single CheekPuff parameter for the animator to use
- Apply Blend Set Weight: lets you apply the result as the weight value for a Blendshapes Set
- Apply to Blendshape: directly applies the result to a blendshape, without using the animator
- Limit Blendshape (Min), Limit Blendshape (Max): these options apply the result as a limit to the min or max value of a blendshape. Useful for preventing clipping from blendshapes that should limit each other and not be fully active at the same time
- Parameter Behaviors allow you to select a combine mode. Options are:
- Max: take the maximum value from all the input tracking keys (you can optionally invert them)
- Min: use the minimum value fro all the input tracking keys
- Add: add up all the tracking keys
- Multiply: multiply together all the tracking keys
- Custom: create a custom math expression such as: “max(EyeClosedLeft, EyeClosedRight) * 0.5” you can use tracking key names directly and the operations: + - * / abs() min() max() clamp(). The final output is clamped between -1 and 1
What about synced parameters? Performance ranks? Webcam support? OSC support?
Synced Parameters
The new system sends the entire set of Unified Expressions face tracking keys across the network to remote viewers of your avatar, so the same native SDK tracking features and animator interaction are active on remote, too.
This means you don’t need to use any synced parameters for this system. The Unified Expressions data will be transmitted similarly to how NetIK is transmitted (meaning it can be lossy depending on factors such as how close you are to the remote avatar).
We’ll tune this behavior over time with your feedback, but the goal is that nearby avatars have very high fidelity, without wasting network bandwidth on avatars you’re not really looking at.
From an avatar creator’s perspective, network degradation should be similar to someone switching from very accurate face tracking hardware to less accurate hardware, meaning if the avatar is built to work with a range of tracking hardware, it should work in a range of network conditions, too.
If however you want to be extra sure some tracking value is not subject to dynamic lossy behavior, you can forward it to the animator with a Parameter Behavior, and set the animator parameter as synced (using your synced parameters budget in that case).
For the majority of cases this shouldn’t be necessary though.
Performance Ranks
The new system keeps track of two things: Face Tracking Operations, and Forwarded Parameters. The goal is to prevent abuse of the new systems while still allowing enough freedom to incentivize using the new stuff rather than relying on the old animator-heavy setups (which will still remain possible).
- Face Tracking Operations: roughly means a single math operation that the face tracking system performs. This includes:
- Each blendshape mapping in each Blendshapes Set
- Each input into a Parameter Behavior
- Each custom operation in a custom Parameter Behavior
- Operations affecting a blendshape get multiplied by the number of meshes mapped to the face tracking system
- Current limits (subject to change):
- Excellent ≤ 2,000
- Good ≤ 4,000
- Medium ≤ 8,000
- Poor ≤ 16,000
- Very Poor > 16,000
- Forwarded Parameters: how many tracking parameters are forwarded into the animator by the Parameter Behaviors using target mode: “Forward to Animator”
- The idea here is to incentivize not just forwarding every last tracking parameter right into the animator and creating even more heavy animators than before.
- Current limits (subject to change):
- Excellent ≤ 10
- Good ≤ 20
- Medium ≤ 30
- Poor ≤ 40
- Very Poor > 40
Webcam Support
The new system works with Selfie Expression webcam face tracking, and because we’re not trying to fit everything into a small number of viseme mappings, the fidelity will be much much higher! This should allow all our desktop PC users to enjoy highly expressive avatars with just a webcam!
OSC Support
The new system also accepts a simple binary blob OSC message with one byte per Unified Expressions tracking key. So OSC based VR face tracking will work as well!
WHEN???
Soon
!
This has been in closed beta testing for awhile (thank you to those testers!) and we’ve been gathering helpful feedback from prominent community members such as Hash and the VRCFT team and many others as we’ve been working on it. Stay tuned in our official discord open-beta-announcements channel for when general public testing opens up.
Lastly, here’s an example video using the new face tracking SDK, provided by Hash showing their face tracking work on the Lapwing avatar from Kuji:
Udon Methods for Friend Info
VRChat Worlds are best experienced with friends, so we’re adding functionality that world creators can use to reward you for bringing and making friends!
The new methods are:
- Get “Bucketed” Friend Count gives worlds an approximate count of how many friends you have in the world, like this (exact numbers TBD):
- None (0-1)
- Few (2-4)
- Some (5-9)
- Many (10+)
- Events for Friend Requests triggers when a friend request is sent or accepted in the current instance, without revealing the other side of the connection
- Event when the local player sends a friend request (but not to whom the request was sent)
- Event when the local player accepts a friend request (but not from whom the request was sent)
We’ve planned these features very carefully to balance user privacy with fun new abilities for worlds. However, if you don’t want worlds to be able to access this info at all, you can turn off the new “Allow Worlds to Count Friends in Instance” setting which will launch at the same time as the feature.
Name Mapped Parameter Buffers
We talked a bit about Variable Width Avatar Parameters in a previous Developer Update. Since then, we’ve also been looking at extending the system further to support mapping synced avatar parameters by name.
Previously if you’ve made an avatar available for multiple platforms with synced avatar parameters, you’ve had to be careful to keep the parameter buffer (the block of 256 bits that contains your data) the same across all platform builds for that avatar. This is because the VRChat client currently operates on the assumption that this buffer is the same for all platforms, which can lead to unexpected behavior in situations where they don’t match.
A future update aims to address this by mapping these parameters by their names rather than by where they appear in the buffer.
As long as the parameter has the same name across all platforms for the avatar, the game client will be able to correctly read it from other users in the instance even if they’re running a different platform than you. This is being designed in a way that means it should happen transparently, without requiring any changes on the avatar creator’s side.
This feature is being set up in combination with variable width parameters - keep an eye out for both in a future update!
Speaking of variable width parameters, here are a few recent developments with those:
- Based on your feedback, we’ve been looking at allowing variable representation, which means you can choose whether the value is signed (positive and negative values) or unsigned (positive values only). For integers, this controls whether the values start at zero or are roughly equally distributed around zero. For floats, switching to unsigned allows the range to be reduced from [-1,1] to [0,1], which trades off the negative numbers but gives double the original precision so the value can be more precise.
- We’ve found during development that it’s unfortunately unlikely this will be able to support bit widths above 8, due to dependencies on how synced parameters are currently networked. However, it’ll still be possible to reduce them below 8, which we hope will help to save on buffer space for some of the more complex avatars.
- These options will be hidden by default in the SDK, with a control to show and hide them, to avoid overwhelming new creators. Here’s a quick updated preview of the interface for avatar parameters (as always, this is subject to change):
Conclusion
That’s it for this week! see you in a few weeeeeeks






