跳到正文

SoundSystem lib

作者:Devolaux

Lib for the SoundSystem mod.

收藏

介绍

中文介绍正在准备中,下面暂时显示原文。

SoundSystem Lib

The sound engine behind SoundSystem, for any Fabric or NeoForge 1.21.1 mod that wants music in the world: play a SoundCloud link or an audio file from a player’s computer, keep every player’s sound in sync, and make it sound like it comes from the speakers around you.

The Lib adds no blocks and no items. On its own it does nothing you can see — it is a dependency. If a mod asks for it, put the jar for your loader in mods/ next to that mod, on the server and on every client: soundsystemlib-fabric-<version>.jar (with Fabric API) or soundsystemlib-neoforge-<version>.jar.


What it does

SoundCloud playback, with nothing to set up — Give it a public SoundCloud link (a track or a playlist). No API key, no account, no login. The Lib finds what it needs from SoundCloud’s own site when the game asks, reads the stream, and decodes it.

Your players’ own files — It also plays WAV, Ogg Vorbis and MP3 files that a player brings from their own computer, from links of the form local:<id>. The Lib finds out what a file holds (format, length, title, artist) and refuses what is not audio; the mod on top of it decides where the files are kept and how they travel between computers.

No third-party library — The SoundCloud client and every audio decoder (AAC, WAV, Ogg Vorbis, MP3) are the Lib’s own code. Nothing like LavaPlayer is inside: when SoundCloud changes how it works, the fix is a new Lib release, and the mods on top of it are not touched.

One shared timeline — The server never carries audio on its own. It only says which track plays, where it is and how fast. Every player’s game downloads and decodes the track itself and keeps its sound on that timeline, so everyone hears the same beat at the same moment, and a big event stays light on the server.

A physical model of sound — What a player hears depends on the world: distance, which way the speaker faces, walls and obstacles in between, the time sound takes to travel (100 ms at 34 blocks), and the reverberation of the room. The music is split in three frequency bands, because bass wraps around and goes through walls where treble is focused and stopped. Optional distortion when a speaker is pushed past 100%.

Ponder inside — The animated 3D guide scenes (hold W over an item) are powered by Ponder, carried inside the jar: with Flywheel and Forge Config API Port on Fabric, with Flywheel on NeoForge. Nothing else to install; if you already have Ponder or Create, the newest version is the one used.

One code, two loaders — The Lib is written once and built for both loaders, so the Fabric and the NeoForge jar of the same version behave the same.


Which tracks can it play?

From SoundCloud: almost all of them. In a survey of 647 public tracks (October 2026), 94.6% could be played. The Lib decodes AAC, the format SoundCloud serves for every track you can listen to in full.

  • Tracks that SoundCloud protects with DRM (about 5% in the survey) can’t be played, and neither can tracks that are only offered as a short preview. The game shows “This track’s audio format is not supported.”
  • MP3 and Opus are not decoded from SoundCloud: no track in the survey needed them. HE-AAC is not decoded yet either.

From a player’s computer: WAV (8, 16, 24 and 32-bit integer, 32 and 64-bit float), Ogg Vorbis and MP3 (MPEG-1, 2 and 2.5, Layer III). A damaged file ends the track or is refused with a message a player can read.

  • Not decoded: compressed WAV (ADPCM, A-law…), Vorbis files that use floor type 0 (no encoder has made one in twenty years), MP3 Layers I and II, and free-format MP3.

The decoders are checked against ffmpeg: for AAC, on test files and on a real SoundCloud stream, the difference is at most one step of the 16-bit scale.


Requirements

  • Minecraft 1.21.1
  • Fabric: Fabric Loader 0.16.14+ and Fabric API — or NeoForge: 21.1 or newer (tested with 21.1.265)
  • Java 21 (the one Minecraft 1.21 already uses)
  • The jar made for your loader: Fabric and NeoForge jars are not interchangeable.

Nothing else: Ponder and Flywheel (and Forge Config API Port, on Fabric) are inside the jar.

Config

config/soundsystemlib.json, created on first start; missing fields get their default value. If you used SoundSystem 1.x, the Lib takes over the matching values from config/soundsystem.json the first time it starts.

  • maxQueueSize (100) — most tracks a playlist link may hold, 1 to 100
  • maxMediaVoices (16) — how many media players your game decodes and plays at once (the nearest ones)
  • maxVirtualSources (12) — separately placed sound sources per media player (the loudest ones; the rest are merged)
  • enableReverb (true) — the reverberation of the room you stand in
  • enablePropagationDelay (true) — sound takes time to travel
  • enableDistortion (true) — a speaker pushed past 100% saturates

Lower the two numbers first if a huge event is heavy on your computer.


For mod developers

The Lib knows no blocks: you describe your own with a few interfaces, and it does the rest.

  • You choose which link plays, when and how fast, and send the state to nearby players in one packet type.
  • You describe your speakers (range, how much of each band they reproduce, how they fuse together) and what is in the world around them.
  • The Lib resolves the link, decodes it, keeps each client on the timeline and mixes what the listener hears.
  • For audio files from your players, you give the Lib a store (LocalAudioFiles.register) that says where the bytes of an id are; the Lib decodes them like any other track. Keeping the files and moving them between server and clients is your mod’s part.

Add it to your build. The Lib is published to GitHub Packages (a token with read:packages is needed to read it), once for each loader and once for the code they share:

dependencies {
    modImplementation 'dev.soundsystem:soundsystemlib-fabric:0.2.0'    // a Fabric mod
    implementation    'dev.soundsystem:soundsystemlib-neoforge:0.2.0'  // a NeoForge mod
    compileOnly       'dev.soundsystem:soundsystemlib-common:0.2.0'    // code shared between loaders
}

Declare the dependency, so that the loader tells a player what to install (use the oldest version that has what you need: 0.2.0 if you play local files, 0.1.1 otherwise):

"depends": { "soundsystemlib": ">=0.2.0" }
[[dependencies.yourmod]]
modId = "soundsystemlib"
type = "required"
versionRange = "[0.2.0,)"
ordering = "AFTER"
side = "BOTH"

(the first in fabric.mod.json, the second in neoforge.mods.toml).

Start the client engine. The engine is the same on both loaders; only the events that feed it differ. On Fabric:

var engine = new PlaybackEngine<>(clock, EngineSettings.DEFAULT, scene);
ClientPlayNetworking.registerGlobalReceiver(MyState.ID, (packet, ctx) -> ctx.client().execute(() -> engine.receive(packet)));
ClientTickEvents.END_CLIENT_TICK.register(client -> { if (client.level != null) engine.tick(client); });
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> engine.stopAll());

On NeoForge:

var engine = new PlaybackEngine<>(clock, EngineSettings.DEFAULT, scene);
// in your RegisterPayloadHandlersEvent: registrar.playToClient(MyState.TYPE, MyState.CODEC, (packet, ctx) -> engine.receive(packet));
NeoForge.EVENT_BUS.addListener((ClientTickEvent.Post event) -> { var client = Minecraft.getInstance(); if (client.level != null) engine.tick(client); });
NeoForge.EVENT_BUS.addListener((ClientPlayerNetworkEvent.LoggingOut event) -> engine.stopAll());

(Names are the game’s own, Mojang’s; a Fabric mod written with Yarn names compiles against the Fabric artifact all the same.)

You can also read a track without the engine — decode any link to frames of 100 ms of 16-bit stereo at 44.1 kHz:

try (var resolver = new MusicResolver(100)) {
    Track track = resolver.resolve("https://soundcloud.com/some-artist/some-track").get(0);
    try (AudioDecoder decoder = resolver.decode(track, 30_000, 1.0)) {   // from 30 s, at normal speed
        // decoder.pollFrame() ...
    }
}

The public API is the package dev.soundsystemlib.api; dev.soundsystemlib.internal is not, and may change at any time. The API is young: until 1.0, a type may still be renamed between minor versions. The server side of the transport (the packet and its repetition) is yours for now; SoundSystem’s is a working example, for both loaders. The full guide is in the repository: docs/API.md.


Mods that use it

  • SoundSystem — DJ tables, speakers, stage lighting and pyro, for Fabric and NeoForge (needs Lib 0.2.0 or newer since version 2.1.3, and 0.1.1 or newer from 2.1.1 before that; Fabric only, and Lib 0.0.1, before)

MIT licence. Ponder, Flywheel and Forge Config API Port keep their own licences. The AAC code tables are transcribed from JAADec (public domain). The MP3 decoder is a port of minimp3 (public domain, CC0). The Lib doesn’t ship or host any audio; music comes from public SoundCloud links, or from files that a mod provides.

常见问题

SoundSystem lib 支持哪些 Minecraft 版本?

SoundSystem lib 支持 Minecraft Java 版 1.21.1,可用的加载器:Fabric / NeoForge。下载时注意选择和你游戏版本一致的文件。

SoundSystem lib 怎么安装?

先用 PCL2 或 HMCL 启动器安装对应版本的 Fabric / NeoForge,再把下载的 .jar 文件放进游戏目录的 mods 文件夹,重新启动游戏即可。开启了版本隔离的,mods 文件夹在 versions/版本名 下面。

评论

登录后评论和评分

Devolaux 的其他作品

查看全部 →