Checking your setup: sbs doctor and sbs deps
sbs doctor the environment, and every mission it can see
sbs doctor <folder> the environment, and that one mission
sbs doctor --env the environment only
sbs doctor --json machine-readable
sbs doctor --strict exit 1 if anything is flagged
What doctor is for, and what it refuses to be
Scope
Doctor answers "is this machine and this mission set up correctly". It never answers "is this content correct".
It reads story.json, __lib__.json, directory listings and file times. It does
not parse a .amd or compile a .mast - those belong to sbs lint and
sbs compile, and doctor points at them rather than growing a second opinion.
That is not fastidiousness. A report that also checks content becomes a slower linter that disagrees with the linter, and then nobody trusts either. The rule is enforced by a test that fails if doctor opens one of those files.
Doctor exits 0. A report that fails the build is a linter; --strict exists
for anyone who wants the other behavior.
Reading the output
Three statuses, in a fixed column:
| Meaning | |
|---|---|
ok |
fine |
-- |
absent, but optional - not a problem |
!! |
a problem, always followed by an indented remedy line |
Python
ok version 3.11.1 embedded (E:\Cosmos\PyRuntime\python.exe)
ok paths PYTHONPATH is ignored and site-packages is not on sys.path
use `sbs deps install X` for optional libraries
Tools
ok browser chrome 151.0.7922.76 (C:\Program Files\Google\Chrome\...)
-- weasyprint not installed - PDFs will have no contents page numbers
install the WeasyPrint package; pip alone cannot supply its GTK libraries
LegendaryMissions
!! freshness source newer than the built lib: quests
run: sbs lib LegendaryMissions
Sections: sbs (version, missions folder, running packaged or from source) -
Python - Layout (__lib__, which sbs_utils won, graphics, PyAddons,
face compositor) - Tools (git, curl, browser, weasyprint) - Sidecar - then
one per mission.
The mission checks are: story.json parses; every declared library is actually
in __lib__; no addon source is newer than its built .mastlib (the classic
"my change did nothing" - the engine reads the lib while the runner reads the
source); the packaging lists are in step; and no generated extraShipData.json
is lying around, since the library reads it back and the addon merges the same
entries again, doubling hull counts from the second run onward.
sbs deps - optional Python libraries
Why plain pip install never worked
sbs.bat is ..\..\PyRuntime\python sbs.pyz, so sbs runs on the embedded
CPython 3.11, not on your own Python. And PyRuntime/python311._pth has
import site commented out, which means:
site-packagesis never onsys.pathPYTHONPATHis ignoredpython -m pipanswers "No module named pip" - while pip is sitting right there inPyRuntime/Lib/site-packages/pip, present and invisible
So a pip install into any interpreter is invisible to sbs. That is not
friction to work around; it is the design of an embeddable distribution.
What sbs deps does instead
It puts site-packages on the path of a child process of the same
interpreter, where pip then runs normally, and installs with --target into a
folder sbs adds to sys.path at startup.
Because it is the same interpreter, pip resolves wheels against the real 3.11
ABI - no --python-version guessing, no host/embedded mismatch, and C extensions
land correctly.
sbs deps install pypdf PDF bookmarks and merged books for `sbs docs`
sbs deps list what is installed, and where
sbs deps remove pypdf
sbs deps path print the folder
Two targets, because there are two sidecars
| Target | Folder | Loaded by | Reaches |
|---|---|---|---|
| default | <missions>/__pylib__ |
sbs |
sbs docs, sbs doctor - host tooling |
--engine |
<cosmos>/PyAddons |
the engine, at startup | a running mission |
PyAddons is not new - it is where ryaml.pyd lives, and the reason ryaml is
importable inside a running mission.
sbs deps install X --engine is explicit and never the default, and asks
before it acts, because:
- A mission that imports it is no longer self-contained. Missions ship as folders and mastlibs; PyAddons is part of the install. That mission then only runs where someone ran the same command.
- It writes into the Cosmos install directory, where it can collide with what Cosmos ships.
sbs_utilsitself stays stdlib-only regardless. An engine-side optional dependency may only take the shapefs.ryaml_module()uses: silent when absent, with a working fallback.
What this cannot do
WeasyPrint is not pip-installable on Windows
pip install weasyprint succeeds and then fails at import with
cannot load library 'libgobject-2.0-0', because it needs GTK/Pango DLLs pip
has no way to supply. sbs deps install weasyprint refuses up front rather
than letting you find out later. Use the WeasyPrint Windows package instead.
Also worth knowing:
pip --targetdoes no cross-install resolution. Two separate installs can leave incompatible versions side by side without an error.- Nothing here is required. Every feature that uses an optional library degrades to working without it.