Summary
Add in-browser, generative music using Strudel (the JavaScript port of TidalCycles). The Strudel wrapper and music logic live in a new @webgamekit/music package, consumed by a new Music panel and by the existing RhythmGame (which gains a complex Strudel song as a playable track).
Motivation
- A reusable, framework-agnostic music engine the whole app can use (panels, games, visual sync).
- A live, generative "Music" panel for experimenting with patterns.
- A richer RhythmGame: drive a chart from a complex Strudel song instead of only MIDI files.
Scope
1. New package @webgamekit/music (packages/music)
- Wrap
@strudel/web (verify maintenance/license before adding): musicInit, musicPlay(pattern), musicStop, musicSetTempo, and an event hook (musicOnTrigger) so consumers can react to each note/hap with its time.
- Framework-agnostic (no Vue/React). Exported functions use the
music* prefix. Types in a dedicated types.ts.
- A library of named example patterns, including at least one complex song for the RhythmGame.
- Pure helpers (pattern building, hap→note-event mapping) unit-tested; audio init guarded so tests run without an AudioContext.
2. Music panel
- Add
'music' to PanelType + the right-panel order in src/stores/panels.ts.
src/components/panels/MusicPanel.vue + src/composables/useStrudel.ts (lifecycle: init once, play/stop, dispose on unmount; no module-level refs).
- Controls: pattern field, play/stop, tempo, preset patterns; reuses existing
ui/ components.
3. RhythmGame integration (extend, do not duplicate)
- Add a Strudel track source to
RhythmGame alongside MIDI: a complex @webgamekit/music song produces note events (via the audio scheduler) that feed the existing chart, scoring, lobby, summary, and multiplayer.
Acceptance criteria
References
- Strudel: https://strudel.cc ,
@strudel/web
- Existing:
packages/audio/ (scheduler), src/views/Games/RhythmGame/, src/stores/panels.ts
Summary
Add in-browser, generative music using Strudel (the JavaScript port of TidalCycles). The Strudel wrapper and music logic live in a new
@webgamekit/musicpackage, consumed by a new Music panel and by the existing RhythmGame (which gains a complex Strudel song as a playable track).Motivation
Scope
1. New package
@webgamekit/music(packages/music)@strudel/web(verify maintenance/license before adding):musicInit,musicPlay(pattern),musicStop,musicSetTempo, and an event hook (musicOnTrigger) so consumers can react to each note/hap with its time.music*prefix. Types in a dedicatedtypes.ts.2. Music panel
'music'toPanelType+ the right-panel order insrc/stores/panels.ts.src/components/panels/MusicPanel.vue+src/composables/useStrudel.ts(lifecycle: init once, play/stop, dispose on unmount; no module-level refs).ui/components.3. RhythmGame integration (extend, do not duplicate)
RhythmGamealongside MIDI: a complex@webgamekit/musicsong produces note events (via the audio scheduler) that feed the existing chart, scoring, lobby, summary, and multiplayer.Acceptance criteria
@webgamekit/musicbuilds, is published via barrel exports, and has unit tests for its pure helpers.pnpm test:unitandpnpm lintpass.References
@strudel/webpackages/audio/(scheduler),src/views/Games/RhythmGame/,src/stores/panels.ts