UdonSharp Linter brings static analysis for UdonSharp behaviour scripts directly into Visual Studio Code. The extension ships a cross-platform Roslyn-based language server that mirrors the diagnostics produced by the official UdonSharp compiler and VRChat policy packs, while adding responsive editor integrations that work even when Unity or VRChat assemblies are unavailable.
- Real-time diagnostics: Roslyn analyzers surface USH0001–USH0045 findings as you type, including network event rules, runtime restrictions, API exposure limits, and language feature bans.
- Offline-aware analysis: Syntax-only fallbacks detect missing custom events, invalid network signatures, and unsupported APIs without Unity or VRChat stub assemblies.
- Rule intelligence: Search the full rule catalogue, inspect localized documentation, and review per-profile severities without leaving VS Code.
- Status bar telemetry: A shield badge shows the active profile, disabled rule counts, and live server health. Click it to swap profiles or open rule search.
- Code action foundation: The server advertises rule metadata describing which diagnostics can surface quick fixes, enabling incremental rollout of Roslyn code fixes.
- Self-contained server runtime: Bundled .NET 8 binaries for Linux (x64/arm64), macOS (Intel/Apple Silicon), and Windows (x64/arm64) require no user-managed runtime.
All settings live under the udonsharpLinter namespace.
| Setting | Type | Default | Description |
|---|---|---|---|
profile |
string (latest | legacy_0.x | strict_experimental) |
latest |
Selects the bundled policy pack that maps to VRChat/UdonSharp release trains. |
rules |
object | {} |
Override individual rule severities (error, warn, info, off). Keys are normalized to upper-case rule IDs. |
unityApiSurface |
string (bundled-stubs | custom-stubs | none) |
bundled-stubs |
Controls the reference assemblies the Roslyn server loads. Use none for syntax-only mode. |
customStubPath |
string | "" |
Absolute or workspace-relative path to custom stub assemblies when unityApiSurface is custom-stubs. |
allow.refOut |
boolean | false |
Treat ref/out/in parameters as allowed in the current workspace. |
codeActions.enable |
boolean | true |
Turns Roslyn code fixes on or off when available. |
telemetry |
string (off | minimal) |
minimal |
Disables telemetry entirely or limits it to anonymized usage counts. |
policyPackPaths |
string[] | [] |
Additional policy pack JSON files to merge with the bundled catalogue. Paths are resolved relative to the workspace root. |
Additional environment variables:
UDONSHARP_LINTER_SERVER_PATH: Override the bundled server executable (useful when iterating on the .NET project).UDONSHARP_LINTER_TELEMETRY: Set to0to force-disable telemetry inside the server process.
- Visual Studio Code 1.105.0 or later.
- Operating systems: Windows 10/11 (x64, arm64), macOS 12+ (Intel or Apple Silicon), Ubuntu 20.04+/Debian 11+/other glibc-based Linux (x64 or arm64).
- No separate .NET runtime is required; the extension ships self-contained binaries published from the
net8.0server project.
- Open the Extensions view in VS Code.
- Search for “UdonSharp Linter”.
- Install and reload VS Code when prompted.
- Clone this repository.
- Run
npm install(ornpm ci) to restore client dependencies. - Execute
npm run compileto build the TypeScript client. - Publish the server using the provided scripts (
DOTNET_CONFIGURATION=Release ./build_and_publish.shon macOS/Linux orDOTNET_CONFIGURATION=Release ./build_and_publish.ps1in Windows PowerShell). This populatesresources/server/<RID>/with platform-specific binaries. - Package the extension with
npx vsce packageor test a development build viacode --extensionDevelopmentPath=/path/to/repo.
The project root includes build_and_publish.sh (bash) and build_and_publish.ps1 (PowerShell) so you can publish the self-contained language server for your platform with a single command.
Policy packs are JSON documents under server/PolicyPacks that describe rule metadata, default severities, per-profile overrides, and localized documentation. At runtime:
PolicyPackLoaderscans the bundled directory and any extra paths frompolicyPackPaths.- The merged catalogue populates
PolicyRepository, which feeds severities to the Roslyn analyzers. - Rule documentation is exposed through the JSON-RPC method
udonsharp/rules/documentationand rendered inside a VS Code webview with Content Security Policy restrictions.
You can author custom packs to experiment with new diagnostics or override messaging in localized deployments.
- Server logs are stored beside the platform executable in
resources/server/<RID>/logs/(server.log,boot.log,fatal.log). - Use the VS Code Output panel (
UdonSharp Linterchannel) to inspect client-side lifecycle events. - Set
UDONSHARP_LINTER_SERVER_PATHto a localdotnet runoutput to attach a debugger during server development.
- Node.js 22.x and npm (for the VS Code client).
- TypeScript 5.9, ESLint 9 (installed via npm).
- .NET 8 SDK with the
dotnetCLI on your PATH. - VSCE (
npm install -g @vscode/vsce) for packaging, or@vscode/test-clifor tests.
| Task | Command |
|---|---|
| Compile client | npm run compile |
| Type-check client | npm run check-types |
| Lint client | npm run lint |
| Watch mode | npm run watch (runs esbuild + TypeScript) |
| Run extension tests | npm run test |
| Publish server binaries | ./build_and_publish.sh (macOS/Linux) or ./build_and_publish.ps1 (Windows); optionally set DOTNET_RIDS="linux-x64 win-x64" to limit targets |
| Package extension | npm run package (alias for npm run compile + esbuild --production) followed by npx vsce package |
The publish script builds self-contained binaries for Windows, macOS, and Linux by default and copies them into resources/server/<RID>/. Ensure these assets are committed before tagging a release.
| Symptom | Suggested Action |
|---|---|
| Status bar shows “UdonSharp: server offline” | Check server.log under resources/server/<RID>/logs/ and verify antivirus software is not blocking the bundled binary. |
| Diagnostics do not appear | Confirm the script derives from UdonSharpBehaviour. The server skips standard C# files to reduce noise. |
| Custom policy packs ignored | Ensure the JSON file includes a root rules array with id, and that the path in policyPackPaths is absolute or workspace-relative. |
| Using custom Unity stubs | Set unityApiSurface to custom-stubs and provide customStubPath. The server will load all .dll files in that directory as metadata references. |
| Developing the server | Export UDONSHARP_LINTER_SERVER_PATH=/absolute/path/to/udonsharp-lsp and run dotnet publish separately to test without repacking the extension. |
Contributions are welcome. Please open issues for bugs or rule gaps before submitting pull requests. When contributing:
- Run
npm run lint,npm run check-types, anddotnet build server/UdonSharpLsp.Server.csprojbefore committing. - Include regression scenarios or rule documentation updates when expanding analyzer coverage.
- Update
CHANGELOG.mdand this README whenever user-facing behaviour changes.
The project is licensed under the MIT License.
- File bugs and feature requests via GitHub Issues.
- For VRChat policy questions, consult the official UdonSharp documentation.
- Commercial support is not provided; please fork and adapt for bespoke moderation flows.
Thank you for using UdonSharp Linter to keep your VRChat worlds reliable and compliant.