ADR-0002: Player-Facing Lisp — Built-in REPL, nEmacs Structural Editor, and Lisp-Scripted Missions
Decisions recorded at sign-off:
- REPL ships launch day. Includes tutorial mode and 32-expression history.
nEmacs slips post-launch.Superseded 2026-04-24 by ADR-0016: nEmacs + REPL are unified and ship together launch-day. The original slip rationale (16 KB arena tension, limited authoring demand) was reviewed and relaxed once the REPL + nEmacs unification made the total surface area lighter than two separate subsystems.- Scripted missions are always optional on the critical path. Campaign cannot gate progression behind scripting; side-content may.
- Per-deck snippet library is in for v1.
Date: 2026-04-14
Deciders: Josh (final approval); Gameplay Design lead; Embedded Systems lead
Depends on: ADR-0001 (Lisp as sole cartridge authoring language)
Related:
KN-86-Capability-Model-Spec.md,KN-86-Lisp-Paradigm-Revisions.md,KN-86-Input-System-Architecture.md,KN-86-UI-Design-System.md
Context
Section titled “Context”ADR-0001 commits the KN-86 platform to Lisp as the substrate of cartridge authoring. A follow-on question remained open: what of the player’s relationship to Lisp? Three possibilities existed — Lisp remains invisible to the player (authoring-only), the REPL ships as a cartridge, or Lisp becomes a first-class platform affordance that the player directly interacts with.
This ADR commits to the third. Lisp is part of the device, not a cartridge. A REPL and a structural editor ship in firmware. The device teaches the player Lisp as part of its interaction language, and advanced missions can require the player to write small scripts that orchestrate across multiple capability cartridges.
The design pressure this creates — writing Lisp on a 30-key device with no keyboard — is what makes the editor a real design problem. It cannot be a character-by-character text editor. It must be a structural editor that composes s-expressions from a context-aware palette, navigated by the same CAR/CDR/CONS/EVAL/QUOTE grammar the player already uses everywhere else on the device.
Decision
Section titled “Decision”Three connected built-in capabilities ship in nOSh firmware:
1. Built-in REPL
Section titled “1. Built-in REPL”A runtime-level utility reachable from the deck home screen (alongside Mission Board, Cipher, Deck State). Presents a standard read-eval-print loop over the same VM defined in ADR-0001.
- Arena: 24 KB SRAM reserved while REPL is active; released on exit.
- FFI exposure: Full
NoshAPIplus access to read-only fields of Universal Deck State (handle, credits, reputation, cart history) for introspection. No write access to deck state from the REPL — that requires a mission context. - Tutorial mode: the REPL doubles as the platform’s Lisp tutorial. First-boot triggers a guided walkthrough (CAR/CDR navigation of a toy list, QUOTE/EVAL, first lambda). The tutorial is a sequence of REPL-pre-loaded prompts, not a separate subsystem.
- History: last 32 expressions persisted to deck state. Recalled via CDR on a history cell.
2. nEmacs — Structural Editor
Section titled “2. nEmacs — Structural Editor”A runtime-level editor for writing and editing Lisp scripts on device. Not a text editor — a structural editor over s-expression trees.
- Editing model: the program is always a well-formed tree of nodes. The player navigates (CAR = descend, CDR = next sibling, CONS = wrap-in-parent, BACK = ascend) and inserts nodes from a predictive palette. Character-by-character typing is available only for literals (numbers, strings, new identifiers) via a multi-tap scheme on a dedicated keypad overlay; this is the slow path and deliberately rare.
- Predictive palette: at every cursor position, the editor proposes the ~8 most likely next tokens based on:
- Lexical context (function position vs. argument position vs. binding position)
- Cipher domain vocabulary from currently-loaded cartridges
- Recently-used identifiers in the current buffer
- Static Lisp grammar (only legal forms at this position)
- Visual syntax: parens are rendered structurally (indentation + bracket glyphs), not as literal characters. Makes code readable on 80×25 without paren clutter.
- Storage: edit buffer lives in a dedicated 16 KB arena while editor is active. Scripts save as Lisp source to deck state, indexed by name. Per-deck, portable via deck-to-deck link.
- Execution: from the editor, EVAL runs the current top-level form against the loaded cartridge context. Errors highlight the offending node.
3. Lisp-Scripted Missions
Section titled “3. Lisp-Scripted Missions”Missions declared as requiring a script present the player with an editor buffer and an acceptance contract. The player writes a Lisp expression that must, when evaluated in the mission context, satisfy the contract.
- Use cases: multi-capability coordination missions — e.g., an intrusion mission that requires the player to write a function that, given a
(scan-result), returns a sequence of(attack ...)calls targeting the right ports in the right order. Single-cartridge missions don’t need scripting and should not use this mechanism. - Acceptance contract: expressed as a predicate in the mission template. The cartridge author supplies it; the platform evaluates. Failed acceptance shows which clause failed, scoped to help debugging without giving away the answer.
- Difficulty pacing: introduced gradually. The first scripted mission is a one-liner (apply a supplied function to an argument); later missions require composing lambdas and recursion.
- Fiction: scripted missions are diegetically framed as deep-decking — writing custom tooling against the ICE you’re breaking. This ties the Lisp-as-mechanic directly into the cyberpunk fiction.
Design Questions (to resolve via spike tasks)
Section titled “Design Questions (to resolve via spike tasks)”Editor UX
Section titled “Editor UX”- Palette rendering: 8 tokens on an 80×25 display. Visible as a persistent bottom strip? Pop-up on trigger? Which column does the editor use for indentation?
- Token-prediction ranking: static grammar + simple recency is the v1 baseline. Do we need a frequency model learned from a cart-source corpus? Likely not for launch.
- Error display: structural editor means errors are node-scoped, not line-scoped. How does the error indicator render?
- Copy/paste: within-buffer node cut-and-paste is essential. Across-buffer is desirable. Scope for v1?
Language surface
Section titled “Language surface”- Scripted-mission primitives: mission contexts expose a restricted subset of FFI. Enumerate the per-mission capability set.
- Safety: the REPL has read-only access to deck state. Scripted missions may mutate mission-local state but not global deck state unless the mission’s contract permits. Enforce at FFI layer.
- Script library: can players save and reuse snippets across missions? Per-deck snippet library stored in deck state. Useful quality of life.
Tutorial
Section titled “Tutorial”- Onboarding flow: first boot → device intro → REPL tutorial → first mission. What’s the pacing?
- Tutorial exit condition: player demonstrates CAR/CDR, EVAL, and defining a lambda. Then free play.
Consequences
Section titled “Consequences”What becomes easier
Section titled “What becomes easier”- Device identity snaps into focus. The player uses Lisp, not just keys labeled after Lisp operations.
- Scripted missions open a new gameplay axis — puzzle-solving via code composition — that no other retro handheld offers.
- Community modding story becomes concrete: modders write carts in Lisp using the same tools the player uses to write scripts.
- Tutorial cost lowers: the REPL is the tutorial.
What becomes harder
Section titled “What becomes harder”- Structural editor is a serious UX design problem. Token prediction on 30 keys with ~8 candidates is tight.
- Memory discipline: 24 KB REPL arena + 16 KB editor arena + active cart arena must coexist on 520 KB. Probable approach: REPL and editor are mutually exclusive with active cartridges (suspending the cart when entering the editor).
- Playtesting load grows — Lisp-as-mechanic is new territory, and difficulty tuning matters.
- Accessibility: Lisp is a real cognitive ask. We’ll need to decide whether scripted missions are ever mandatory on the critical path or always optional / alternate solutions exist.
What we’ll need to revisit
Section titled “What we’ll need to revisit”- If playtesting shows scripted missions are too hard, we can pull them to side-content without breaking the REPL or editor commitments.
- Token-prediction quality is a long-tail tuning problem. v1 baseline is probably fine; learned models are a post-launch investment.
Action Items
Section titled “Action Items”- Spike: Structural editor UX (Gameplay Design + UI Design, 4 days). Paper-prototype the nEmacs editor. Resolve: palette layout on 80×25, navigation grammar, literal-entry mode, indentation rendering, error display. Output: annotated mockups + interaction flow.
- Spike: Token prediction v1 ranking model (Gameplay Design, 2 days, parallel). Define the static-grammar + recency baseline. Test against a hand-coded Lisp corpus representative of launch carts. Output: ranking spec + eyeballed quality review.
- Spec: Scripted-mission primitive surface (Gameplay Design, 2 days). Enumerate the FFI subset available inside a mission script context. Define the acceptance-contract format.
- Design: REPL shell behavior (Embedded Systems, 1 day). Input handling, history persistence, tutorial mode hooks.
- Design: Memory orchestration (Embedded Systems, 1 day). When does the REPL / editor suspend an active cartridge? What’s the resume story?
- Review gate: Josh reviews all spike outputs. Sign off on committing editor and scripted-mission scope for launch vs. post-launch.
- Implementation: queued behind ADR-0001’s VM landing.
- Tutorial content: write the first-boot REPL walkthrough. Gameplay Design owns.
Open Questions for Sign-Off
Section titled “Open Questions for Sign-Off”- Scope split: are REPL + nEmacs both launch-day features, or does one (likely nEmacs) slip to post-launch? Recommendation: both launch, but with scripted-missions gated behind a content pack so we can pull it if playtesting goes poorly.
- Critical-path scripting: can a mission on the main campaign path require scripting, or is scripted content always optional / alternate? My vote: always optional in the main campaign; side-content can require it. This preserves accessibility.
- Per-deck snippet library: yes for launch, or post-launch? Cheap to build, high quality-of-life — I’d vote yes for launch.