Server-driven audio playback for NeoForge mods.
Acoustic lets a server-side mod start, stop, and update custom OGG sounds on
selected clients. It is built for ambience, scripted music, boss themes, events,
and other cases where vanilla sounds.json playback is too limited.
- Server-side API for targeted sound playback.
- Direct OGG streaming from mod assets.
- Loop counts, infinite loops, start offsets, and end offsets.
- Fade in, fade out, runtime volume changes, and runtime pitch changes.
- Optional player predicates evaluated on the server before packets are sent.
- Music arbitration for exclusive tracks that can fade or block vanilla music.
- Kotlin DSL and Java-friendly entry points.
- Minecraft
1.21.1 - NeoForge
21.1+ - Kotlin for Forge
5.3+
Acoustic is a library-style mod. It does not add gameplay content by itself; it provides an API that other mods and server logic can use.
Place audio files in the standard Minecraft resource location layout:
src/main/resources/assets/<namespace>/sounds/<path>.ogg
For example, this resource:
src/main/resources/assets/mymod/sounds/ambient/cave.ogg
is played with:
ResourceLocation.fromNamespaceAndPath("mymod", "ambient/cave")val sound = ResourceLocation.fromNamespaceAndPath("mymod", "ambient/cave")
val instanceId = Acoustic.soundManager
.play(sound, players)
.loop()
.fadeIn(2f)
.fadeOut(3f)
.volume(0.8f)
.condition { player -> player.isUnderWater }
.execute()
Acoustic.soundManager
.update(instanceId, players)
.volume(0.4f, transition = 1.5f)
.pitch(0.8f, transition = 0.25f)
.execute()
Acoustic.soundManager
.stop(instanceId, players)
.fadeOut(2f)
.execute()ResourceLocation sound = ResourceLocation.fromNamespaceAndPath("mymod", "ambient/cave");
String instanceId = AcousticApi.play(sound, player)
.loop()
.fadeIn(2.0F)
.fadeOut(3.0F)
.volume(0.8F)
.condition(target -> target.isUnderWater())
.execute();
AcousticApi.update(instanceId, player)
.volume(0.4F, 1.5F)
.pitch(0.8F, 0.25F)
.execute();
AcousticApi.stop(instanceId, player)
.fadeOut(2.0F)
.execute();loop()repeats forever.loop(1)plays once.loop(N)plays exactlyNtimes.start(seconds)starts inside the file.end(seconds)stops at a file offset; negative values mean end of file.fadeIn(seconds)andfadeOut(seconds)apply to the active segment.fadeIn(seconds, repeatOnLoop = false)applies fade-in only to the first loop cycle;fadeOut(seconds, repeatOnLoop = false)applies fade-out only to the final loop cycle.exclusive()lets a sound participate in music arbitration and block vanilla music until it ends or is stopped.priority(value)lets higher-priority Acoustic tracks fade out lower-priority managed tracks.
Use the bundled Gradle wrapper:
.\gradlew.bat buildThe release jar is produced under build/libs.
