Udonite compiles a large slice of everyday C#. Every construct below is covered by tests that assemble the output and run it on the real Udon virtual machine.

## What compiles

### Types and members

<div class="chips">
<span class="tag"><code>class</code></span>
<span class="tag"><code>struct</code></span>
<span class="tag"><code>interface</code></span>
<span class="tag"><code>enum</code></span>
<span class="tag">nested types</span>
<span class="tag">your own classes as fields and locals</span>
<span class="tag">generics with constraints</span>
<span class="tag">default interface methods</span>
<span class="tag">properties</span>
<span class="tag">auto-properties</span>
<span class="tag">expression-bodied members</span>
<span class="tag">indexers</span>
<span class="tag">extension methods</span>
<span class="tag"><code>params</code></span>
<span class="tag">optional parameters</span>
<span class="tag">named arguments</span>
<span class="tag"><code>out</code> / <code>ref</code> parameters</span>
<span class="tag">tuples and deconstruction</span>
<span class="tag">local functions</span>
<span class="tag">static helper classes</span>
</div>

Records and record structs: positional construction, `with`, value equality, `ToString`, deconstruction. Static fields must be `const` or `readonly` (see below).

### Statements and expressions

<div class="chips">
<span class="tag"><code>if</code></span>
<span class="tag"><code>switch</code> statements</span>
<span class="tag">switch expressions</span>
<span class="tag"><code>for</code></span>
<span class="tag"><code>foreach</code></span>
<span class="tag"><code>while</code></span>
<span class="tag"><code>do</code></span>
<span class="tag"><code>break</code></span>
<span class="tag"><code>continue</code></span>
<span class="tag">pattern matching</span>
<span class="tag">type patterns</span>
<span class="tag"><code>is not null</code></span>
<span class="tag">relational patterns</span>
<span class="tag">property patterns</span>
<span class="tag"><code>when</code> guards</span>
<span class="tag"><code>?.</code></span>
<span class="tag"><code>??</code></span>
<span class="tag"><code>??=</code></span>
<span class="tag">string interpolation with format specifiers</span>
<span class="tag"><code>nameof</code></span>
<span class="tag">arithmetic operators</span>
<span class="tag">bitwise operators</span>
<span class="tag">shift operators</span>
<span class="tag"><code>[Flags]</code> enums</span>
<span class="tag"><code>HasFlag</code></span>
<span class="tag"><code>char</code> arithmetic</span>
<span class="tag">arrays</span>
<span class="tag">multidimensional arrays</span>
<span class="tag">ranges and indices</span>
<span class="tag"><code>Array.Sort</code></span>
<span class="tag"><code>Find</code></span>
<span class="tag"><code>FindAll</code></span>
<span class="tag"><code>Exists</code></span>
<span class="tag"><code>IndexOf</code></span>
<span class="tag"><code>Resize</code></span>
<span class="tag"><code>Copy</code></span>
<span class="tag"><code>Fill</code></span>
<span class="tag"><code>ConvertAll</code></span>
<span class="tag"><code>List&lt;T&gt;</code></span>
<span class="tag"><code>Dictionary&lt;K,V&gt;</code></span>
<span class="tag"><code>HashSet&lt;T&gt;</code></span>
<span class="tag"><code>Queue&lt;T&gt;</code></span>
<span class="tag"><code>Stack&lt;T&gt;</code></span>
<span class="tag">LINQ</span>
<span class="tag"><code>Action</code> / <code>Func</code> fields</span>
<span class="tag">method groups</span>
<span class="tag">multicast <code>+=</code> / <code>-=</code></span>
<span class="tag">C# <code>event</code></span>
<span class="tag">delegates to another behaviour's method</span>
<span class="tag">lambdas as values</span>
<span class="tag"><code>StringBuilder</code></span>
<span class="tag"><code>string.Format</code></span>
<span class="tag"><code>Split</code></span>
<span class="tag"><code>Join</code></span>
<span class="tag"><code>Substring</code></span>
<span class="tag"><code>Replace</code></span>
<span class="tag"><code>Trim</code></span>
<span class="tag"><code>PadLeft</code></span>
<span class="tag">nullable value types</span>
<span class="tag"><code>HasValue</code></span>
<span class="tag"><code>GetValueOrDefault</code></span>
</div>

Relational patterns look like `is > 5 and < 10`. Ranges and indices cover `arr[^1]` and `arr[1..3]`. LINQ works over arrays, lists and dictionaries: `Select`, `Where`, `OrderBy`, `ThenBy`, `GroupBy`, `First`, `Any`, `All`, `Sum`, `Average`, `Min`, `Max`, `Count`, `Take`, `Skip`, `TakeWhile`, `SkipWhile`, `Distinct`, `Reverse`, `Concat`, `Zip`, `Union`, `Intersect`, `Except`, `SequenceEqual`, `ToArray`, `ToList`, `ToDictionary`, `Range`, `Repeat`, and chains of them. Lambdas passed to LINQ and to `List<T>`/`Array` helpers are inlined at the call site. A method group looks like `Action done = Cleanup;`. Delegates to a public method on another behaviour, and lambdas as values, both compile; a lambda that captures a variable has one restriction, covered below.

### Unity and VRChat

<div class="chips">
<span class="tag"><code>GetComponent&lt;T&gt;()</code></span>
<span class="tag"><code>TryGetComponent&lt;T&gt;(out T)</code></span>
<span class="tag"><code>Instantiate</code></span>
<span class="tag"><code>Destroy</code></span>
<span class="tag"><code>SetActive</code></span>
<span class="tag">transforms</span>
<span class="tag">physics queries</span>
<span class="tag"><code>Mathf</code></span>
<span class="tag"><code>Vector3</code></span>
<span class="tag"><code>Quaternion</code></span>
<span class="tag"><code>Color</code></span>
<span class="tag"><code>Random</code></span>
<span class="tag"><code>Time</code></span>
<span class="tag">coroutines</span>
<span class="tag"><code>yield return null</code></span>
<span class="tag"><code>WaitForSeconds</code></span>
<span class="tag"><code>WaitUntil</code></span>
<span class="tag">nested coroutines</span>
<span class="tag"><code>StartCoroutine(Run())</code></span>
<span class="tag"><code>StartCoroutine(nameof(Run))</code></span>
<span class="tag"><code>StopAllCoroutines</code></span>
<span class="tag"><code>Invoke</code></span>
<span class="tag"><code>InvokeRepeating</code></span>
<span class="tag"><code>CancelInvoke</code></span>
<span class="tag"><code>async</code> methods</span>
<span class="tag"><code>Task</code></span>
<span class="tag"><code>UniTask</code></span>
<span class="tag"><code>UniTaskVoid</code></span>
<span class="tag"><code>await</code></span>
<span class="tag"><code>VRCPlayerApi</code></span>
<span class="tag"><code>Networking</code></span>
<span class="tag">pickups</span>
<span class="tag">stations</span>
<span class="tag"><code>UdonBehaviour</code> references</span>
<span class="tag"><code>SendCustomEvent</code></span>
<span class="tag"><code>SetProgramVariable</code></span>
<span class="tag"><code>GetProgramVariable&lt;T&gt;</code></span>
</div>

`Invoke`, `InvokeRepeating` and `CancelInvoke` work on public methods. `async` methods can return `void`, `Task`, `UniTask` or `UniTaskVoid`, with `await Task.Delay(...)` and awaiting other async methods. Everything in [Networking](/docs/compiler/networking).

## What Udon can never run

These are refused with `UDN0011`. The refusal says so, and says what to do instead.

| Construct | Why, and what to write instead |
|---|---|
| `try`/`catch`/`throw` | Udon has no exceptions. Check the condition first. |
| Mutable `static` fields | Every behaviour has its own heap, so a static would be one value per behaviour rather than one shared value. Use a field on one behaviour and reference it. |
| `Awake` | Udon does not dispatch it. Use `Start`. |
| `CompareTag` and `gameObject.tag` | Udon does not expose tags. Compare layers or names, or hold a reference. |
| `IsInvoking`, `Application.isPlaying`, `Time.timeScale`, `AudioListener`, `new GameObject()`, `ScriptableObject` subclasses | Not exposed by Udon. |
| Serialized arrays of your own classes or structs in inspector fields | Udon cannot deserialize them. Use arrays of primitives, Unity types, or references to behaviours. |
| A delegate pointing at a method on a plain object (not a behaviour), and a delegate in a public field Unity would serialize | Neither survives the trip into a world. |
| A capturing lambda kept beyond the method that created it (assigned to a field, returned, passed as an argument, or created inside a loop) | the captured variables live in the behaviour's single heap, so a stored closure would see stale state on the next call. Non-capturing lambdas can be stored freely; capturing ones work as locals called within the same method. |

## Not yet

Refused with `UDN0002`. These are gaps in Udonite rather than in Udon, and the ones people ask for get lifted.

- List patterns (`is [1, ..]`).
- `typeof(T)` as a free expression, and the non-generic `GetComponent(typeof(T))`.
- Recursion (`UDN0012`), capturing lambdas inside loops, `checked` arithmetic.

If a refusal blocks you, open an issue with the refusal line. The construct is usually a day's work once it is named.
