Welcome to the Developer Update for 16 February 2023! This is the fifth Developer Update of 2023.
Thank you to DrMorro, whose award-winning expansive world Organism graces our Dev Update banner this week. I’d tell you to “get lost” in Organism, but that sounds kinda mean. Also, it’s kinda a given you’ll get lost in there.
If you’d like to catch up, you can read our previous Developer Update from February 9.
This is a pretty technically-heavy Update, so bear with the WALL OF TEXT in this one.
We’re currently planning to wait on the release of the updated VRChat Creator Companion with the Web UI (we call it “VCC Web”) before fully swapping to VCC.
Due to feedback, we are investigating direct downloads of packages. They’ll be VPM-compatible UnityPackages instead of the legacy ones. VCC will continue to be the recommended and primary method to set up the VRChat SDKs and keep them updated.
Once VCC releases, SDK2 will be deprecated simultaneously and SDK2 will no longer be available for download.
We are now actively blocking uploads from Unity versions older than 2019. This has affected an extremely low number of creators!
Users will see a message in their Unity console if their SDK is too old and they’ve been blocked:
Any users still on a version before 2019 should follow the below upgrade guides, and work their way up to the Currently Supported Unity Version.
As noted in previous Developer Updates, at a future date (undetermined, but on the scale of “months away”), SDK2 worlds and avatars will no longer be permitted for upload. We will support existing SDK2 content within VRChat for as long as possible.
If you are maintaining a SDK2 world project and want to migrate, CyanLaser maintains CyanTrigger, which provides a SDK2-like interface for Udon. He also has created a SDK2 migrator, which can auto-convert SDK2 to SDK3, including complicated assets like the Standard Assets package that was supported with SDK2.
We released a patch for VRChat on Feburuary 9, containing a few small fixes and improvements!
- Group Banner opacity now follows icon opacity, banners will be visible even with nameplate opacity set to 0%
- You can still turn Group Banners off entirely via the Group Banner toggle in the Quick Menu
- Group Banners now use mipmaps, meaning they will no longer shimmer and have improved visual quality at a distance
- The camera now has an option to show a rule-of-thirds grid for easier photo composition! Find the button on the far right of the options
- Fixed an issue causing jumpy camera motion while in moving stations
- We are still working on improving the UI and grab functionality while locomoting
- Fixed issue where player would exit stations when trying to move in drone camera mode
- Fixed issues with aiming the camera in desktop mode while in stations
- Fixed “Take Photo” button visually looking enabled while the camera is saving a multi-layer image. Saving high-resolution layered images can take a while-- at 8K, each image is ~45MB!
- Fixed menu FPS calculation to allow for FPS values lower than 11 to be displayed… though we hope you won’t need to experience that too often!
- Added “Y” button for Chatbox to keyboard controls menu in Desktop mode
During maintenance and upgrading of our backend systems that we completed back in mid-January, some player moderations (blocks, mutes, etc.) that were made prior to that then may have been lost during the upgrade process.
Unfortunately, these player moderations won’t be recovered! To avoid this in the future, we’re auditing our upgrade process to ensure we are not losing this data. We apologize for any inconvenience this might cause!
We’ve got two changes on the way for the Avatar Performance rank system!
A bit ago, we started calculating avatar VRAM usage as a result of the textures on the avatar (we don’t count meshes yet). This has turned out to be useful, as people discovered that their setup was a bit VRAM-heavy, and optimized as a result!
The time has come for us to fully implement this stat. In an upcoming release, Avatar VRAM usage will affect your performance rank.
Here’s the numbers we’re looking at. Remember, this is textures only! Thry’s tool also counts meshes. (It’s still a great tool. Hi, Thry!)
This means Very Poor is anything >= 150MB.
This means Very Poor is anything >= 40MB+.
How’d you arrive at these values?
Let’s start with PC. First, we need to establish how much VRAM we have to play with. We looked at the Steam Hardware survey as well as our own internal analytics, and called 8GB of VRAM a decent median value.
Next, we need to target an instance size that was close to the average instance size users encountered, but left room for full instances to exist reasonably. This gave us an instance size of 20, so any values need to fit within 8GB split across 20 avatars.
Except… not quite. Between the VR compositor and your OS, we assume 2GB of your VRAM is already spoken for. On top of that, the world you’re in needs VRAM too! We chop off another GB for that.
So, we took the remaining 5GB, divided it across 20 avatars, giving us the above values.
If you’re someone with a fancy, high VRAM card, this is still good news for you! On PC, in a hardcapped 80-person instance full of line-toeing Poor avatars at 149.9MB, avatar textures will “only” be eating 12GB of VRAM. That sounds like a lot, but currently full instances experience far worse, sometimes with 3090s, 4090s, and 7900XTXs running their 24GB of VRAM dry when someone rolls in with a Medium avatar with 20 8K textures. Yeesh. shivers
What about Quest values?
The Quest has 6GB of shared RAM between the CPU and GPU. No such thing as VRAM, just RAM.
Practically speaking, we only have access to about 4GB of that RAM. The underlying Quest OS eats up a good bit.
Since we already did a lot of the hard work for PC, we can approximate a scale-down by simply dividing the PC values by 4.
How many avatars will this affect? How many avatars will become Very Poor?
Another great question. We looked into this. The answer is “a very small amount”. About 0.8% of avatars that were not already Very Poor will be ranked Very Poor after this change.
Let’s look at this a different way.
This is a (pretty big!) slice of avatars on VRChat. Each one of the pie charts represents the current Performance Rank of that avatar.
Each slice of each pie indicates how the avatars within that Perf Rank will rank with respect to the VRAM stat. For example, an avatar currently in the Medium pie that falls into the orange “Poor” slice will fall to Poor once this system is implemented.
In short, most avatars won’t change rank due to this. Very few will drop all the way to Very Poor.
Of course, these pie charts are misleading, because you don’t know how many avatars are in each rank (and I’m not gonna tell you). As such, the slices seem larger than you’d expect.
I will tell you that there are a lot of Very Poor avatars that won’t budge with this change. Keep that in mind.
Will the SDK tell me this info?
Yes, we’ll be implementing this stat into the SDK so you know what’s going on when we implement this change.
If you have other questions, ask away in the thread.
We’re also adding Constraints to Avatar stats! This only applies to PC, as Quest doesn’t have constraints. We’ll get to that in a second.
This stat will not affect Performance Rank yet, but as you can see, we have a recommended max of 15.
Wait, what? Only 15? I thought constraints were cheap-like-free!?
Yeah, we did too. We were wrong.
Constraints have a significant impact to frametime, and have a “cliff” where if you pass it, Constraints all the sudden cost 30% more, and get worse the more you add.
How’d you arrive at 15 being your recommended value?
Sorta the same way as VRAM. Take a target, split it by an average instance, but keep some room for heavier instances.
How bad are constraints, really?
Not terrible at small amounts, but as you get bigger… pretty bad. Here’s some research we’ve done. Envelope math follows!
From 0 to 682 enabled constraints in the scene, they each cost about 3.2µs (0.0032ms, but remember you get ~11ms per frame at 90FPS). This sounds tiny (and alone, it is!), but they add up FAST. At 300 constraints in a scene, you’re at 0.96ms-- a solid ~9% of your frame budget. Double that to 600, and that’s nearly a fifth of your frametime going to constraints!!
That’s a lot when users are usually already over that 11ms target already, and worse considering that avatar prefabs like clone, clothing attachment, and other community-created systems often include dozens or hundreds of constraints for a single avatar. It isn’t unusual to be in a VRChat instance with over a thousand active constraints.
But if you’re at a thousand constraints, you have another problem: the constraint cliff.
What’s this “cliff” thing?
So, as mentioned, this cost is just simply additive… until you hit 683 constraints.
If you’re unfamiliar with this view of the profiler, it’s comparing two frames and the time it took to calculate and render each frame. In the bottom section, the orange bars going to the right indicate that the “right side” frame took longer in those particular “markers”. We’re looking at constraint-related markers here.
When you go from 682 constraints and hit 683, something in Unity throws a fit. All the sudden, your constraints now cost 30% more-- 4.2µs per frame… and that per-component cost increases with each additional Constraint you add.
This appears to be a Unity bug, and not something we can do much about. As such, for the time being, we need to start informing users “hey, uh, please try to limit how many constraints you’re using.”
You can test this yourself, by the way. These screenshots are from a basic Unity project with no VRChat code included.
What about disabled constraints?
There are three ways to turn off constraints:
Turning off the GameObject or the Component (the green checkboxes) incurs a cost so low that the constraint basically doesn’t exist.
However, constraints also have
IsActive on the component, shown in red. Having this set to False but the GameObject and Component set to True incurred a cost, although one that wasn’t as high as an active constraint. Additionally, these
IsActive False Constraints don’t seem to contribute to the “cliff”, but they do make things slower, so don’t use the
IsActive checkbox to turn Constraints on and off. Turn off the component or GameObject instead.
Can’t you only count enabled constraints?
Sure, but you can animate them on.
And no, before you ask, we can’t rescan on changes. Scanning for perf stats is pretty expensive so we only do it once on avatar load.
Aren’t constraints threaded?
Sorta. They execute off-main, but they have a single-threaded dependency sorting step which makes that irrelevant.
Does this apply to all types of constraints?
We only did testing with Parent constraints, each with only one source. Other types with more sources might have different behavior.
Oh… and the Quest version of VRChat is chomping at the XR2. Is that why you haven’t enabled constraints on Quest?
So, what now?
We’re looking at a few solutions, none of which we’re ready to talk about yet.
We are contacting Unity regarding this buggy behavior, as well as the odd main thread dependency. We haven’t tested on newer Unity versions yet, so it’s possible that the behavior changed in later versions. Remember that Constraints were pretty new in 2019.4!
For now, we ask that avatar creators take it easy on constraints, and avoid prefabs and systems that have excessive constraint usage. Aim for 15 constraints across your whole avatar, disabled or not, max. If they aren’t in usage, turn them off by disabling the GameObject they’re on, or the Component itself.
This feature is currently in development, and we have a working internal build where a World can specify a variety of controls to show in the QuickMenu (buttons, sliders, toggles, labels, etc), which appear in a new tab.
This feature makes it much simpler for creators to add world-specific controls and information, which visitors can easily find and understand!
There will be multiple ways to add and organize these UI controls, including doing it directly from Udon. However, we are focusing first on creating a Unity Editor Window where you build and preview your Udon UI layout.
Adding a simple “Teleport To Roof” button to a world, for example, might look like this:
- Open the Udon UI Editor Window.
- Press “New QuickMenu UI”, which enables the layout and presents an empty UI slot.
- Drag-and-drop the UdonBehaviour which has the Teleportation function into this slot, which adds it to the outline, and presents a chooser with the public variables and events available in the Udon Program.
- Choose the “TeleportToRoof” event from this list.
- This adds a new Button to the QuickMenu UI, labeled “TeleportToRoof”, which will trigger this event when a user presses it.
The following mockup is a basic wireframe that shows the two main parts of the Window - the UI Preview, where you can see what your controls would look like in the QuickMenu, and the Outline, where you can view and edit the details of those controls.
Udon Variables can also be bound to the UI, and will show the latest value of the target variable whether it was changed through the UI or through an Udon Program. For example:
A Creator has a world with Post-Processing which is turned on by default. They make an UdonBehaviour which can toggle the effect on and off with a Boolean variable called
postProcessingEnabled, as well as change the weight of the effect with a float variable called
postProcessingWeight. They select these two variables to show in their default Udon UI group, and set the range of the
postProcessingWeight variable to (0,1). When players visit their world, they can open their Quick Menu and easily set the strength of the effect with the Slider and turn the effect on or off entirely with the Toggle.
Please remember that this is all subject to change as we continue development! We’ll do our best to answer questions about this new Editor Window and the Udon UI System in general, but there are details and workflows to work out still. To get ahead of some likely first questions:
- The look of the Udon UI in the QuickMenu will be customizable, but not at launch.
- You may be able to use this to target properties directly rather than just UdonBehaviour Variables and Events, but probably not at launch.
- You will be able to add and remove controls at runtime using Udon… but probably not at launch.
- You can apply these same controls to a world-space canvas instead of (or in addition to) the QuickMenu.
- We’re thinking about localization for this, but it’s not on the roadmap yet.
We are very excited to get this into your hands!
The Unity Inspector for UdonBehaviours will now detect missing VRCUrlInputField variables, and offer to reload the SDK in case this component did not load correctly (known issue, will be fixed when we can upgrade to Unity 2020 or newer). This change addresses this Canny.
This will likely be a SDK-only release! Keep an eye our our Discord for the announcement. Once it’s out, you’ll be able to update your project easily with the VCC – hit “update”, and you’re done!
As noted above in the Creator Companion reminder section, we’ll still offer web UnityPackage downloads so you can import it that way, but using the VCC is strongly recommended!
The Web port of the Creator Companion has gotten a new helpful tutorial for its initial run to show you the basics and guide you through installing Unity Hub and the correct Unity Editor Version.
We’re real close to getting the Creator Companion Web version to release! Sooooooon!
We’ve spent a lot of time refactoring and fixing up the backend of the VRChat Home webpage, in particular the Groups section!
Generally, you should notice faster loading and rendering, better stability, and better loading and error states.
This is coming quite soon, if it isn’t out already!
you can now pat the VRCat badge on vrchat dot com slash home
That’s all for this week! Whew, more technical stuff!
We’ve got more on the way already for you next week, so we’ll see you then!