MultiLoader 26.1+ · Part 11

Data Generation: Sound Definitions (MultiLoader 26.1+)

BEGINNER MULTILOADER 26.1-26.1.2 12 min read · Jun 14, 2026
MultiLoader 26.1+ · 17 parts
1 Getting Started with MultiLoader 26.1+ 2 Setting Up RegistrationUtils (MultiLoader 26.1+) 3 Creating Items (MultiLoader 26.1+) 4 Creating Blocks (MultiLoader 26.1+) 5 Data Generation: Block & Item Models (MultiLoader 26.1+) 6 Data Generation: Block Loot Tables (MultiLoader 26.1+) 7 Data Generation: Crafting Recipes (MultiLoader 26.1+) 8 Data Generation: Block & Item Tags (MultiLoader 26.1+) 9 Data Generation: Language Files (MultiLoader 26.1+) 10 Data Generation: Advancements (MultiLoader 26.1+) 11 Data Generation: Sound Definitions (MultiLoader 26.1+) 12 Data Generation: Particle Descriptions (MultiLoader 26.1+) 13 Data Generation: Enchantments (MultiLoader 26.1+) 14 Custom Food Items (MultiLoader 26.1+) 15 Custom Tools (MultiLoader 26.1+) 16 Custom Armour (MultiLoader 26.1+) 17 Block Entities (MultiLoader 26.1+)

Custom sounds in Minecraft require two things: a registered SoundEvent that the game plays by name, and an entry in sounds.json that maps the event name to one or more audio files. The sounds.json file can be generated automatically using SoundDefinitionsProvider, keeping the JSON in sync with your registered events.

NOTE
Complete Data Generation: Language Files before continuing. We add a new provider to the existing gatherClientData listener.

Registering a Sound Event

Sound events live in the minecraft:sound_event registry. Create a SoundRegistry class in your common registry package:

java
public class SoundRegistry {
public static final RegistrationProvider<SoundEvent> SOUNDS =
RegistrationProvider.get(Registries.SOUND_EVENT, Constants.MOD_ID);
public static final RegistryObject<SoundEvent, SoundEvent> EXAMPLE_SOUND =
SOUNDS.register("example_sound",
() -> SoundEvent.createVariableRangeEvent(
Identifier.fromNamespaceAndPath(Constants.MOD_ID, "example_sound")));
public static void init() {}
}

createVariableRangeEvent is the standard choice for most sounds: the range falls off naturally with distance based on volume. Use createFixedRangeEvent(Identifier, float) only when you need an exact, fixed radius (as used for ambient cave sounds, for example).

Call SoundRegistry.init() from CommonClass.init():

java
public class CommonClass {
public static void init() {
ItemRegistry.init();
BlockRegistry.init();
SoundRegistry.init();
CreativeTabRegistry.init();
}
}

Sound Definitions Provider

In your NeoForge data package, create ExampleSoundDefinitionsProvider extending SoundDefinitionsProvider:

java
public class ExampleSoundDefinitionsProvider extends SoundDefinitionsProvider {
public ExampleSoundDefinitionsProvider(PackOutput output) {
super(output, Constants.MOD_ID);
}
@Override
public void registerSounds() {
add(SoundRegistry.EXAMPLE_SOUND.get(),
SoundDefinition.definition()
.with(sound(
Identifier.fromNamespaceAndPath(Constants.MOD_ID, "example_sound")))
.subtitle("subtitles.examplemod.example_sound"));
}
}

The add(SoundEvent, SoundDefinition) method writes one entry in sounds.json. The identifier passed to sound() is the path to the audio file relative to assets/<namespace>/sounds/, without the .ogg extension.

The optional subtitle(String) call sets the translation key shown in the subtitles overlay when accessibility subtitles are enabled. Add the translation to your language provider:

java
// In ExampleLanguageProvider.addTranslations():
add("subtitles.examplemod.example_sound", "Example sound plays");
TIP
To give a sound multiple audio files that the game chooses between randomly, chain multiple .with(sound(...)) calls on the same SoundDefinition. You can also set per-entry .volume(float), .pitch(float), and .weight(int) to control how often each variant is selected:

SoundDefinition.definition() .with(sound(path1).weight(3)) .with(sound(path2).weight(1))

Adding the Audio File

Datagen does not create audio files — you must supply the .ogg yourself. Place it at:

text
common/src/main/resources/assets/examplemod/sounds/example_sound.ogg

Minecraft requires .ogg format, mono or stereo, at any sample rate. Free tools such as Audacity can export to .ogg (File › Export Audio). Keep the file size small for sounds that play frequently.

Registering the Provider

Sound definitions are client-side, so register the provider inside gatherClientData:

java
public static void gatherClientData(GatherDataEvent.Client event) {
event.createProvider(output -> new ExampleModelProvider(output));
event.createProvider(ExampleLanguageProvider::new);
event.createProvider(ExampleSoundDefinitionsProvider::new);
}

Testing In-Game

Run the NeoForge Data configuration and verify that assets/examplemod/sounds.json appears in the generated resources folder:

json
{
"example_sound": {
"subtitle": "subtitles.examplemod.example_sound",
"sounds": [
{ "name": "examplemod:example_sound" }
]
}
}

Launch the client and run /playsound examplemod:example_sound master @s to confirm the sound plays. If you hear nothing, check that the .ogg file is in the correct location and that its name matches the identifier in the provider exactly.

You can find the source for this tutorial here:

View Source on GitHub
NEXT IN SERIES

Data Generation: Particle Descriptions (MultiLoader 26.1+)

Register a SimpleParticleType, generate the particle description JSON using ParticleDescriptionProvider with single-sprite and indexed-suffix variants, and test with the /particle command.

Continue →