SpecEnvoy
EN·中文
SpecEnvoy Studio · Sound Lab

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.

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:

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

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:

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:

SlotWhat it isWhere 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.
Tip: the Composer's ⧉ Integration snippet button writes the music line for you, with your exact style and seed already filled in.

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:

StyleSounds likeGood for
heroicbright, marching adventuremenus, flying high, SkyEnvoy
tensecreeping menace over a pedal notestealth, waves closing in, Wirecut
battledriving minor-key combat with tomsFrontline, fight scenes
calmweightless and kindgentle games, Phyloca, pause screens
mysterycurious bells and shadowspuzzles, exploring the unknown
sunnylight-hearted marimba bounceGoalburst menus, Crumb Run
chippure arcade energyGlowcade cabinets, Worldie
racingfast four-on-the-floorRoadEnvoy, time trials
nocturnequiet night piano, no drumsrest scenes, night title screens

Effect presets — the names a prompt can use (hear them all in the Effects panel):

GroupPresets
Fightpunch.light punch.heavy punch.body kick.heavy block metal.hit whoosh.fast whoosh.big land.soft land.hard
Guns & battlegun.pistol gun.rifle gun.heavy gun.mg gun.cannon gun.far mg.far explosion.small explosion.big explosion.far artillery.far alarm.base
Sci-fizap.small zap.heavy zap.chip hit.shield
Movement & worldstep.hard step.gravel step.grass thunder.near thunder.far
Interfaceui.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

Open the Sound Lab →