MEGAPOST

· Sam

How the sounds of Pebble Bay are made - Part 1: Synthesis

Every sound you hear in Pebble Bay is generated in game, while you play. I'm going to explain how this works, how the effects are built from a few simple ingredients, and what that buys over audio files.

I even added some interactive synth stuff for you to play with (Thanks Claude!)

I make house and acid techno, so the obvious move was to write the soundtrack in Ableton and export it as audio files. However, when I realised you can synthesise sounds in-game I was curious as to how it might come out sounding compared to the more expensive VSTs I have access to in Ableton.

The result of this is that there isn't a single audio file in the game. All of the sound code together is 14 KB; the same sounds as audio files would be roughly 3 MB. That's not a huge deal on phones with lots of storage, but it means the web version has nothing to download before the first sound, and it sounds cool.

I used AI pretty heavily throughout development: it wrote the audio code, which let me go deep on fine tuning the actual sounds quickly without getting hung up on (and bored by) the JavaScript audio code.

How the effects are synthesised

There are three raw ingredients in the file, and everything is built from them:

  • tone: one oscillator with a very fast attack and an exponential decay. It can start slightly sharp and settle (a mallet hitting a bar) or glide to another pitch (a pop, a plop).
  • hiss: two seconds of white noise through a filter, with its own volume shape and an optional filter sweep. Snow, splashes, paper and whooshes are all this.
  • held: a sustained note with a slow swell (pads, the ship's horn), optionally with vibrato and a pitch scoop.

Try it: build a hand bell from five sine waves

A real bell's overtones aren't neat multiples of the note, which is what makes it sound like metal. The game's bell is five pure tones at 1, 2, 2.76, 5.4 and 8.93 times the note, each fading faster than the one below. Untick partials to hear it fall apart: one alone is a plain beep.

Interactive: tick boxes for the five partials. It works on the live page; the edit copy only shows this note.

The seven instruments, one note each

Interactive: a play button for each of the seven instruments. It works on the live page; the edit copy only shows this note.

Marimba: the note plus its 4th overtone (3.93×) for a moment, plus a 14 ms tap of noise for the felt mallet. Kalimba: the note, a bright clang at 5.95× that dies at once, and a soft octave. Pad: two triangle waves 12 cents apart under a 900 Hz low-pass, so they gently beat against each other.

Effect recipes

Interactive: twelve effect recipe cards, each with a play button. It works on the live page; the edit copy only shows this note.

Take an effect apart

Interactive: the mini synth: layer switches, sliders and a live spectrogram for collect, place, horn, hello and bubbles. It works on the live page; the edit copy only shows this note.

A spectrogram of exactly what plays: time runs left to right, pitch goes up, brighter is louder. It redraws as you change a setting.

Things a file can't do

Interactive: buttons that play the same effect several times, so you can hear it change. It works on the live page; the edit copy only shows this note.


How it works in the game

Game eventscollected, built, levelUp… Event → sound namea lookup table, 50 events Per batch ruleseach sound once, small onesgive way, collects cascade Song datanotes on an eighth-note grid Schedulerevery 100 ms, books next 0.3 s 2.5 s crossfade when the song changes Ambience loopswind, sea, aurora, made at start Live mixtime of day, distance to shore + a gull or an ice creak every 14 to 30 s Effects bus0.8 Music bus0.33 Ambience bus1.0 Compressor−12 dB, 4:1 Soft ceiling−1.3 dBFS Speaker
Three kinds of sound, three buses, one safety chain. The music bus is 0.6 × 0.55 at default settings, so music sits about 8 dB under the effects. Nothing can clip: the compressor catches pile-ups and a tanh curve rounds off anything left above −1.3 dBFS.
  • Effects come from the simulation. The sim returns events (collected, built, shipIn…) and a lookup table turns each into a sound name. Per batch each sound plays once; smaller sounds give way to bigger ones beside them (no pebble clink under a level-up fanfare); collecting several things plays a cascade of up to six notes, each two semitones higher. The same sound can't retrigger within 45 ms.
  • The music follows the clock. A Pebble Bay day is 20 real minutes. The day loop plays for about 15.5 of them (around 35 passes of 26.7 s), the night loop for about 4. The Feast tune takes over for Feast Day and the finale. Switches crossfade over 2.5 s, and day and night use different thresholds so dusk doesn't flip back and forth.
  • The ambience follows the camera. The wind is always there and gets louder at night. The sea gets louder the closer the camera is to the shore. A shimmering chord (the "aurora") fades in only at night. Gulls call by day and the sea ice creaks at night, every 14 to 30 seconds, panned left or right at random.

Why I chose code instead of audio files

  1. Variation for free. Random grains and pitches mean the 500th footstep isn't the same recording again (the "machine gun" effect that makes repeated samples grate).
  2. Sounds can react to the game. Pitch, length, direction and pan are parameters, so the collect cascade, skid and bubbles change with what's happening. In the future I feel like I could take this much farther and do more interesting and unique stuff.
  3. Seamless loops by construction. The ambience loops are generated with their last half second crossfaded into the start. The aurora chord snaps every frequency to a whole number of cycles per 16 s loop, so it joins with zero click. Still achievable in Ableton with audio files but thought it was cool.
  4. Change one number, hear it. Retuning the horn or slowing the night loop is a one-line edit, not a re-render and re-export.

The honest downsides

  • The biggest limitation here is there are no real voices, no rich acoustic instruments, and there's no reverb in the chain at all (the long decays do that job). However I found operating in such strict limitations helped me focus and get a bit more creative.
  • Designing sounds by typing numbers is slower than turning knobs in a DAW.
  • Could be an issue with very low-end Android phones in terms of the sound queues and scheduler.

Usually when I make tracks I have access to much more complex synths and effects in Ableton. Limiting this to more basic synthesis made me see synthesis from a new perspective.

In Part 2 I'll get into the music theory of the game: why a 26 second loop can play 35 times in a row without wearing thin. If you'd like to join the playtest group pop me a message at sam@megapost.ai :)

← All posts