docs: Add ADR for preset scripting language (Issue #48)
This commit is contained in:
217
docs/proposals/adr-preset-scripting-language.md
Normal file
217
docs/proposals/adr-preset-scripting-language.md
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
# ADR: Preset Scripting Language for Mainline
|
||||||
|
|
||||||
|
## Status: Draft
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
We need to evaluate whether to add a scripting language for authoring presets in Mainline, replacing or augmenting the current TOML-based preset system. The goals are:
|
||||||
|
|
||||||
|
1. **Expressiveness**: More powerful than TOML for describing dynamic, procedural, or dataflow-based presets
|
||||||
|
2. **Live coding**: Support hot-reloading of presets during runtime (like TidalCycles or Sonic Pi)
|
||||||
|
3. **Testing**: Include assertion language to package tests alongside presets
|
||||||
|
4. **Toolchain**: Consider packaging and build processes
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
|
||||||
|
The current preset system uses TOML files (`presets.toml`) with a simple structure:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[presets.demo-base]
|
||||||
|
description = "Demo: Base preset for effect hot-swapping"
|
||||||
|
source = "headlines"
|
||||||
|
display = "terminal"
|
||||||
|
camera = "feed"
|
||||||
|
effects = [] # Demo script will add/remove effects dynamically
|
||||||
|
camera_speed = 0.1
|
||||||
|
viewport_width = 80
|
||||||
|
viewport_height = 24
|
||||||
|
```
|
||||||
|
|
||||||
|
This is declarative and static. It cannot express:
|
||||||
|
- Conditional logic based on runtime state
|
||||||
|
- Dataflow between pipeline stages
|
||||||
|
- Procedural generation of stage configurations
|
||||||
|
- Assertions or validation of preset behavior
|
||||||
|
|
||||||
|
### Problems with TOML
|
||||||
|
|
||||||
|
- No way to express dependencies between effects or stages
|
||||||
|
- Cannot describe temporal/animated behavior
|
||||||
|
- No support for sensor bindings or parametric animations
|
||||||
|
- Static configuration cannot adapt to runtime conditions
|
||||||
|
- No built-in testing/assertion mechanism
|
||||||
|
|
||||||
|
## Approaches
|
||||||
|
|
||||||
|
### 1. Visual Dataflow Language (PureData-style)
|
||||||
|
|
||||||
|
Inspired by Pure Data (Pd), Max/MSP, and TouchDesigner:
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Intuitive for creative coding and live performance
|
||||||
|
- Strong model for real-time parameter modulation
|
||||||
|
- Matches the "patcher" paradigm already seen in pipeline architecture
|
||||||
|
- Rich ecosystem of visual programming tools
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
- Complex to implement from scratch
|
||||||
|
- Requires dedicated GUI editor
|
||||||
|
- Harder to version control (binary/graph formats)
|
||||||
|
- Mermaid diagrams alone aren't sufficient for this
|
||||||
|
|
||||||
|
**Tools to explore:**
|
||||||
|
- libpd (Pure Data bindings for other languages)
|
||||||
|
- Node-based frameworks (node-red, various DSP tools)
|
||||||
|
- TouchDesigner-like approaches
|
||||||
|
|
||||||
|
### 2. Textual DSL (TidalCycles-style)
|
||||||
|
|
||||||
|
Domain-specific language focused on pattern transformation:
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Lightweight, fast iteration
|
||||||
|
- Easy to version control (text files)
|
||||||
|
- Can express complex patterns with minimal syntax
|
||||||
|
- Proven in livecoding community
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
- Learning curve for non-programmers
|
||||||
|
- Less visual than PureData approach
|
||||||
|
|
||||||
|
**Example (hypothetical):**
|
||||||
|
```
|
||||||
|
preset my-show {
|
||||||
|
source: headlines
|
||||||
|
|
||||||
|
every 8s {
|
||||||
|
effect noise: intensity = (0.5 <-> 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
on mic.level > 0.7 {
|
||||||
|
effect glitch: intensity += 0.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Embed Existing Language
|
||||||
|
|
||||||
|
Embed Lua, Python, or JavaScript:
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Full power of general-purpose language
|
||||||
|
- Existing tooling, testing frameworks
|
||||||
|
- Easy to integrate (many embeddable interpreters)
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
- Security concerns with running user code
|
||||||
|
- May be overkill for simple presets
|
||||||
|
- Testing/assertion system must be built on top
|
||||||
|
|
||||||
|
**Tools:**
|
||||||
|
- Lua (lightweight, fast)
|
||||||
|
- Python (rich ecosystem, but heavier)
|
||||||
|
- QuickJS (small, embeddable JS)
|
||||||
|
|
||||||
|
### 4. Hybrid Approach
|
||||||
|
|
||||||
|
Visual editor generates textual DSL that compiles to Python:
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Best of both worlds
|
||||||
|
- Can start with simple DSL and add editor later
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
- More complex initial implementation
|
||||||
|
|
||||||
|
## Requirements Analysis
|
||||||
|
|
||||||
|
### Must Have
|
||||||
|
- [ ] Express pipeline stage configurations (source, effects, camera, display)
|
||||||
|
- [ ] Support parameter bindings to sensors
|
||||||
|
- [ ] Hot-reloading during runtime
|
||||||
|
- [ ] Integration with existing Pipeline architecture
|
||||||
|
|
||||||
|
### Should Have
|
||||||
|
- [ ] Basic assertion language for testing
|
||||||
|
- [ ] Ability to define custom abstractions/modules
|
||||||
|
- [ ] Version control friendly (text-based)
|
||||||
|
|
||||||
|
### Could Have
|
||||||
|
- [ ] Visual node-based editor
|
||||||
|
- [ ] Real-time visualization of dataflow
|
||||||
|
- [ ] MIDI/OSC support for external controllers
|
||||||
|
|
||||||
|
## User Stories (Proposed)
|
||||||
|
|
||||||
|
### Spike Stories (Investigation)
|
||||||
|
|
||||||
|
**Story 1: Evaluate DSL Parsing Tools**
|
||||||
|
> As a developer, I want to understand the available Python DSL parsing libraries (Lark, parsy, pyparsing) so that I can choose the right tool for implementing a preset DSL.
|
||||||
|
>
|
||||||
|
> **Acceptance**: Document pros/cons of 3+ parsing libraries with small proof-of-concept experiments
|
||||||
|
|
||||||
|
**Story 2: Research Livecoding Languages**
|
||||||
|
> As a developer, I want to understand how TidalCycles, Sonic Pi, and PureData handle hot-reloading and pattern generation so that I can apply similar techniques to Mainline.
|
||||||
|
>
|
||||||
|
> **Acceptance**: Document key architectural patterns from 2+ livecoding systems
|
||||||
|
|
||||||
|
**Story 3: Prototype Textual DSL**
|
||||||
|
> As a preset author, I want to write presets in a simple textual DSL that supports basic conditionals and sensor bindings.
|
||||||
|
>
|
||||||
|
> **Acceptance**: Create a prototype DSL that can parse a sample preset and convert to PipelineConfig
|
||||||
|
|
||||||
|
**Story 4: Investigate Assertion/Testing Approaches**
|
||||||
|
> As a quality engineer, I want to include assertions with presets so that preset behavior can be validated automatically.
|
||||||
|
>
|
||||||
|
> **Acceptance**: Survey testing patterns in livecoding and propose assertion syntax
|
||||||
|
|
||||||
|
### Implementation Stories (Future)
|
||||||
|
|
||||||
|
**Story 5: Implement Core DSL Parser**
|
||||||
|
> As a preset author, I want to write presets in a textual DSL that supports sensors, conditionals, and parameter bindings.
|
||||||
|
>
|
||||||
|
> **Acceptance**: DSL parser handles the core syntax, produces valid PipelineConfig
|
||||||
|
|
||||||
|
**Story 6: Hot-Reload System**
|
||||||
|
> As a performer, I want to edit preset files and see changes reflected in real-time without restarting.
|
||||||
|
>
|
||||||
|
> **Acceptance**: File watcher + pipeline mutation API integration works
|
||||||
|
|
||||||
|
**Story 7: Assertion Language**
|
||||||
|
> As a preset author, I want to include assertions that validate sensor values or pipeline state.
|
||||||
|
>
|
||||||
|
> **Acceptance**: Assertions can run as part of preset execution and report pass/fail
|
||||||
|
|
||||||
|
**Story 8: Toolchain/Packaging**
|
||||||
|
> As a preset distributor, I want to package presets with dependencies for easy sharing.
|
||||||
|
>
|
||||||
|
> **Acceptance**: Can create, build, and install a preset package
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
**Recommend: Start with textual DSL approach (Option 2/4)**
|
||||||
|
|
||||||
|
Rationale:
|
||||||
|
- Lowest barrier to entry (text files, version control)
|
||||||
|
- Can evolve to hybrid later if visual editor is needed
|
||||||
|
- Strong precedents in livecoding community (TidalCycles, Sonic Pi)
|
||||||
|
- Enables hot-reloading naturally
|
||||||
|
- Assertion language can be part of the DSL syntax
|
||||||
|
|
||||||
|
**Not recommending Mermaid**: Mermaid is excellent for documentation and visualization, but it's a diagramming tool, not a programming language. It cannot express the logic, conditionals, and sensor bindings we need.
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. Execute Spike Stories 1-4 to reduce uncertainty
|
||||||
|
2. Create minimal viable DSL syntax
|
||||||
|
3. Prototype hot-reloading with existing preset system
|
||||||
|
4. Evaluate whether visual editor adds sufficient value to warrant complexity
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- Pure Data: https://puredata.info/
|
||||||
|
- TidalCycles: https://tidalcycles.org/
|
||||||
|
- Sonic Pi: https://sonic-pi.net/
|
||||||
|
- Lark parser: https://lark-parser.readthedocs.io/
|
||||||
|
- Mainline Pipeline Architecture: `engine/pipeline/`
|
||||||
|
- Current Presets: `presets.toml`
|
||||||
Reference in New Issue
Block a user