For developers
Add it to your game engine
Download the MP3s, put them in your project and play them. Short examples for Godot, Unity, Phaser, plain web audio and a crossfade.
extends Node
@onready var music: AudioStreamPlayer = $Music
func _ready():
music.stream = load("res://music/Purrple Cat - Sands of Time.mp3")
music.volume_db = -14.0
music.play()
func _on_music_finished():
music.play() # or pick the next track hereusing UnityEngine;
public class Soundtrack : MonoBehaviour {
public AudioClip[] tracks; // drag your MP3s here
public AudioSource source; // volume ~0.3
int i;
void Start() { Play(0); }
void Update() { if (!source.isPlaying) Play((i + 1) % tracks.Length); }
void Play(int n) { i = n; source.clip = tracks[i]; source.Play(); }
}// preload
this.load.audio("hub", "assets/music/purrple-cat-hub.mp3");
// create
const music = this.sound.add("hub", { volume: 0.3, loop: true });
this.sound.once("unlocked", () => music.play()); // browsers need a click first<audio id="bgm" src="music/purrple-cat-hub.mp3" loop></audio>
<script>
const bgm = document.getElementById("bgm");
bgm.volume = 0.3;
document.addEventListener("pointerdown", () => bgm.play(), { once: true });
</script>function crossfade(from, to, secs = 3) {
to.volume = 0; to.play();
const t0 = performance.now();
(function tick(now) {
const k = Math.min(1, (now - t0) / (secs * 1000));
from.volume = (1 - k) * 0.3;
to.volume = k * 0.3;
if (k < 1) requestAnimationFrame(tick); else from.pause();
})(t0);
}Ship the files, don’t hotlink
Download the MP3s and include them in your build. Do not depend on this site or the file host staying at the same address.
Full songs, not loops
Each track plays from start to finish. Queue two or three per scene and crossfade, instead of looping a single song.
Mixing tips
- Start the music near 25 to 35 percent volume
- Duck it a few dB under dialogue
- Fade out over 2 to 4 seconds when a scene ends
Credit it
Music by Purrple Cat (purrplecat.com), licensed under CC BY 4.0: creativecommons.org/licenses/by/4.0/