"A green offline dotnet build misses s&box whitelist violations"
▸ 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
.razorfiles 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:
- SDK
Microsoft.NET.Sdk.Razor, not plainMicrosoft.NET.Sdk, because.razorcompilation needs it. TargetFrameworknet10.0.- A static global using of
Sandbox.Internal.GlobalGameNamespace. - Global usings for
Microsoft.AspNetCore.ComponentsandMicrosoft.AspNetCore.Components.Rendering. DefineConstantsSANDBOX.- 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, andMicrosoft.AspNetCore.Components.dll. - A
ProjectReferenceto the install'saddons/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.
- Published