"Hand-vendored library without an .sbproj is silently skipped"
▸ SYMPTOM
A hand-vendored library placed under Libraries/ compiles with no errors in an offline dotnet build, but the game code fails the editor compile with a wall of CS0246 ("type or namespace not found") on every type the library defines. The library's own code never appears in compile_status at all, as though it does not exist.
▸ CAUSE
Library discovery runs at project load (LibrarySystem.InitializeFromProject in the engine's Sandbox.Tools). Each subfolder of Libraries/ is admitted only if it contains exactly one *.sbproj file. Zero files (the hand-vendored case) or two or more files both cause the folder to be silently skipped, with no warning and no log line.
A skipped folder never becomes a library project, so the game compiler receives no reference to it. The CS0246 errors are not about missing code; the library's code is present on disk but was never offered to the compiler.
Library Manager installs get their .sbproj from the package pipeline, which is why only hand-vendored or manually copied libraries hit this.
▸ FIX
Add a minimal library-type project file to each vendored folder, matching the engine's library.minimal template:
{
"Title": "My Library",
"Type": "library",
"Org": "my-org",
"Ident": "my-library",
"Schema": 1
}Two sharp edges:
- Discovery runs only at project load. Adding the
.sbprojunder a live editor does nothing until the project is closed and reopened. A hot recompile does not rescanLibraries/. - Offline
dotnet buildcannot catch a missing.sbproj. It compiles the library source directly via the csproj and does not simulate the editor's discovery logic. A green offline build does not prove the editor will find the library.
Once discovered, the game auto-references every loaded library with a code path. No PackageReferences entry is needed for local libraries.
▸ WHY IT WORKS
The .sbproj file signals to the engine's library system that the folder is a valid library project. With exactly one project file present, AddFromFolder registers it as a library, compiles its code, and exposes its types to the game project. Without the file, the folder is structurally invisible to the discovery scan.
- Published