Getting Started — KN-86 Cartridge SDK
30 minutes from cold install to your first running
.kn86cartridge.
The KN-86 SDK gives you a single CLI — kn86 — that scaffolds, builds,
and runs cartridges for the Kinoshita KN-86 Deckline. This guide takes
you from zero to a “Hello, Operator” cart that paints the screen and
emits a CIPHER fragment to the auxiliary OLED.
Prerequisites
Section titled “Prerequisites”- Rust toolchain —
rustc1.75 or newer (the SDK is distributed viacargo install). Install via rustup. - The desktop emulator —
kn86emu, the SDL3 host athosts/emulator/in thekn-86monorepo. The SDK shells out to it forkn86 run. Build it from the monorepo root with:This producesTerminal window cmake -S hosts/emulator -B hosts/emulator/build && cmake --build hosts/emulator/buildhosts/emulator/build/bin/kn86emu. (Note:hosts/emulator/is currently a stub pending source population — see the repo README.) - macOS or Linux. Tested on macOS arm64 (Apple Silicon) and Linux x86_64. Windows is not supported in v0.1; use WSL2.
- SDL2 for the emulator (
brew install sdl2on macOS, or your distro’slibsdl2-devon Linux).
1. Install the SDK (one command)
Section titled “1. Install the SDK (one command)”cargo install --path sdk/tools/kn86-sdk # from a kn-86 monorepo checkoutThat installs the kn86 binary into ~/.cargo/bin. Confirm:
kn86 --version# kn86 0.1.0 (NoshAPI v1.0)The version line tells you two things: the SDK version and the
NoshAPI version that SDK pins. Cart manifests must match the major
NoshAPI version, or kn86 build rejects the build with an actionable
error.
If
kn86: command not found, ensure~/.cargo/binis on your$PATH(rustup adds this for you on most shells; checkecho $PATH).
2. Scaffold a project
Section titled “2. Scaffold a project”kn86 new hello-operatorcd hello-operatorYou’ll get this layout:
hello-operator/├── cart.toml # Manifest — identity, API version, build paths.├── src/│ └── main.lsp # Entry-point Lisp source.├── README.md # Cart-author quickstart.└── .gitignoreOpen cart.toml — every field is annotated. The cart-id is
deterministically derived from your project name (FNV-1a) so the same
name always gets the same ID; rotate it manually if you publish a cart
and need a fresh identity.
The [api].nosh-api-version = "1.0" line is your contract with the
runtime: kn86 build checks the major matches the SDK’s pinned
NoshAPI version (currently 1) and refuses to build on a mismatch.
3. Look at src/main.lsp
Section titled “3. Look at src/main.lsp”The scaffold gives you a runnable cart. Open src/main.lsp:
(register-cell-type "operator-greeting" ROOT-TYPE (fn (cell event) (if (is event 'enter) (do (text-clear) (text-puts 2 2 "KN-86 DECKLINE :: HELLO, OPERATOR") (text-puts 2 4 "Cartridge: hello-operator") ... (sfx-confirm)) (if (is event 'info) (do (cipher-emit "trace.acknowledged" "operator") (sfx-keyclick)) ...))))
(spawn-cell ROOT-TYPE)What’s happening:
register-cell-typedeclares a cell type and the lambda that handles its events. Every cart is a tree of cells; the runtime dispatches keypresses by walking from the focused cell up the tree.text-putswrites a string at(col, row)on the main grid (128×75 cells at the 1× ceiling per ADR-0036; CLAUDE.md Canonical Hardware Specification is authoritative). Rows 1–73 are yours; Row 0 (status) and Row 74 (action bar) are firmware-owned — never draw there.cipher-emitsends a CIPHER fragment to the auxiliary 256×64 OLED. CIPHER is OLED-exclusive (the Null cart is the lone exception).sfx-confirm/sfx-keyclickare pre-mixed YM2149 cues. The rawpsg-writeregister interface is also available; see the FFI reference.spawn-cellat the bottom is the cart entry — the runtime invokes top-level forms once when the cart loads, so this brings the root cell into existence.
4. Build
Section titled “4. Build”kn86 build# Built /home/you/hello-operator/build/hello-operator.kn86 (1947 bytes) [NoshAPI v1.0, VM v1.0]Under the hood, kn86 build:
- Reads
cart.toml, validates it, and verifies the NoshAPI major matches the SDK’s pinned version. - Reads
src/main.lsp. - Wraps the source in an ADR-0006 v2.0
.kn86container with an 80-byte header, a static-data END tag, and a CRC-32 checksum. - Writes it to
build/hello-operator.kn86.
The code section embeds the .lsp source verbatim (ADR-0006 Option 1,
the v0.1 launch path and current behavior) — Fe tree-walks the source on
load; there is no bytecode. Ahead-of-time Fe bytecode compilation is a
deferred future (see ADR-0004 2026-06-14 amendment); the file format
already reserves the offsets for it.
5. Run it
Section titled “5. Run it”kn86 runkn86 run locates the emulator binary in this priority order:
--emu /absolute/path/to/kn86emu$KN86_EMUenvironment variablekn86emuon$PATH
If you built the emulator from source and didn’t install it system-wide:
export KN86_EMU=/path/to/kn-86/hosts/emulator/build/bin/kn86emukn86 runYou should see the KN-86 phosphor-on-black screen (AMBER by default
per ADR-0036; the
SYS tab lets you swap to WHITE or GREEN) with your “HELLO,
OPERATOR” greeting. Press INFO to fire cipher-emit (watch the
auxiliary OLED — trace.acknowledged operator). Press BACK to exit.
6. Where to go next
Section titled “6. Where to go next”- FFI reference — every NoshAPI primitive
with signature, semantics, error modes, and an example. Auto-generated
from
docs/adr/ADR-0005-ffi-surface.md(single source of truth). Regenerate locally withkn86 docs ffi. - Reference cartridges — the launch-title carts in
carts/carts/(blackledger.lsp,icebreaker.lsp,depthcharge.lsp,neongrid.lsp) are full-feature examples spanning multi-cell hierarchies, mission phases, and CIPHER vocabularies. - Lisp paradigm —
docs/software/cartridges/authoring/lisp-paradigm.mddescribes how each of the 14 module keys (CAR,CDR,CONS,EQ,EVAL,QUOTE,INFO,BACK,NIL,ATOM, plus 4 module- specific) maps to gameplay actions. - Screen design rules —
docs/software/cartridges/authoring/screen-design-rules.mdlays out the Row 0 / Rows 1–23 / Row 24 contract.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Fix |
|---|---|
kn86: command not found | Ensure ~/.cargo/bin is on $PATH. |
cart.toml not found | Run kn86 build from the project root (where cart.toml lives). |
cart.toml nosh-api-version is X.Y, but this SDK targets v1.0 | Either bump cart.toml [api].nosh-api-version to a compatible value, or install a matching SDK version. |
could not find emulator binary kn86emu | Build kn86emu (see Prerequisites) and either put it on $PATH or set KN86_EMU. |
invalid cart name | Names must be lowercase kebab-case, 2..=31 chars: [a-z][a-z0-9-]*, no trailing dash. |
Cross-platform notes
Section titled “Cross-platform notes”- macOS arm64 (Apple Silicon) — confirmed working. SDL2 via
Homebrew (
brew install sdl2). - Linux x86_64 — confirmed working. Distro packages typically
ship
libsdl2-dev(Debian/Ubuntu) orSDL2-devel(Fedora). - Windows — not supported in v0.1. WSL2 with an X server (or WSLg on Windows 11) works as a Linux fallback.
Versioning policy
Section titled “Versioning policy”SDK v0.1.x targets NoshAPI v1.x. The promise:
- Patch bumps of the SDK never change the FFI surface.
- Minor bumps of the SDK can ship NoshAPI minor additions (new primitives, never removals or signature changes).
- Major bumps of the SDK move to a new NoshAPI major and may
break older carts. The CLI surface (
kn86 new/kn86 build/kn86 run) is independently semver’d.
See docs/software/api-reference/nosh-api/versioning.md
for the full rules.