mcpField
V
vrc-udon

vrc-udon

github.com/alexanderstephenthompsonDevelopment47 installs
Repository

About vrc-udon

vrc-udon is a development skill for writing Udon scripts for VRChat worlds with UdonSharp. It focuses on networking, ownership, synchronization, and handling players who join late.

Key features

  1. 01UdonSharp syntax and patterns
  2. 02Networking and variable synchronization
  3. 03Ownership transfer guidance
  4. 04Late-joiner state handling
  5. 05Event-driven script communication

Use cases

  1. 01Write Udon scripts for VRChat worlds
  2. 02Synchronize state across networked players
  3. 03Handle ownership before changing synced variables
  4. 04Keep world state correct for late joiners

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/alexanderstephenthompson/claude-hub --skill vrc-udon

After installing, type/vrc-udonin Claude Code to confirm it loaded.

Bundled filesreferences/networking.mdassets/udon-checklist.md

Details

From the project README

VRChat Udon Skill

Version: 1.0 Stack: VRChat SDK, UdonSharp

Udon looks like regular Unity scripting until you add networking. Then everything changes. Modifying a synced variable without ownership silently fails — no error, no warning, just nothing happens. Forgetting RequestSerialization means your changes never leave your machine. Testing in the editor gives you zero signal about networking bugs because there's only one player. Late joiners see the default state, not the current state, unless you explicitly handle re-serialization.

Every rule in this skill exists because the default Udon behavior is to silently fail.


Scope and Boundaries

This skill covers:

  • UdonSharp syntax and patterns
  • Networking and synchronization
  • Player interactions
  • World events
  • Common Udon behaviors

Defers to other skills:

  • unity-csharp: C# patterns and performance optimization
  • vrc-worlds: World setup and optimization

Use this skill when: Writing Udon scripts for VRChat worlds.


Core Principles

  1. Network Awareness — Every synced variable has bandwidth cost.
  2. Owner Model — Only owner can modify synced variables.
  3. Late Joiners — State must be correct for players who join later.
  4. Local vs Global — Be explicit about what's local vs networked.
  5. Event-Driven — Use SendCustomEvent, not polling.

Patterns

Basic UdonSharp Script
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class MyBehavior : UdonSharpBehaviour
{
    [UdonSynced] private bool _isActive;

    public override void Interact()
    {
        // Take ownership before modifying synced var
        Networking.SetOwner(Networking.LocalPlayer, gameObject);
        _isActive = !_isActive;
        RequestSerialization();
    }

    public override void OnDeserialization()
    {
        // Called when synced vars update from network
        UpdateVisuals();
    }

    private void UpdateVisuals()
    {
        // Update based on _isActive state
    }
}
Ownership Transfer Pattern
public void TakeOwnershipAndModify()
{
    // Always check and transfer ownership first
    if (!Networking.IsOwner(gameObject))
    {
        Networking.SetOwner(Networking.LocalPlayer, gameObject);
    }

    // Now safe to modify synced variables
    _syncedValue = newValue;
    RequestSerialization();
}
Late Joiner Support
[UdonSynced] private bool _doorOpen;

public override void OnPlayerJoined(VRCPlayerApi player)
{
    // If we're owner, re-serialize state for the new player
    if (Networking.IsOwner(gameObject))
    {
        RequestSerialization();
    }
}

public override void OnDeserialization()
{
    // Late joiners get current state here
    SetDoorState(_doorOpen);
}
Custom Event Communication
// Script A - sends event
public UdonBehaviour targetScript;

public void OnButtonPress()
{
    targetScript.SendCustomEvent("HandleButtonPress");
}

// Script B - receives event
public void HandleButtonPress()
{
    // Handle the event
}

// Network event (all players)
public void TriggerGlobalEvent()
{
    SendCustomNetworkEvent(NetworkEventTarget.All, "OnGlobalEvent");
}

public void OnGlobalEvent()
{
    // Runs on all players
}

Anti-Patterns

Anti-PatternProblemFix
Modifying synced vars without ownershipSilent failureSetOwner first, then modify
Forgetting RequestSerializationChanges don't syncAlways call after modifying synced vars
Syncing too much dataNetwork lagMinimize synced variables
Update() for network checksPerformance wasteUse OnDeserialization, events
No late joiner handlingBroken state for joinersRe-serialize on player join

Checklist

  • Ownership transferred before synced var changes
  • RequestSerialization called after changes
  • OnDeserialization updates all visual state
  • Late joiners handled (OnPlayerJoined + serialize)
  • Network events used for global triggers
  • Minimal synced variable count

References

  • references/networking.md — Udon networking, sync, and ownership patterns

Assets

  • assets/udon-checklist.md — Udon script development checklist

Comments

Markdown supported