Carter Temm

audiogame-utils

I've spent a lot of time making audio games, and quite a bit more time maintaining different versions of the same code for different platforms. Speech, input, sound, menus, saves, multiplayer connections, and a dozen other systems have to exist before you get anywhere near the fun part of actually making your game.

Reimplementing these things is a slog, to say the least. I'd rather spend that time polishing the game.

Audiogame-utils is my collection of reusable JavaScript building blocks for the boring infrastructure. A game can run in a browser, then use Tauri to ship the same code as a native app on Windows, macOS, Linux, iOS, and Android. Of course, there are many other engines that you might run to. The thing that makes Audiogame-utils unique to me is that the same code runs anywhere, and there is a well-documented process for getting Tauri apps in Apple's App Store. Whenever you run into a platform limitation, you can write Rust code to get around it.

The library handles the platform differences behind the scenes, so your game's codebase shouldn't spiral out of control as easily.

Common AudioGame components

Speech can go through a screen reader, an ARIA live region, browser text to speech, or a native speech backend. The library picks sensible defaults for the current platform, while still letting players choose a voice, rate, pitch, volume, and output mode when the speech system supports them.

Input from the keyboard, mouse, gamepad, and multi-finger touch gestures can be mapped to named actions. Your game asks whether the player pressed "move" or "interact" instead of caring whether that meant W, an arrow key, a controller button, or a swipe. Players can use a keymap you provide or make their own.

The audio tools cover ordinary playback, looping, live changes, three dimensional positioning, reusable sound pools, mixers, reverb, and surface based footsteps. Coordinate helpers keep the game's idea of direction lined up with the audio engine. Cacophony does the underlying playback and is the package's only runtime dependency.

There are accessible fields and screens for games with a visible interface, plus the dynamic spoken menus familiar to anyone who grew up playing audio games. Reviewable buffers keep recent chat, combat, and system messages in named lists so players can move between them and hear older entries again. Those same buffers can appear as an accessible tabbed interface for people who would rather read them.

Worlds, multiplayer, and the rest of the machinery

The map system stores and searches large game worlds with ease. It can load hundreds of thousands of objects, retrieve what is near a point or inside a region, add custom object types, and save the current state. Spatial indexes, vectors, movement, rotation, distance, and angle helpers are there when you need them.

For multiplayer games, the client handles WebSocket messages, connection loss, heartbeats, and reconnecting to the same session. The server keeps track of players, rooms, shared state, and messages without dictating whether you host it with Node, Deno, Bun, or a framework. In memory socket pairs let you test the networking code without opening a real port.

Smaller pieces cover game loop timing, countdowns, events, storage, statistics, text formatting, random choices, focus trapping, platform detection, full screen mode, close protection, display wake locks, and opening external links correctly.

Browser first does not mean browser only

Modern browsers already have capable audio, controller, touch, storage, and accessibility APIs. They also exist on nearly every device someone might use to play a game. This makes the browser a decent common platform, provided somebody deals with its rough edges (and yes, there are many).

When you want an installable application, one command patches a new or existing Tauri project with the packages, permissions, and configuration audiogame-utils needs. After a single initialization call, saves move to disk, native window controls become available, and asset paths resolve for the installed app. The rest of the game keeps using the same APIs.

You don't have to adopt an application framework or a particular folder structure. audiogame-utils publishes plain ECMAScript modules, so you can use one helper in an existing project or build the whole game around it. It works with JavaScript and TypeScript, ships its own type declarations, and requires no build step of its own.

Getting started

Install it with npm:

npm install audiogame-utils

Or with Deno through JSR:

deno add jsr:@cartertemm/audiogame-utils

The documentation and runnable examples cover every public module. Start with the piece your game needs today. There is no reason to rewrite a speech wrapper or input system before you can find out whether the game itself is any fun.