lantern

sprout-garden-sound-engine

Sprout Garden: Sound Engine

The garden plays music. Strudel makes it happen.

The Vision

The garden isn't just accompanied by music - the garden IS the composition.

  • Sprouts flowing through plots = notes triggering
  • Loops = rhythmic patterns
  • Parallel paths = polyphony
  • Transforms = timbral changes
  • The visualization IS the sequencer

Strudel Integration

Strudel is TidalCycles for the browser - live coding music through patterns. It's the perfect audio engine for Sprout Garden because both are fundamentally about patterns.

Why Strudel?

Feature Benefit
Browser-native No installation, works in same context as game
Pattern-based Same mental model as garden flow
Web Audio API High performance, low latency
TidalCycles heritage Battle-tested pattern language
Open source Can embed and extend

The Mapping

Garden Event          →  Strudel Pattern
─────────────────────────────────────────
Sprout enters plotNote triggers
Plot type             →  Sound/instrument
Sprout color          →  Pitch or filter
Sprout shape          →  Sample or synth
Loop iteration        →  Pattern cycle
Fork (1→many)         →  Chord / polyphony
Grafter (many→1)      →  Note cluster
Tick                  →  Beat subdivision

Example Flow

Garden path:

🌱 → → ⚙️ → → 🎨 → → 🎯

Strudel pattern equivalent:

s("spring:emit vine vine gear:transform vine vine bloom:transform vine harvest:arrive")
  .sound("piano")
  .scale("C:pentatonic")

Each plot type maps to a note in the scale. The sequence of plots = the melody.

Architecture

Option 1: Event-Driven

Garden emits events, Strudel plays them:

// Garden simulation emits
garden.on('sprout:enter', (sprout, plot) => {
  strudel.trigger({
    sound: plotSounds[plot.type],
    note: colorToNote[sprout.color],
    duration: '8n'
  });
});

garden.on('sprout:transform', (sprout, before, after) => {
  strudel.trigger({
    sound: 'transform',
    note: shapeToNote[after.shape],
    fx: 'filter:sweep'
  });
});

Option 2: Pattern Generation

Garden generates Strudel pattern strings:

function gardenToPattern(path) {
  const notes = path.map(step => plotToNote(step.plot));
  return `s("${notes.join(' ')}")`;
}

// Execute the pattern
strudel.repl(gardenToPattern(sprout.lineage));

Option 3: Hybrid (Best)

  • Background pad: Strudel pattern loops based on garden structure
  • Event triggers: Individual sounds on sprout events
  • Generative: Pattern evolves as garden changes
// Background: garden structure → looping pattern
const backgroundPattern = generateBackgroundPattern(garden);
strudel.repl(backgroundPattern);

// Events: sprout movement → triggers
garden.on('tick', (sprouts) => {
  for (const sprout of sprouts) {
    triggerSproutSound(sprout);
  }
});

Sound Design

Plot → Sound Mapping

Plot Sound Character
Spring 🌱 Pluck/bell Beginning, bright
Vine → Quick blip Movement, passing
Form Grower ⚙️ Mechanical click + tone Transformation
Color Bloomer 🎨 Chime/shimmer Color = pitch
Delay ⏱️ Sustained pad Held note
Gate 🚧 Pass: ding / Block: thunk Success/fail
Fork ⑂ Chord (split) One becomes many
Grafter ⊕ Resolution chord Many become one
Harvest 🎯 Resolution/arrival Completion

Color → Pitch

Color Note Feeling
Red 🔴 C Root, grounded
Green 🟢 E Third, warmth
Blue 🔵 G Fifth, open
Yellow 🟡 A Sixth, bright

Pentatonic - can't hit a wrong note.

Shape → Instrument/Timbre

Shape Instrument Texture
Circle ● Sine/pad Smooth, round
Square ■ Square wave Edgy, digital
Triangle ▲ Triangle wave Hollow, flute-like
Star ★ Bell/pluck Bright, sparkly

Loop → Rhythm

A loop in the garden creates a rhythmic pattern:

  ⊕ → ⚙️ → 🎨 → ❓
  ↑               ↓
  └───────────────┘

This is literally a musical loop. Each iteration = one bar/cycle.

Strudel pattern:

s("merge gear bloom check").loop()

Soundpacks

Same garden, different vibes:

Pack Aesthetic Use Case
Cartoon Boings, bloops Fun, kids
Chiptune 8-bit Retro game
Glass Crystal bells Ambient, calm
Nature Water, birds Zen garden
Synth Analog pads Focus mode
Orchestra Strings, woodwinds Elegant
Techno Kicks, hats Daddy mode 🎧

Switch soundpack = same garden plays different genre.

Implementation Path

Phase 1: Basic Triggers

  • Load Strudel as dependency
  • Map plot types to sounds
  • Trigger on sprout events
  • Volume/mute control

Phase 2: Generative Background

  • Generate pattern from garden structure
  • Background pad based on garden "shape"
  • Tempo tied to tick rate

Phase 3: Full Integration

  • Garden edits = pattern edits (live coding!)
  • Export garden as Strudel pattern
  • Import Strudel pattern as garden (!)
  • Visualize sound patterns as garden paths

Phase 4: The Reverse

Parse Strudel patterns into gardens.

s("bd sd bd sd")

Becomes:

🌱 → 🔵 → 🟢 → 🔵 → 🟢 → 🎯
      kick  snare kick  snare

The pattern IS the garden. The garden IS the pattern.

Research Links

The Dream

A kid builds a garden. The garden plays music. They don't know they're composing.

An adult builds a workflow. The workflow plays music. They debug by ear.

A musician plays music. The music draws gardens. They compose visually.

Same thing. Different entry points.

🌱 = 🎵 = 🚂 = 📊

Tags

sprout-garden, sound-design, strudel, tidalcycles, generative-music, live-coding, web-audio

Slots

North

slots:
- sprout-garden

South

slots: []

East

slots: []

West

slots: []
↑ northsprout-garden