Every sound effect in Lantern Valley is a function

· 1 min read · web-audio, game-dev, javascript, lantern-valley, audio

A cozy island scene at dusk with glowing lanterns, a game whose effects are synthesized in code

The sound effects of Lantern Valley are not files. Each one is a function that calls a small Web Audio synth, so there is nothing to download, nothing to license and nothing to re-export when a sound needs a tweak.

The toolbox #

A Synth is wired to an audio context and a bus, so the same sound can play in the game or in an offline context for auditing. The original three verbs are tone, noiseHit and voice, and everything else builds on them: bells, plucks, arpeggios.

A tone takes a frequency and an envelope (attack, decay, gain), plus a pitch slide, a detune and a stereo pan. Notes come from MIDI numbers:

const midi = (n) => 440 * Math.pow(2, (n - 69) / 12)

A registry, one file per domain #

Importing the sfx index registers every sound. There is one file per domain: player, world, UI, animals, fishing, farming, cooking, the boat, herding and more, and a new island adds its own. Sounds are looked up by name through a small registry.

Details that make it feel alive #

  • Variation per play. The engine draws a new pitch factor and volume factor for every play, so repeated sounds do not machine-gun.
  • A voice limit. The synth tracks when each source ends and can say how many are still sounding.
  • Pan by source. A sound that comes from one side goes through a stereo panner.
  • A dry path. Some sounds bypass the room reverb and go straight to the effects volume.

What it costs #

Synthesis happens at play time, so the cost is a few nodes for a few hundred milliseconds. In exchange, the audio weighs nothing in the bundle.

The saving side of the project is in the save post. The game is on its project page.

Related projects