Monorepo for Aesthetic.Computer
aesthetic.computer
1# KidLisp Multi-Platform Learning Books
2
3## Overview
4
5Transform kidlisp.com into a multi-platform learning environment where users can learn KidLisp through different "runtime targets" — each with its own API surface and interactive book.
6
7## Architecture
8
9```
10┌─────────────────────────────────────────────────────────────────┐
11│ kidlisp.com │
12├─────────────────────────────────────────────────────────────────┤
13│ Header: Logo | [Aesthetic.Computer ▼] | @user | Keeps | Book │
14│ │ │
15│ ├─► Aesthetic.Computer (default) │
16│ ├─► Teenage Engineering Playdate │
17│ └─► FF1 Art Computer │
18├─────────────────────────────────────────────────────────────────┤
19│ ┌──────────────────┐ ┌──────────────────────────────────────┐ │
20│ │ │ │ │ │
21│ │ Code Editor │ │ Preview / Iframe │ │
22│ │ (Monaco) │ │ (platform-specific) │ │
23│ │ │ │ │ │
24│ └──────────────────┘ └──────────────────────────────────────┘ │
25└─────────────────────────────────────────────────────────────────┘
26```
27
28## Tab Renaming
29
30| Old Name | New Name | Purpose |
31|----------|----------|---------|
32| Code | **Book** | Platform-specific learning content (paginated, Little Schemer style) |
33
34## Platform Configurations
35
36### 1. Aesthetic.Computer (Default)
37
38**Runtime:** Browser-based, WebGL canvas, real-time
39**Preview:** `https://aesthetic.computer/$code?noauth=true` iframe
40**Book:** "KidLisp on Aesthetic.Computer"
41**API Surface:**
42- `wipe`, `ink`, `line`, `box`, `oval`, `plot`
43- `width`, `height`, `now`, `frame`
44- `tap`, `pan`, `draw`, `lift`
45- `repeat`, `later`, `def`
46- Audio: `synth`, `sample`
47- Networking: realtime multiplayer
48
49**Code State:** Editable, saves to AC backend, can be "kept" as NFT
50
51### 2. Teenage Engineering Playdate
52
53**Runtime:** Lua-based, 1-bit 400×240 display, crank input
54**Preview:** Playdate Simulator view (or mock)
55**Book:** "KidLisp for Playdate"
56**API Surface (KidLisp → Playdate mapping):**
57```lisp
58; KidLisp → Playdate Lua
59(wipe) → gfx.clear()
60(ink "white") → gfx.setColor(gfx.kColorWhite)
61(box x y w h) → gfx.fillRect(x, y, w, h)
62(line x1 y1 x2 y2) → gfx.drawLine(x1, y1, x2, y2)
63(crank) → playdate.getCrankPosition()
64(a-button) → playdate.buttonIsPressed(playdate.kButtonA)
65(d-pad) → playdate.buttonIsPressed(...)
66```
67
68**Constraints:**
69- 1-bit color only (black/white)
70- 400×240 fixed resolution
71- 30 FPS default (max 50)
72- Crank as unique input
73
74**Code State:** Editable, exports to `.pdx` bundle
75
76### 3. FF1 Art Computer (Feral File)
77
78**Runtime:** FF OS, Linux-based, WebGL/WebAssembly, DP-1 protocol
79**Preview:** Mock FF1 display frame or actual kept piece (read-only from IPFS)
80**Book:** "KidLisp for FF1"
81**API Surface:** Same as Aesthetic.Computer (both WebGL) + DP-1 specific:
82```lisp
83; DP-1 playlist integration
84(playlist-info) → current playlist metadata
85(artwork-info) → current artwork metadata
86(display-info) → screen resolution, orientation
87```
88
89**Kept Pieces Integration:**
90- When a piece is "kept" on AC, it gets IPFS URL
91- FF1 can play any kept piece via DP-1 protocol
92- In FF1 mode, can browse your kept collection
93- Code becomes **read-only** (viewing the immutable IPFS version)
94
95**Code State:** Read-only when viewing kept pieces from IPFS
96
97### 4. Ableton Live (Max for Live)
98
99**Runtime:** Max for Live devices in Ableton Live
100**Preview:** Device parameter mock / Live connection
101**Book:** "KidLisp for Ableton"
102**Existing Work:** `ac-m4l/` — AC Metronome, AC Notepat, AC Prompt devices
103
104**API Surface (KidLisp → Max/MSP mapping):**
105```lisp
106; MIDI output
107(note pitch velocity duration) → noteout
108(cc controller value) → ctlout
109(bend value) → bendout
110
111; Timing / Transport
112(beat) → current beat position
113(tempo) → live.tempo
114(bar) → bar number
115(playing?) → transport state
116
117; Audio (via buffer~)
118(sample name) → buffer~ playback
119(synth freq amp) → cycle~ / saw~ etc.
120
121; Live parameters
122(param name value) → live.remote~
123(track-info) → live.path / live.object
124```
125
126**Constraints:**
127- Real-time audio thread (no blocking!)
128- MIDI timing critical
129- Works within Ableton's timeline/session view
130- Device UI limitations (Max for Live patcher)
131
132**Code State:** Editable, exports to `.amxd` device
133
134### 5. Game Boy (GBDK) — 🔒 Coming Soon
135
136**Runtime:** GBDK-2020 C compiler → Game Boy ROM
137**Preview:** Emulator (BGB/mGBA)
138**Book:** "KidLisp for Game Boy"
139**Existing Work:** `kidlisp-gameboy/` — Compiler in progress
140
141**API Surface:**
142```lisp
143; 160×144, 4 colors (2-bit)
144(wipe) → cls()
145(ink 0-3) → set drawing color
146(sprite id x y) → move_sprite()
147(tile x y id) → set_bkg_tile()
148(joypad) → joypad() buttons
149(sound ch freq) → NR registers
150```
151
152**Constraints:**
153- 160×144 resolution, 4 shades of green
154- 8KB VRAM, limited sprites (40 max, 10 per line)
155- No floating point!
156- Sound: 4 channels (2 pulse, 1 wave, 1 noise)
157
158**Code State:** Editable, exports to `.gb` ROM
159
160### 6. Nintendo 64 — 🔒 Experimental
161
162**Runtime:** libdragon / N64 homebrew
163**Preview:** Emulator (Ares/simple64)
164**Book:** "KidLisp for N64"
165**Existing Work:** `kidlisp-n64/` — Early experiments
166
167**API Surface:**
168```lisp
169; 320×240 or 640×480
170(wipe color) → rdp_fill_rectangle
171(box x y w h) → rdp primitives
172(sprite id x y) → rdp_draw_sprite
173(3d-tri ...) → RDP triangle commands
174(controller port) → controller_scan()
175```
176
177**Constraints:**
178- RDP (Reality Display Processor) rendering
179- 4MB RAM (8MB with expansion pak)
180- 4 controller ports
181- N64 controller: analog stick, C-buttons, Z-trigger
182
183**Code State:** Editable, exports to `.z64` ROM
184
185## Book Structure (per platform)
186
187Each platform's book follows the "Little Schemer" style:
188
189```
190┌─────────────────────────────────────────┐
191│ KidLisp on [Platform] │
192│ │
193│ Chapter 1: Drawing │
194│ ───────────────────────────── │
195│ │
196│ What does this do? │
197│ │
198│ (wipe "blue") │
199│ (ink "yellow") │
200│ (box 10 10 50 50) │
201│ │
202│ [Try it →] │
203│ │
204│ ◄ 1/24 ► │
205└─────────────────────────────────────────┘
206```
207
208### Book Content Format (JSON/Markdown)
209
210```json
211{
212 "platform": "aesthetic-computer",
213 "title": "KidLisp on Aesthetic.Computer",
214 "chapters": [
215 {
216 "title": "Drawing",
217 "pages": [
218 {
219 "question": "What does this do?",
220 "code": "(wipe \"blue\")\n(ink \"yellow\")\n(box 10 10 50 50)",
221 "answer": "It clears the screen blue, then draws a yellow box.",
222 "tryIt": true
223 }
224 ]
225 }
226 ]
227}
228```
229
230### Book Storage Location
231
232```
233system/public/kidlisp.com/books/
234├── aesthetic-computer.json
235├── ableton.json
236├── playdate.json
237├── ff1.json
238├── gameboy.json
239└── n64.json
240```
241
242## Implementation Plan
243
244### Phase 1: UI Restructuring
245- [ ] Rename "Code" tab to "Book"
246- [ ] Add platform dropdown to preview header (next to "Aesthetic.Computer")
247- [ ] Store selected platform in localStorage
248- [ ] Platform change triggers:
249 - Book content swap
250 - Preview iframe URL change (future)
251 - API reference update (future)
252
253### Phase 2: Book Viewer
254- [ ] Create paginated book component
255- [ ] Load book JSON based on platform
256- [ ] "Try it" button loads code into editor
257- [ ] Page navigation (prev/next, chapter jump)
258- [ ] Progress tracking (localStorage)
259
260### Phase 3: Aesthetic.Computer Book
261- [ ] Write initial chapters:
262 1. Drawing (wipe, ink, box, line, oval)
263 2. Animation (frame, now, sim)
264 3. Interaction (tap, draw, pan)
265 4. Variables (def)
266 5. Loops (repeat)
267 6. Time (later, 0.5s)
268 7. Sound (synth, sample)
269 8. Making a Game
270
271### Phase 4: FF1 Integration
272- [ ] "Kept Pieces" browser in FF1 mode
273- [ ] Load piece from IPFS URL
274- [ ] Read-only code editor mode
275- [ ] Display IPFS/NFT metadata
276
277### Phase 5: Playdate Integration
278- [ ] KidLisp → Playdate Lua transpiler (see `kidlisp-gameboy/compiler/`)
279- [ ] Playdate simulator mock (or WebAssembly sim)
280- [ ] Playdate-specific book content
281- [ ] Export to `.pdx` functionality
282
283### Phase 6: Ableton Integration
284- [ ] KidLisp → Max/MSP JavaScript transpiler
285- [ ] Live device preview / parameter mock
286- [ ] Ableton-specific book content (MIDI, timing, audio)
287- [ ] Export to `.amxd` device
288
289### Phase 7: Retro Consoles (Game Boy, N64)
290- [ ] KidLisp → C transpiler for GBDK/libdragon
291- [ ] Emulator embeds for preview
292- [ ] Platform-specific books
293- [ ] Export to ROM files
294
295## Technical Notes
296
297### Platform Detection State
298
299```javascript
300const platforms = {
301 'aesthetic-computer': {
302 name: 'Aesthetic.Computer',
303 icon: '🟪',
304 previewUrl: (code) => `https://aesthetic.computer/${code}?noauth=true`,
305 bookPath: '/books/aesthetic-computer.json',
306 editable: true,
307 runtime: 'browser',
308 status: 'active'
309 },
310 'ff1': {
311 name: 'FF1 Art Computer',
312 icon: '🖼️',
313 previewUrl: (ipfsUrl) => ipfsUrl, // From kept piece
314 bookPath: '/books/ff1.json',
315 editable: false, // Read-only for kept pieces
316 runtime: 'browser',
317 status: 'active'
318 },
319 'ableton': {
320 name: 'Ableton Live',
321 icon: '🎹',
322 previewUrl: null, // Device mock
323 bookPath: '/books/ableton.json',
324 editable: true,
325 runtime: 'max-js-transpile',
326 status: 'active'
327 },
328 'playdate': {
329 name: 'Playdate',
330 icon: '🎮',
331 previewUrl: null, // Custom renderer
332 bookPath: '/books/playdate.json',
333 editable: true,
334 runtime: 'lua-transpile',
335 status: 'coming-soon'
336 },
337 'gameboy': {
338 name: 'Game Boy',
339 icon: '👾',
340 previewUrl: null, // Emulator embed
341 bookPath: '/books/gameboy.json',
342 editable: true,
343 runtime: 'gbdk-c-transpile',
344 status: 'coming-soon'
345 },
346 'n64': {
347 name: 'Nintendo 64',
348 icon: '🕹️',
349 previewUrl: null, // Emulator embed
350 bookPath: '/books/n64.json',
351 editable: true,
352 runtime: 'libdragon-c-transpile',
353 status: 'experimental'
354 }
355};
356```
357
358### FF1 Kept Piece Loading
359
360```javascript
361async function loadKeptPiece(codeId) {
362 // Fetch piece metadata from AC API
363 const meta = await fetch(`/api/piece/${codeId}`);
364 const { ipfsUrl, title, artist } = await meta.json();
365
366 // Load code from IPFS (read-only)
367 const code = await fetch(ipfsUrl).then(r => r.text());
368
369 // Set editor to read-only mode
370 editor.updateOptions({ readOnly: true });
371 editor.setValue(code);
372
373 // Update preview with IPFS-hosted version
374 updatePreview(ipfsUrl);
375}
376```
377
378## Open Questions
379
3801. **Playdate Simulation:** Should we build a web-based Playdate simulator, or just show static preview + export?
381
3822. **Cross-Platform Pieces:** Can a piece be written once and run on multiple platforms with graceful degradation?
383
3843. **Book Editing:** Should there be an admin interface to edit book content, or just JSON files in repo?
385
3864. **FF1 Live Connection:** Could kidlisp.com connect directly to a user's FF1 via DP-1 for live preview?
387
388## References
389
390- [Playdate SDK Documentation](https://sdk.play.date/)
391- [FF1 Art Computer](https://feralfile.com/install)
392- [DP-1 Protocol](https://github.com/display-protocol/dp1)
393- [The Little Schemer](https://mitpress.mit.edu/9780262560993/the-little-schemer/) (book format inspiration)
394- [KidLisp Interpreter](/workspaces/aesthetic-computer/kidlisp/)