Skip to content

plonk ​

Game music made in code. A song is a few hundred bytes of text: instruments and patterns of notes, synthesized live with Web Audio. The whole engine is about 2 kB brotli. One compressed music loop is usually 300 kB to 1 MB, so a plonk soundtrack is smaller than a single track and starts playing with nothing to download.

ts
import { Player } from "plonkjs";

new Player().play({
  bpm: 112,
  instruments: { lead: { wave: "square", decay: 0.15, sustain: 0.3, echo: 0.3 } },
  sections: { a: { lead: "C5 . E5 G5 . E5 C5 . | D5 . F5 A5 . F5 D5 ." } },
  order: ["a"],
});

Get started · Songs and patterns · Playground · API reference

Why plonk ​

  • Tiny. About 2 kB brotli for the engine, plus a few hundred bytes per song. gloop, our match-3 game for Poki, added 2.2 kB to its build for its whole soundtrack.
  • Music that reacts. Change the tempo without a jump, and fade single tracks in and out: drop the drums on a menu, speed up when time runs low.
  • Text you can edit. "C5 . E5 G5" is a melody, "x . . ." is a kick drum. People and coding agents can write and change songs directly.
  • Any engine. Phaser, PixiJS, three.js, KAPLAY, Excalibur, a hand-written loop or debuff. Give it the engine's audio context and it shares its volume and mute.
  • Testable without speakers. notes() turns a song into data, so tests and agents can check music they can't hear.

What it sounds like ​

plonk makes synth music: square, sawtooth, triangle and sine waves, filtered noise for drums, envelopes, a resonant filter that can sweep on every note, detuned unison, vibrato and a tempo-synced echo. Think chiptune with a few modern touches. Try the playground to hear it and edit a song live.

It isn't a replacement for a recorded orchestral score, and it doesn't play audio files.