unity-vrc-udon-sharp
UdonSharp Skill
Why This Skill Matters
UdonSharp looks like regular Unity C# scripting — until you hit its hidden walls. Many standard C# features (List<T>, async/await, try/catch, LINQ, generics) silently fail or refuse to compile in Udon. Networking is even more treacherous: modifying a synced variable without ownership produces no error — it just does nothing. Forgetting RequestSerialization means your state changes never leave your machine. Standard single-player local testing gives zero signal about these networking bugs because there is only one player.
Every rule in this skill exists because UdonSharp's default behavior is to fail silently. Read the Rules before generating any code.
Before Writing Network Code
Four architectural decisions that must be made before choosing sync modes or writing any synced variable. Changing them mid-implementation typically requires a full rewrite:
- Who owns this state? One owner writes; all others read. If two players can both write (e.g., a shared toggle), you need an ownership transfer protocol — writes without ownership are silently discarded.
- When does ownership transfer? On grab? Interact? Game event?
OnPlayerLeft?Networking.SetOwneris locally immediate on the calling client —Networking.IsOwner(gameObject)istruesynchronously after the call, and writing[UdonSynced]fields plusRequestSerialization()immediately afterwards is safe under anIsOwnerguard. ConcurrentSetOwnercalls from multiple clients are resolved by network arrival order — there is no client-side arbitration, so accept that the loser's write is overwritten. - What do late joiners see? State set only by one-time events (
SendCustomNetworkEvent) is invisible to late joiners. Persistent state requires[UdonSynced]variables; the owner callsRequestSerialization()on join events to push current state to newcomers. - What if the owner leaves mid-session? Without explicit
OnPlayerLefthandling, the object's synced state can never change again. Decide upfront: auto-transfer to master, reset to a known default, or the next interacting player claims ownership.