Skip to content

FOS Sync Doctor

Version 1.0.0 · requires FOS Essentials Core 1.1.0 or later

Audits the synchronised behaviours of your world for the mistakes that never raise an error — the ones you only discover when a player joins your instance and sees a different world from everyone else.

Free. Requires FOS Essentials Core 1.1.0.

Menu: FOS Essentials > FOS Sync Doctor > Audit.


This pack contains editor code only. No component, no prefab, no behaviour. It reads your scripts and reports; it never runs in game and costs nothing at runtime.

That is also why it ships without a Runtime assembly or a Prefabs folder, unlike every other FOS pack: there would be nothing to put in them.


Synchronised variables with no OnDeserialization — error

Section titled “Synchronised variables with no OnDeserialization — error”

The single most common late-joiner bug. The values arrive, and nothing applies them. For the player who joined, the world stays in its initial state — permanently.

A field carrying [FieldChangeCallback] is not reported: the callback fires on deserialisation, so that pattern is already correct.

RequestSerialization() inside Start() — warning

Section titled “RequestSerialization() inside Start() — warning”

VRChat documents that a serialisation requested from Start() does not reach players who join later. Send it from an event, or from OnPlayerJoined.

Manual sync that never serialises — warning

Section titled “Manual sync that never serialises — warning”

Manual sync sends nothing until you ask. Without a single RequestSerialization() the variables are, in practice, local.

Serialising with no ownership check — warning

Section titled “Serialising with no ownership check — warning”

Only the owner can serialise. Called by anyone else, RequestSerialization() silently does nothing — the most confusing failure in Udon, because everything looks fine locally.

Continuous sync carrying an array or a string — warning

Section titled “Continuous sync carrying an array or a string — warning”

Continuous sync is capped at roughly 200 bytes per behaviour. A variable-length field goes over it without warning. Manual sync carries far more.

Without [UdonBehaviourSyncMode] the mode defaults to Any and stays changeable in the inspector, where it can be altered by accident.

A broadcast event acting on the local player — warning

Section titled “A broadcast event acting on the local player — warning”

The one that costs the most time to understand. A network event sent to every client runs on every client, and Networking.LocalPlayer is a different player on each of them. A teleport meant for one person moves the whole instance.

Player events used without isLocal — warning

Section titled “Player events used without isLocal — warning”

OnPlayerTriggerEnter and its siblings fire on every client, for every player entering. Without the check, a stranger walking through your volume triggers the effect on your machine.

A network event whose name starts with _ — warning

Section titled “A network event whose name starts with _ — warning”

VRChat refuses to run such an event remotely. The call leaves, nothing happens, and nothing is logged.


Findings come in two kinds, and the window never mixes them up.

Certain findings are established by inspecting the compiled types: which fields carry [UdonSynced], which sync mode is declared, whether OnDeserialization is overridden. These are facts.

Probable findings are deduced from the text of your scripts, because the body of a method cannot be inspected any other way. “This script never calls RequestSerialization is wrong if another script calls it for you. Those findings carry a probable tag and are worth a look rather than a blind fix.

Comments and string literals are stripped before anything is searched, so a script explaining “no ownership check here” in a comment is not mistaken for one that performs the check.

An audit tool that cannot tell you how much to trust it is not worth much.


  • It does not read your scene, only your scripts. A behaviour that is perfectly written but wired to the wrong object is not something this tool can see.
  • It does not check performance, lighting or Quest budgets. VRWorldToolkit does that well, and for free.
  • It does not touch anything. Every finding is a report; the fixes are yours to make.

By default the FOS packs themselves are skipped — you are auditing your world, not this line. The toggle exists if you want to look.