unity-vrc-udon-sharp

Installation
SKILL.md

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.SetOwner is locally immediate on the calling client — Networking.IsOwner(gameObject) is true synchronously after the call, and writing [UdonSynced] fields plus RequestSerialization() immediately afterwards is safe under an IsOwner guard. Concurrent SetOwner calls 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. Late-joiner-visible state must live in [UdonSynced] variables, which are delivered automatically via OnDeserialization; no manual RequestSerialization() on join is needed.
  • What if the owner leaves mid-session? VRChat automatically transfers ownership to a remaining player (selection rule is not publicly documented), and OnOwnershipTransferred fires on all clients. Synced variables are preserved, so state is not frozen; decide upfront whether to keep the current value, reset to a known default, or re-apply/re-broadcast derived state in OnOwnershipTransferred.

Context Preservation

Installs
436
GitHub Stars
229
First Seen
Mar 12, 2026
unity-vrc-udon-sharp — niaka3dayo/agent-skills-vrc-udon