manifest.json. The cheat reads it first when it loads the script, and
spd build, spd publish and spd doctor check it with the same rules the market’s server uses.
Only name and version are required. Everything else has a default, so this is a complete
manifest:
spd new writes a bit more:
Fields
name, version, author, description and permissions end up on the
script global. license isn’t read: a library is published under the
spurdo! library license, and a script’s license isn’t used for anything.
An invalid field fails spd build and spd publish with the field and what’s wrong with it. An
unknown permission also fails the load in the cheat.
name
name is the key of the script everywhere: the cheat’s settings and script list, the registry and
the market. It’s a package id:
@scope/slug, lowercase letters, digits,.,_and-, up to 214 characters;- the scope is your account’s,
spd whoamiprints it.spd buildwarns while it’s still the@your-nickplaceholder, andspd publishrefuses a scope that isn’t yours; - the slug is yours to pick, and it’s the
displayNamewhen there isn’t one.
name makes it a different script: settings saved under the old one don’t follow it. Old
scripts with a free-form name are moved to a package id by spd migrate, which keeps the old name
as displayName.
On the market, displayName and description are used once: the first spd publish takes them
as the item’s name and summary. After that the item’s card is edited on the site. See
Publishing a script.
Permissions
A script withoutpermissions, or with [], gets neither. List what it needs:
spd build fails when the code imports @native/ffi and the manifest has no ffi;
spd build --fix-permissions adds it and builds again.
Manifests used to grant both permissions when
permissions was missing. They don’t anymore:
spd migrate warns about it. A version on the market that asks for ffi or filesystem, its
own or through a library, is reviewed by a moderator before buyers get it. See
Permissions and moderation.Source and entry
source is the module the bundle starts from. Without it, the first of src/index.ts,
src/index.tsx, src/index.js and src/index.jsx that exists is used. Set it only if your entry
is somewhere else; it has to be inside src/, with forward slashes.
entry is always dist/index.js: spd build writes the bundle there and the cheat loads it from
there. You can leave it out.
Workers
Workers aren’t listed in the manifest.spd build finds them in the code:
dist/index.js: src/parser.ts goes to
dist/parser.js, src/workers/zip.ts to dist/workers_zip.js, and the path in the code is
rewritten to it. Workers started by workers are found the same way. The path has to be a string
literal, relative to the file; a computed path fails the build.
A worker only has @native/fs and @native/wasi; the build warns when it imports another native
module. See Workers.
Folder layout
assets/ and load it by a path relative to the
script folder: new Font("assets/Inter.ttf"), new Texture("assets/logo.svg"). spd publish
uploads assets/, and buyers get it next to dist/, so the same path works for them.
data/ is the script’s own runtime folder. It’s never published: every buyer starts with an
empty one. A file the code loads from data/, or from any other folder of the project
(fonts/, images/), exists only on your disk, and the script fails for everyone who bought it.
spd build and spd publish warn when the code names such a file.
Imports resolve to @native/* modules and to files inside the folder; npm packages are bundled
in by spd build. There’s no node_modules at runtime.
localStorage is keyed by the folder name, not name. The script hot-reloads when any file in
its folder changes, except under data/.