The Udon VM and Udon Assembly
This page was written by a member of the VRChat community. Thank you for your contribution! The VRChat team can't guarantee the validity of the information on this page. If you would like to suggest changes, go to the bottom of this page and click "Edit this page."
Overview of the Udon VM
The Udon VM is a bytecode interpreter designed to run compiled Udon Graph programs.
As such, it's important to keep in mind what it has and doesn't have:
- The Udon VM is expected to be running inside a .NET environment. While reflection is not used to access functions, the Udon VM is 'styled' like it is.
- It doesn't directly implement call/return or subroutines (though
JUMP_INDIRECT
exists and can be used for the purpose). - It has flow control, via
JUMP
,JUMP_INDIRECT
, andJUMP_IF_FALSE
. - It can call functions from C# (where allowed).
- It doesn't have local variables; only fields on the object.
- It has an integer stack, but this integer stack should be treated as essentially "extra parameters" for opcodes in most cases. It is possible to use it as part of a call/return mechanism, but remember that there are no local variables, so recursive functions must be implemented very carefully.
You can export Udon Assembly from Udon Graph and UdonSharp programs.
This can help in getting an idea of how the code you write is compiled, and help you find extern names!
Udon Types
"Udon Types" are how Udon refers to C# types.
The easiest way to understand these type names is to start with the corresponding .NET name, such as System.Int32[]
.
There are various rules in the construction of Udon Types:
- All
.
s and+
s are removed, i.e.VRC.SDKBase.VRCPlayerApi+TrackingData
becomesVRCSDKBaseVRCPlayerApiTrackingData
. - The type may have
Array
appended, representing[]
.
As such, the example above is SystemInt32Array
.
Udon Assembly
Udon Assembly programs are made up of two sections: The data section, and the code section.
These sections are marked with start/end directives, as so:
.data_start
# Data goes here!
.data_end
.code_start
# Code goes here, instead!
.code_end