- assets/audio/music/zombie_industrial_loop.ogg: 57.60 s Ogg Vorbis loop generated locally with YuE2-3B on the Tesla V100 (score written for this track; vocals removed with HTDemucs). The loop is spliced at the track's structural repeat with a 0.6 s crossfade: measured seam dip <= 1.6 dB. - scripts/main.gd: "Music" AudioStreamPlayer at -11 dB, started at boot on desktop and on the start click on Web (browser autoplay policy). It forces stream.loop at runtime because the Web staging step re-imports the OGG with loop=false. - tools/test_music.gd: soundtrack test (loop, length, volume, playback, still playing after player death). - docs/MUSIC.md: source, loop construction, verification, licence. - docs/WEB-DEPLOY.md: release ab6054111f5919a8 notes. Initial commit of the project.
3.2 KiB
Soundtrack — industrial metal loop
Endless survival loop played from the first frame, at -11 dB, independent of gameplay state.
Source
Generated locally (2026-10-10) with YuE2-3B Q8_0 through the audio.cpp CUDA build for the
Tesla V100 (~/dev/audio.cpp, cmake -DCMAKE_CUDA_ARCHITECTURES=70), seed 31337, 16 steps,
cot=melody + an external ABC score written for this track (K:Em Phrygian, Q:1/4=168,
96 bars; the model rendered it at a perceived 112.5 BPM). Style prompt: instrumental
industrial metal, Nine Inch Nails meets the Quake 2 soundtrack, machine drums, palm-muted
downtuned guitars, atonal synth stabs, no vocals.
--lyrics "[instrumental]" does not suppress singing (verified: male shouts 0:52-1:17 and
1:37-2:35). The instrumental was therefore obtained by HTDemucs vocal removal
(--task sep --family htdemucs, input resampled to 44.1 kHz, RTF 0.049) and remixed as
drums + bass + other.
Working files: ~/yue2-out/zombie-industrial/.
Loop construction
The track has a structural repeat (bars 24-30 ≈ 46-52, spectral similarity 0.95), so the loop splices at matching material instead of cutting arbitrarily:
- region 51.37 s → 108.97 s of the instrumental master = 27 bars (bar = 2.1333 s, 112.5 BPM);
- rotation by one tail segment plus a 0.60 s equal-power crossfade;
- result: 57.60 s, seam dip ≤ 1.6 dB in 20 ms windows, sample step 0.04 (inaudible);
- perceptual check on a 3 s + 3 s excerpt around the seam: no click, no level hole, natural continuation.
A longer variant (132 s) was rejected: its crossfade cancels (a -48 dB hole) because the two overlapped sections are out of phase.
Asset and import
assets/audio/music/zombie_industrial_loop.ogg — Ogg Vorbis q6, 48 kHz stereo, 1.0 MB,
-14 LUFS / -1.0 dBTP. Import: loop=true, bpm=112.5, beat_count=108, bar_beats=4.
The Web staging step (tools/prepare_web.py) copies the asset but ignores *.import, and the
staging import regenerates it with loop=false. main.gd therefore sets stream.loop = true
at runtime: keep that line, it is what makes the browser build loop.
Runtime wiring
scripts/main.gd: _setup_music() creates the AudioStreamPlayer named Music (group
music), _start_music() starts it once, _restart_music() restarts it if the loop flag is
ever absent. On Web the start is deferred to the click that captures the mouse, because
browsers only allow audio after a user gesture. Music keeps playing while the player is dead;
R reloads the scene and the track restarts with it.
Verification
godot --headless --path . --script res://tools/test_music.gd
godot --display-driver headless --audio-driver PulseAudio --path . --script res://tools/test_music.gd
godot --headless --path . -- --smoke
Both runs PASS: node present, loop=true, length 57.60 s, volume -11 dB, playback advancing
(confirmed on the real PulseAudio device, not only the Dummy driver), music still playing after
player death. Grenade, wave, death and damage-feedback tests also pass unchanged.
License
YuE2-3B weights are CC BY-NC 4.0 (non-commercial): this track is for personal/experimental use. It is an AI-generated render, not a recording of a third-party work.