Unofficial ChoiceScript Audio Enhanced Plugin

The Unofficial Audio Enhanced plugin adds loops, volume controls, crossfades, and more to ChoiceScript. It uses javascript to automatically play music through the game itself on your command. It’s intended to be a framework for you to build your own custom audio solution through ChoiceScript itself. For instance, with Audio Enchanced, you could have a custom narrator for your game, or create a variable mix where specific instruments play depending on conditions.

I made this plugin on accident for my own in-development games, but it’s morphed into something I feel is worth sharing. Because of this, it’s untested on anything but my own PC, cannot be used in hosted games, and will break Quicktest and Randomtest. I’ll try to support this plugin the best I can, but keep in mind it’s a volunteer project by a self-taught programmer who taught themselves javascript just for this. However, if you’re the do-it-yourself kind of person, I’ve commented on every line of code to explain exactly what’s happening because I have no idea what I’m doing I’m a nice person. If you know ChoiceScript, then you might know enough to read javascript. Maybe. Possibly. Okay, it’s a bit more complicated than that, but ChoiceScript does teach some programming fundamentals and I’ll stop now.


As an unofficial plugin, this will break quicktest and randomtest. Your game will work fine, but the tests will fail. You can get around this by *commenting out the new commands before running the tests.

How to Install:

  1. Download the plugin file (link) and save it as sePlugin.js.
  2. Place the plugin file in your game’s web folder.
  3. In your game’s web folder, create a new folder called audio (case sensitive). This is where you’ll be storing your sound files.
  4. Open your game’s web\mygame\index.html.
  5. In web\mygame\index.html, look for a block of code that looks like this:
<script src="../persist.js"></script>
<script src="../alertify.min.js"></script>
<script src="../util.js"></script>
<link href="../style.css" rel="stylesheet" type="text/css">
<style id="dynamic"></style>
<script src="../ui.js"></script>
<script src="../scene.js"></script>
<script src="../navigator.js"></script>
<script src="mygame.js"></script>
  1. Immediately after <script src="../scene.js"></script>, add the following on a new line: <script src="../aePlugin.js"></script>
  2. In startup.txt, after you’ve *create-d your game’s variables, add the following command: *se_stop_all. This will make sure any audio playing when you restart the game is stopped.

And with that, you’re set!

New Commands:

*se_sound [audio_filename_or_url] [audio_id] [is_a_loop?] [volume]: Creates a sound using Sound Enhanced, which gives you greater control over it. You can still use the old *sound, but sounds added that way cannot be modified with these commands.

[audio_filename_or_url]: The name or location of the sound to be played. If the sound file is in your audio folder, then use the full filename. If the sound file is hosted on the web somewhere, then use it’s full URL.

[audio_id]: The name for this specific instance of the sound. Can be whatever you want.

[is_a_loop?]: Optional, defaults to false. Determines whether the sound will loop. Should be a boolean (true or false). If true, sound will keep playing until deleted. If false, sound will play once and delete itself.

[volume]: Optional, defaults to global volume. Sets the volume of the specific sound. Must be a number between 0 (muted) and 1 (very loud), and requires [is_a_loop?] to be specified. Note that setting a volume for a specific sound will decouple it from the globally-set volume, which may break the player’s sound controls.

*se_volume [volume] [audio_id]: Sets either the global volume for all sounds, or sets the volume of a specific sound.

[volume]: How loud, on a scale of 0 (muted) to 1 (very loud).

[audio_id]: Optional, defaults to none. The ID of the specific sound to change. If no ID is given, volume is set globally. Otherwise, the volume is set just the specified sound.

*se_fade_in [audio_id] [volume]: Causes the specified sound to “fade in”, or get louder over time. Fades last five seconds.

[audio_id]: The ID of the sound to fade in.

[volume]: Optional, defaults to global volume.

*se_fade_out [audio_id] [volume]: Causes the specified sound to “fade out”, or get softer over time. Fades last five seconds.

[audio_id]: The ID of the sound to fade out.

[volume]: Optional. If not specified, sound will fade out completely and delete itself when done. If specified, sound will fade out to the specified volume. You can set this to 0 to cause the sound to mute without deleting.

*se_pause [audio_id]: Pauses a specific sound. The sound won’t play until it’s unpaused, at which point it will resume from whatever point it was paused.

[audio_id]: The ID of the sound to pause.

*se_unpause [audio_id]: Resumes a specified paused sound.

[audio_id]: The ID of the sound to unpause.

*se_stop [audio_id]: Deletes the specified sound.

[audio_id]: The ID of the sound to stop.

*se_stop_all: Stops all currently playing and muted audio. Made to clear the soundscape when restarting the game.

Known Bugs:

  • As a general rule, Sound Enhanced assumes the player isn’t speedrunning. If the player clicks through your game as fast as they can, they might cause commands to stack up in weird ways. This isn’t likely if the player stops to read what’s on screen, but you should still space your commands far apart. If it becomes a problem, add *page_break “speedbumps”; the time it takes for players to click and load the next block of code should slow them down.
  • If you tell a song to fade out/in while it’s already fading out/in, things get buggy. I’ve put in a basic check to prevent an infinite fade in/out loop, but you should avoid overlapping fades when possible.
  • If a song is set to fade out completely in the same block of ChoiceScript code (from the last *choice or *page_break to the next *choice or *page_break) that it’s created, then when you go to the stat screen and come back, the song will fade out again. If for some reason you want a song to fade out immediately, then tell it to fade to 0 (mute) and then stop it in the next block of code.

Planned Features:

Combining *se_stop_all with *se_stop; if no [audio_id] is given, *se_stop would work like *se_stop_all.

Possibly merging se_pause with se_unpause; an extra argument would determine if the audio would pause/unpause. I’m going back and forth on whether this is better.

Demo game showing off everything you can do.

[insert feature creep here]

Special Thanks:

CJW for his Save Manager Plugin, of which I referenced constantly.

Anyone that’s interacted with me on the forums over the past week. Without such a vibrant community, I wouldn’t have stuck this out.



Glad to see you posting this :slight_smile:

Woops!? :laughing:

Interesting :eyeglasses:

I haven’t tried my hand with this, but I assume the interaction of this plugin with a screenreader is similar like other elements (images, choices, buttons)?

i.e. The audio plays only when the reader reached the *se_sound commands.


Should be fixed now. Freud would love this.

Yup! If you’ve ever used CJW’s plugin, it works like that. So you can put a submenu in your stats screen to adjust volume, or tell certain sounds to pause or play at story points. I’m working on a demo game so people can test it in action.


Cannot wait to see how people will use this. (What truly makes this post for me, though, is the special thanks to Satan.)

Ooo This plugin seems amazing.

Hail Satan :man_cook:

Anyone still have this file? I can’t find it on wayback machine, and the original link is discontinued :frowning:

Sadly it’s discontinued :frowning: It was really good