How to use the Sound Lab
The Sound Lab is the audio engine behind SpecEnvoy Games, opened up as an instrument. Nothing in it is a recording — every instrument, effect and piece of music is synthesized from code, on the spot, in your browser. This page is the manual: the six panels, the export formats, and how a game adopts a sound you made.
The one idea everything builds on
Every sound here is deterministic: the same settings and the same seed (a whole number) always produce exactly the same sound — today, next year, in any game. A seed is like a recipe number. So "a sound you designed" is never a file you have to keep; it's a tiny description (preset + parameters + seed, or style + seed for music) that any of our games can replay perfectly. That's why the export buttons give you JSON (the description) as well as WAV (the rendered audio, for listening anywhere).
The six panels
1 · Instruments
Pick any of the 26 instruments, then play the on-screen keyboard — or your computer keyboard: white keys on A S D F G H J K, sharps on W E T Y U, octave down/up on Z / X. The velocity slider is how hard you play: it changes brightness and attack, not just loudness — that's most of what makes these sound like instruments instead of beeps.
2 · Drums
A twelve-piece synthesized kit. Tap the pads; each hit varies slightly, like a drummer.
3 · Effects
The 40 named presets are the sounds our games actually use — punches, gunfire, explosions, sci-fi zaps, footsteps, interface sounds. Selecting one reveals its generator's parameters as sliders (size, sharpness, distance, metallic…). Move them and press play; press 🎲 New seed to hear natural variation of the same design.
- ⬇ WAV downloads the audio you're hearing.
- ⧉ JSON copies the tiny description, e.g.
{"gen":"impact","p":{"size":0.9,"metallic":0.5}}— a game plays that object directly.
4 · Ambience
Looping background beds — wind, rain, summer night, sea, cave, city, campfire, far-off battle, crowds. They loop seamlessly by construction (sounds near the end of the loop wrap around to its start). One bed plays at a time; choosing another crossfades. WAV export gives you one clean loop.
5 · Engines
Six vehicle sounds — propeller plane, jet, helicopter, tank, petrol car, electric car — under a live throttle slider. The pitch genuinely follows the throttle, the way an engine note rises with the revs.
6 · Composer
Original music from a seed — and then a track that's yours. Pick a style (each is a mood: heroic, tense, battle, calm, mystery, sunny, chip, racing, nocturne), roll the 🎲 seed, press play. Then make it yours:
- Arrange. The box under the transport lists every part of the band — melody, counter, chords, pad, bass, sparkle, drums. Swap any part's instrument (battle brass → solo string?), 🎲 reroll just that part while everything else keeps its notes, mute parts you don't want, and set tempo and key. That's track-making here: generate, then sculpt.
- Record. Choose a backing — the band, or metronome only (an accented click with the two intro bars as your count-in, for writing a melody before any band exists) — then arm ⏺ and play the record keyboard or A–K. Every note is captured quantized to the grid (1/16 by default) at its position in the loop; turn ⏺ off and the next pass plays you back over the same backing. Your take shows up in Arrange as "Your take" — re-instrument it, mute it, undo a note, or clear it — and it travels with every export.
- Intensity. Drag the slider while the music plays. Instrument layers fade in and out — the same piece plays thin while you explore a game and thick when the fight starts. This is the adaptive-music trick our games use.
- Stingers. Win / Lose / Level up / Found — short musical punctuation, in key with the style.
Exports: Score JSON (the entire piece as data — a game replays it note-perfect), WAV mixdown (one full loop, rendered offline), and the integration snippet (ready-to-paste code). Exports contain exactly what you hear — muted parts are left out — and once you've customised the arrangement, the snippet switches to the Score-JSON form, because a custom track travels as its score, not as a style name.
A practical workflow: sound for a game
- 1. Audition in the Lab until something fits — instrument, effect, bed, or a style + seed.
- 2. Note the recipe: the preset name (or copied JSON) for effects; the style + seed pair for music. Seeds make taste transferable — "heroic, seed 48213" is a complete spec.
- 3. Hand the recipe to the game (see below). No files move; the game regenerates the sound from the same code.
How our games adopt the engine
Games import one module and speak a small API. This is the entire integration surface:
import { GameAudio } from '/games/lib/audio/engine.js?v=1';
const audio = new GameAudio({ game: 'mygame' });
audio.attachUnlock(); // first tap unlocks sound (iOS rule)
audio.attachAutoSuspend(); // silence on hidden tab / lost focus
audio.play('punch.heavy', { pan: 0.3, duck: 0.35 });
audio.play({ gen: 'impact', p: { size: 0.9, metallic: 0.5 } });
audio.ui('confirm');
audio.music.start('battle', { seed: 12345, intensity: 0.4 });
audio.music.setIntensity(0.9); // combat — layers fade in on the beat
audio.music.stinger('win');
await audio.ambient.start('night.field');
const eng = audio.createEngine('heli');
await eng.ready; eng.start(0.3); eng.set(throttle01);
Sound settings persist per game; the engine handles mixing, a shared generated-reverb, and ducking music under big effects. Because everything is code, a game's whole soundscape — orchestra included — weighs a few hundred kilobytes and works fully offline.
Working with an AI coding session
Our games are built with AI coding sessions. There are two prompts — a one-liner and a fill-in template — and the difference is simply who makes the sound choices:
- Chose nothing? Use the one-liner. The session reads the engine manual, looks at the game, and picks the effects, the music style and the seed itself. Best for "just give this game good sound."
- Chose anything? Use the full template. You auditioned in the Lab and want your picks implemented — a specific style + seed, particular effects, one ambience — or you want to limit the job ("music only", "just the engine sound"). Keep the lines you care about, delete the rest; the last two lines (offline entry + gates) always stay.
The one-liner
Use the shared audio engine — read docs/prompts/game-audio.md.
The fill-in template
It has three slots. Everything else is instructions to the session, not to you:
| Slot | What it is | Where to get the value |
|---|---|---|
<GAME> | the game's folder name | emberfist · lanternfall · wirecut · frontline · sixthwing · skyenvoy · roadenvoy · goalburst · phyloca · crumbrun · worldie |
<STYLE> | one of the nine music moods | the styles table below — or just audition in the Composer |
<SEED> | any whole number — the piece's recipe number | press 🎲 in the Composer until you like the piece, then copy the number from the seed box |
Use the shared audio engine — read docs/prompts/game-audio.md, then wire up
<GAME>:
- SFX: use engine presets (audition list: /apps/studio/soundlab/#sfx);
replace or augment the game's own audio.js gradually.
- Music: audio.music.start('<STYLE>', { seed: <SEED> }) — drive
music.setIntensity() from game state (threat / wave / speed), don't
leave it constant. Add stingers on win/lose.
- Ambience: pick a bed that fits the map; crossfade between areas.
- Add shared: ['/games/lib/audio'] to the game's entry in
tools/offline/build-sw.mjs (offline support — do not skip).
- Run the audio gates AND the game's own gates before finishing.
Three ready-to-paste examples
One per kind of game, with every slot filled. The seeds here are only examples — roll your own in the Composer and swap the number if you find one you like better.
1 · A fighter (Emberfist) — punchy effects, battle music that heats up with the round:
Use the shared audio engine — read docs/prompts/game-audio.md, then wire up
emberfist:
- SFX: punch.light / punch.heavy / punch.body / kick.heavy for strikes,
block + metal.hit for guards and armoured fighters, whoosh.fast on
dodges, ui.confirm / ui.back in menus.
- Music: fights use audio.music.start('battle', { seed: 41007 });
drive music.setIntensity() from the round — 0.4 while feeling out,
0.9 when either fighter drops below 30% health.
- Stingers: 'win' and 'lose' at round end.
- Add shared: ['/games/lib/audio'] to emberfist's entry in
tools/offline/build-sw.mjs (never regenerate on a dirty shared tree).
- Run the audio gates AND the game's own gates before finishing.
2 · A night-survival game (Lanternfall) — ambience does the atmosphere, music switches with the wave:
Use the shared audio engine — read docs/prompts/game-audio.md, then wire up
lanternfall:
- Ambience: night.field while resting, battle.far during waves.
- SFX: gun.pistol / gun.rifle / gun.heavy mapped to weapon tiers,
explosion.small for bursts, step.grass for movement, ui.pickup on
ammo and ui.coin on salvage.
- Music: audio.music.start('nocturne', { seed: 77120, intensity: 0.2 })
while resting; on a wave, switch to 'tense' seed 88231 and drive
music.setIntensity() from the game's threat value.
- Stingers: 'found' on a lantern, 'lose' on going down.
- Add shared: ['/games/lib/audio'] to lanternfall's entry in
tools/offline/build-sw.mjs (never regenerate on a dirty shared tree).
- Run the audio gates AND the game's own gates before finishing.
3 · A racer (RoadEnvoy) — the engine rig is the star, music rides the speed:
Use the shared audio engine — read docs/prompts/game-audio.md, then wire up
roadenvoy:
- Engine sound: audio.createEngine('car-ice') for petrol models and
'car-ev' for the EV; call eng.set(rpm01) every frame from the drivetrain.
- SFX: whoosh.fast on close passes, explosion.small on crashes (a crunch,
nothing burns), ui.click / ui.confirm in menus.
- Ambience: wind.calm on open road, rain.storm when the weather rolls in.
- Music: audio.music.start('racing', { seed: 52941, intensity: 0.6 });
raise music.setIntensity() with speed; stinger 'win' at the finish line.
- Add shared: ['/games/lib/audio'] to roadenvoy's entry in
tools/offline/build-sw.mjs (never regenerate on a dirty shared tree).
- Run the audio gates AND the game's own gates before finishing.
The value library
Music styles — what each mood is and where it fits:
| Style | Sounds like | Good for |
|---|---|---|
heroic | bright, marching adventure | menus, flying high, SkyEnvoy |
tense | creeping menace over a pedal note | stealth, waves closing in, Wirecut |
battle | driving minor-key combat with toms | Frontline, fight scenes |
calm | weightless and kind | gentle games, Phyloca, pause screens |
mystery | curious bells and shadows | puzzles, exploring the unknown |
sunny | light-hearted marimba bounce | Goalburst menus, Crumb Run |
chip | pure arcade energy | Glowcade cabinets, Worldie |
racing | fast four-on-the-floor | RoadEnvoy, time trials |
nocturne | quiet night piano, no drums | rest scenes, night title screens |
Effect presets — the names a prompt can use (hear them all in the Effects panel):
| Group | Presets |
|---|---|
| Fight | punch.light punch.heavy punch.body kick.heavy block metal.hit whoosh.fast whoosh.big land.soft land.hard |
| Guns & battle | gun.pistol gun.rifle gun.heavy gun.mg gun.cannon gun.far mg.far explosion.small explosion.big explosion.far artillery.far alarm.base |
| Sci-fi | zap.small zap.heavy zap.chip hit.shield |
| Movement & world | step.hard step.gravel step.grass thunder.near thunder.far |
| Interface | ui.click ui.confirm ui.back ui.error ui.coin ui.pickup ui.powerup ui.win ui.lose |
Ambience beds: wind.calm wind.strong rain.soft
rain.storm night.field sea.shore cave.deep
city.hum fire.camp battle.far crowd.murmur
crowd.excited
Engines: prop (light aircraft) · jet · heli ·
tank · car-ice (petrol) · car-ev (electric)
What should drive intensity? Whatever the game's excitement really is:
a fighter → health difference and final seconds; a wave shooter → the threat or wave number;
a racer → speed and the last lap; sports → match phase; a puzzle → keep it low and let the
'found' stinger mark the solve.
Good to know
- Why no samples? Three birds: game downloads stay tiny (a full soundtrack is code, not megabytes of audio), everything works offline, and there is nothing to license — every sound is first-party synthesis, every melody is original.
- Same seed, same sound — forever. Determinism is also our quality gate: the engine's test suite verifies the browser and our build machines render the same bits.
- Interface sounds don't vary on purpose. A confirm that sounds different every press reads as broken; impacts and gunfire do vary per trigger, like the real world.
- Your exports are yours. WAVs and JSON you design here are yours to use — details in the Lab's licensing note.