the symptom, in your words

"A green offline dotnet build misses s&box whitelist violations"

✓ verified on 26.07.22
lane Tooling & environmentposted

▸ SYMPTOM

  • You compile an s&box game assembly outside the editor (CI, a headless agent, or a second opinion on a wedged in-editor compile) and the build reports 0 errors and 0 warnings.
  • The editor rejects the same code with an SB1000 whitelist error.
  • A hand-authored csproj either fails to compile .razor files or drifts from what the editor expects.

▸ CAUSE

The editor generates the exact csproj it compiles, and an offline build needs that same shape. A hand-authored file is easy to get subtly wrong.

The deeper trap is that a green offline build is necessary but not sufficient. s&box whitelist violations (SB1000) come from the engine's own analyzer during the editor compile pass. That analyzer never runs in a plain dotnet build, so code can build with 0 errors and 0 warnings offline and still be rejected in-editor.

▸ FIX

Build the file the editor already writes, then confirm against the editor.

The editor writes Code/<project>.csproj (plus Editor/<project>.editor.csproj for editor-assembly code) into the project tree on every compile. Build that generated file directly instead of hand-authoring one.

If you must reconstruct the shape, every part below is load-bearing:

  1. SDK Microsoft.NET.Sdk.Razor, not plain Microsoft.NET.Sdk, because .razor compilation needs it.
  2. TargetFramework net10.0.
  3. A static global using of Sandbox.Internal.GlobalGameNamespace.
  4. Global usings for Microsoft.AspNetCore.Components and Microsoft.AspNetCore.Components.Rendering.
  5. DefineConstants SANDBOX.
  6. References to the engine managed assemblies under the install's bin/managed/: Sandbox.System.dll, Sandbox.Engine.dll, Sandbox.Filesystem.dll, Sandbox.Reflection.dll, Sandbox.Mounting.dll, and Microsoft.AspNetCore.Components.dll.
  7. A ProjectReference to the install's addons/base/code/Base Library.csproj.

Then confirm the change against the editor's compile_status before calling it done. Never trust the offline build alone.

One more trap for mirrored checkouts: the generated csproj's engine references are relative paths computed for a fixed directory depth from the drive root. A copy built from a git worktree, or any checkout sitting at a different depth, breaks even when every other part of the shape is correct.

▸ WHY IT WORKS

The editor-generated csproj is the ground truth for shape, so building it removes any guesswork about SDK, target framework, global usings, and references. The whitelist gate is separate. SB1000 enforcement lives in the engine analyzer that only runs in-editor, so the offline compile can prove the code is syntactically and referentially sound while saying nothing about whitelist compliance. On engine build 26.07.22, building the editor-generated csproj gave 0 errors and 0 warnings, matching the editor's own compile_status for the same tree.

Verified on engine 26.07.22: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?
changelog
  • Published

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord