Skip to Content

Introducing syngen

A library for audio game development

Over the past year I’ve used web technologies to create audio games like soundStrider and participate in numerous game jams. With syngen I’m releasing my tools as open-source so folks can join me in crafting dynamic audio experiences and games for the web. Continue reading to dive into its features, view example code, and learn more about its future.

Overview

syngen is a game engine and synthesis toolkit that specializes in creating audio games with fully synthesized sounds. If you’ve played any of my games before, then you might be familiar with its capabilities.

It provides a light wrapper around the Web Audio API with tools for building synths and positioning them as props on a three-dimensional binaural soundstage. Its event loop fires each frame to update props and core systems. Additional utilities provide tools for engineering custom systems that hook into its API to deliver rich experiences.

Features

  • Wrapper for the Web Audio API with a domain-specific API
  • Event-driven main loop and core systems
  • Interfaces and utilities for building custom sounds and systems
  • Binaural processing to position sounds on a realistic stage
  • Virtualized mixer for advanced signal routing and mastering
  • Built-in synthesizers, effects, and global reverb send

Getting started

Please clone the repository or install with your favorite package manager:

npm install syngen

The library must be used within a browser environment so it can access the window object. You may require('syngen') as a UMD module, or include dist/syngen.min.js to assign it to the syngen global.

Example usage

This example demonstrates how to define a prop and instantiate one on the soundstage. Here you’ll hear a relatively loud sine tone playing Middle C, centered in the stereo field:

const prototype = syngen.prop.base.invent({
  onConstruct: function () {
    this.synth = syngen.audio.synth.createSimple({
      frequency: syngen.utility.midiToFrequency(60),
      gain: syngen.utility.fromDb(-6),
    }).connect(this.output)
  },
  onDestroy: function () {
    this.synth.stop()
  },
})

const instance = syngen.props.create(prototype)

Example projects

The library ships with an example directory with simple demonstrations of its built-in capabilities. For more advanced real-world examples, please play and tinker freely with the open-source projects below:

  • Audo. This endless audio racing game was developed with syngen for GMTK Jam 2020 with the theme out of control. Collect power-ups and dodge opponents on an expanding, non-euclidean track.
  • Auraboros. This endless audio shooter was developed with syngen for Ludum Dare 47 with the theme stuck in a loop. Face endless waves of enemies with responsive movement and projectile physics.
  • Kaleidophone. This generative audio toy was developed with syngen for LOWREZJAM 2020 and Brackeys Jam 2020.2 with the theme rewind. Manipulate time to explore generative graphics and soundscapes.
  • S.E.A. This experimental watercraft simulator was developed with syngen for No Video Jam with the theme waves. It leverages Perlin noise to procedurally generate its terrain and dynamic soundtrack.

Further reading

Additional resources have been provided to help you get started with your own audio projects:

  • API Documentation. The library ships with a docs directory containing detailed documentation. It’s also accessible online. Inside is an explanation of every namespace, interface, method, and type to expect when working with syngen.
  • syngen-template. Need a head start with creating your audio game? This template repository provides a working directory structure and Electron wrapper for quick development and deployment. Feel free to create a fork and start coding your own way.

The future of syngen

This initial release reflects a year of learning with game development. It contains some assumptions and vestiges that have remained since I first started this journey. For this reason it’s been released as version 0.1.0 to indicate that it’s experimental and to be used at your own risk in production. Hopefully the examples above demonstrate the rewards of that gamble.

Because I have games in production on this release branch, it needs to remain backwards compatible. Therefore, minor version bumps and patch releases will only contain new features and bug fixes. If it ever reaches the 1.0.0 milestone, then that will indicate a stabilization of this current API.

What I would like to do in a 2.0.0 release branch is reflect on my previous assumptions to rework it entirely. This might include simplifications and optimizations that improve its power and usability. Ideally it would empower me to build a new generation of audio games beyond what I’ve thought possible and learned this past year.

Please reach out or create an issue on GitHub if you encounter any bugs or have any questions or projects to share. I’m excited to hear your creations!