Shoddy Documentation
Install the runtime, install the extension. Two steps, once per machine, on Windows, macOS or Linux.
The packaged extension carries its own mill — the program that compiles and runs Shoddy — and the whole machine library. So there is nothing to clone, nothing to build, and nothing to configure. Follow Track A and you are writing Shoddy in a few minutes. Track B builds the mill from source instead. Take it only if you want to work on Shoddy itself, or want the mill on your command line without VS Code.
Include finds machines/A program folder should never need its own copy of machines/.
When your program says Include "seq.shoddy"
— a bare filename, no path — the mill looks in three places, in order:
SHODDYLIB, if you have set one.
SHODDYLIB is an environment variable — a named setting
your operating system hands to every program it starts;machines/ beside the executable, then one level up beside its
bin/.That third rule is why nothing needs configuring. The mill inside the extension finds the
machines staged beside it. A mill you build yourself finds the repo’s
machines/ from bin/. Both work from any
folder on disk, with no environment variables set at all.
You normally never set SHODDYLIB. Set it only if you keep
several checkouts — separate copies of the repository — and want a program
pinned to one of them. It is no longer part of installing Shoddy. If you do set one, the
editor steps aside and lets it win.
The mill is a .NET program, so it needs the .NET runtime — the support package that
lets .NET programs run. It needs the runtime, not the much larger SDK, which is
the full developer kit. Check first with dotnet --list-runtimes.
If nothing at version 10 appears, install from
dotnet.microsoft.com, or:
winget install Microsoft.DotNet.Runtime.10
brew install --cask dotnet-runtime
Download the latest .vsix from
the latest release, then in
VS Code: Extensions view → the ··· menu →
Install from VSIX… → pick the file you downloaded. Reload when
prompted.
The release page also carries sparky — the calculator packaged as an MCP server, a plug-in that lets an AI assistant use the calculator. It is a separate, self-contained download. It needs neither this extension nor the runtime. The sparky page has the per-client registration shapes — the snippet each assistant client needs.
Use a scratch folder anywhere on disk — any throwaway folder will do. That is the real test, because it proves a program folder needs nothing of its own:
check.shoddy:
Include "stats.shoddy"
Def Main()
Print(Sum({ 1, 2, 3 }))ctrl+r) — expect 6.If step 2 reports unknown word: Sum or cannot open the include, see
Troubleshooting below.
Track B is for working on the language, the mill, or the machines — and for having
mill on your command line. Everything here replaces
Track A’s A1–A2; it is not in addition to them. A mill you build yourself takes
precedence over the extension’s bundled copy whenever the repo is your open workspace.
Check with dotnet --version. If it’s missing or older than 10,
install from dotnet.microsoft.com/download, or:
winget install Microsoft.DotNet.SDK.10
brew install dotnet-sdk
The mill is not committed to the repository, so you build it yourself from the repo root.
The verify run should print HELLO FROM SHODDY and a run of worked
examples. (What the wrapper actually runs, and why it’s a folder publish, is on the
Toolchain page.)
git clone https://github.com/shoddymills/shoddy
cd shoddy
.\build.ps1 build
bin\mill.exe run tst\examples.shoddy
git clone https://github.com/shoddymills/shoddy
cd shoddy
./build.sh build
bin/mill run tst/examples.shoddy
That is the whole setup. bin/mill finds the repo’s
machines/ one level up on its own, so bare includes work immediately
with nothing set. ./build.ps1 machines
(./build.sh machines) compiles the library to machine DLLs up
front. You can skip that: a machine is always used compiled, so the mill builds any machine
you use that is missing one anyway.
mill on your PATH OptionalThis step only lets you type mill instead of the full path to
bin/mill. PATH is the list of folders
your terminal searches when you type a command.
System Properties → Environment Variables, and append
C:\github\shoddy\bin to your user Path (safer than
setx, which rewrites the whole value).
echo 'export PATH="$HOME/github/shoddy/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc). A terminal copies the environment
variables once, when it launches, so terminals that are already open never see the
change.Machine-level symptoms — the ones that come from installs and paths, not from your program. Editor-side symptoms (F5 fails but ▶ works, millPath) are in the VS Code page’s table.
| Symptom | Likely cause |
|---|---|
“The framework Microsoft.NETCore.App version 10 was not
found” |
The .NET 10 runtime isn’t installed (step A1), or the terminal predates the install — open a new one |
unknown word: Sum (or any library word), or “cannot
open” on an Include |
A SHODDYLIB left over from an older install is pointing at a
directory that no longer holds the machines — clear it, or point it at a real
machines/ folder. With it unset, the mill finds its own |
dotnet not recognized |
Neither runtime nor SDK is installed, or the terminal predates the install |
mill not recognized (Track B) |
PATH doesn’t include the repo’s
bin, the terminal predates the change, or the mill was never built
(step B2) |
| macOS: works in one terminal but not another | The export went into a profile that shell doesn’t read
— keep it in ~/.zshrc (or
~/.zprofile for login shells) |
Next: the VS Code page — the Run button, the perch, and the tasks. Going deeper: the Toolchain page is the command-line reference; the Beginner’s Guide is the door into the language itself.