CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-net-kyori--adventure-api

A serverside user interface library for Minecraft: Java Edition

Pending
Overview
Eval results
Files

sound-system.mddocs/

Sound System

Sound playback and management with support for different sources, volumes, positional audio, and sound stopping. Adventure's sound system provides comprehensive audio control for Minecraft servers.

Capabilities

Sound Interface

Core interface for representing and playing sounds with configurable properties.

/**
 * Represents a sound with key, source, volume, and pitch
 */
interface Sound extends Examinable {
    /**
     * Gets the sound key (identifier)
     * @return the sound key
     */
    Key name();
    
    /**
     * Gets the sound source category
     * @return the sound source
     */
    Source source();
    
    /**
     * Gets the sound volume (0.0 to Integer.MAX_VALUE)
     * @return the volume
     */
    float volume();
    
    /**
     * Gets the sound pitch (-1.0 to 1.0)
     * @return the pitch
     */
    float pitch();
    
    /**
     * Gets the random seed for sound variation
     * @return optional containing the seed
     */
    OptionalLong seed();
    
    /**
     * Creates a sound with specified properties
     * @param name the sound key
     * @param source the sound source
     * @param volume the volume (0.0 to Integer.MAX_VALUE)
     * @param pitch the pitch (-1.0 to 1.0)
     * @return new sound
     */
    static Sound sound(Key name, Source source, float volume, float pitch);
    
    /**
     * Creates a sound with seed
     * @param name the sound key
     * @param source the sound source
     * @param volume the volume
     * @param pitch the pitch
     * @param seed the random seed
     * @return new sound
     */
    static Sound sound(Key name, Source source, float volume, float pitch, long seed);
    
    /**
     * Creates a sound builder
     * @return new sound builder
     */
    static Builder sound();
    
    /**
     * Sound source categories affecting volume controls
     */
    enum Source {
        /**
         * Master volume category
         */
        MASTER("master"),
        
        /**
         * Music volume category
         */
        MUSIC("music"),
        
        /**
         * Record/note block volume category
         */
        RECORD("record"),
        
        /**
         * Weather sounds category
         */
        WEATHER("weather"),
        
        /**
         * Block interaction sounds category
         */
        BLOCK("block"),
        
        /**
         * Hostile mob sounds category
         */
        HOSTILE("hostile"),
        
        /**
         * Neutral/friendly mob sounds category
         */
        NEUTRAL("neutral"),
        
        /**
         * Player-generated sounds category
         */
        PLAYER("player"),
        
        /**
         * Ambient environment sounds category
         */
        AMBIENT("ambient"),
        
        /**
         * Voice/speech sounds category
         */
        VOICE("voice"),
        
        /**
         * User interface sounds category (since 4.22.0, Minecraft 1.21.6)
         */
        UI("ui");
        
        /**
         * Gets source by name
         * @param name the source name
         * @return the source or null
         */
        static @Nullable Source byName(String name);
    }
    
    /**
     * Builder for creating sounds
     */
    interface Builder extends AbstractBuilder<Sound> {
        /**
         * Sets the sound key
         * @param name the sound key
         * @return this builder
         */
        Builder type(Key name);
        
        /**
         * Sets the sound source category
         * @param source the source
         * @return this builder
         */
        Builder source(Source source);
        
        /**
         * Sets the sound volume
         * @param volume the volume (0.0 to Integer.MAX_VALUE)
         * @return this builder
         */
        Builder volume(float volume);
        
        /**
         * Sets the sound pitch
         * @param pitch the pitch (-1.0 to 1.0)
         * @return this builder
         */
        Builder pitch(float pitch);
        
        /**
         * Sets the random seed
         * @param seed the seed
         * @return this builder
         */
        Builder seed(long seed);
    }
    
    /**
     * Sound emitter for positional audio
     */
    interface Emitter {
        // Marker interface for sound emitters (entities, locations, etc.)
    }
}

Usage Examples:

import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.key.Key;

// Basic sound playback
Sound levelUp = Sound.sound(
    Key.key("entity.player.levelup"),
    Sound.Source.PLAYER,
    1.0f,  // volume (0.0 to Integer.MAX_VALUE)
    0.0f   // normal pitch (-1.0 to 1.0)
);
audience.playSound(levelUp);

// Custom sound with different properties
Sound lowPitchBell = Sound.sound()
    .type(Key.key("block.note_block.bell"))
    .source(Sound.Source.BLOCK)
    .volume(0.7f)
    .pitch(0.5f)  // lower pitch
    .build();

// Play sound at specific location
audience.playSound(levelUp, x, y, z);

// High-pitched notification
Sound notification = Sound.sound(
    Key.key("entity.experience_orb.pickup"),
    Sound.Source.PLAYER,
    0.5f,  // quieter
    1.5f   // higher pitch
);

Sound Stop Interface

Interface for stopping sound playback with various filtering options.

/**
 * Represents a request to stop playing sounds
 */
interface SoundStop extends Examinable {
    /**
     * Gets the specific sound to stop (null for any)
     * @return the sound key or null
     */
    @Nullable Key sound();
    
    /**
     * Gets the source category to stop (null for any)
     * @return the source or null
     */
    @Nullable Sound.Source source();
    
    /**
     * Stops all sounds
     * @return sound stop for all sounds
     */
    static SoundStop all();
    
    /**
     * Stops a specific sound by key
     * @param sound the sound key to stop
     * @return sound stop for specific sound
     */
    static SoundStop named(Key sound);
    
    /**
     * Stops sounds from a specific source category
     * @param source the source category
     * @return sound stop for source category
     */
    static SoundStop source(Sound.Source source);
    
    /**
     * Stops a specific sound from a specific source
     * @param sound the sound key
     * @param source the source category
     * @return sound stop for sound and source
     */
    static SoundStop namedOnSource(Key sound, Sound.Source source);
    
    /**
     * Creates a sound stop builder
     * @return new builder
     */
    static Builder builder();
    
    /**
     * Builder for creating sound stop requests
     */
    interface Builder extends AbstractBuilder<SoundStop> {
        /**
         * Sets the sound to stop
         * @param sound the sound key or null for any
         * @return this builder
         */
        Builder sound(@Nullable Key sound);
        
        /**
         * Sets the source category to stop
         * @param source the source or null for any
         * @return this builder
         */
        Builder source(@Nullable Sound.Source source);
    }
}

Usage Examples:

import net.kyori.adventure.sound.SoundStop;

// Stop all sounds
audience.stopSound(SoundStop.all());

// Stop specific sound
audience.stopSound(SoundStop.named(Key.key("entity.player.levelup")));

// Stop all music
audience.stopSound(SoundStop.source(Sound.Source.MUSIC));

// Stop specific sound from specific source
audience.stopSound(SoundStop.namedOnSource(
    Key.key("music.overworld"), 
    Sound.Source.MUSIC
));

// Using builder for complex stop requests
SoundStop complexStop = SoundStop.builder()
    .sound(Key.key("ambient.cave"))
    .source(Sound.Source.AMBIENT)
    .build();

Common Sound Patterns

Sound Effect Library

public class SoundEffects {
    // UI Sounds
    public static final Sound BUTTON_CLICK = Sound.sound(
        Key.key("ui.button.click"), Sound.Source.MASTER, 0.5f, 1.0f);
    
    public static final Sound SUCCESS = Sound.sound(
        Key.key("entity.experience_orb.pickup"), Sound.Source.PLAYER, 0.7f, 1.2f);
    
    public static final Sound ERROR = Sound.sound(
        Key.key("block.note_block.bass"), Sound.Source.PLAYER, 0.8f, 0.5f);
    
    // Game Events
    public static final Sound LEVEL_UP = Sound.sound(
        Key.key("entity.player.levelup"), Sound.Source.PLAYER, 1.0f, 1.0f);
    
    public static final Sound DEATH = Sound.sound(
        Key.key("entity.player.death"), Sound.Source.PLAYER, 1.0f, 1.0f);
    
    // Environmental
    public static final Sound THUNDER = Sound.sound(
        Key.key("entity.lightning_bolt.thunder"), Sound.Source.WEATHER, 0.8f, 1.0f);
    
    public static final Sound RAIN = Sound.sound(
        Key.key("weather.rain"), Sound.Source.WEATHER, 0.3f, 1.0f);
}

Positional Audio

// Play sound at entity location
public void playSoundAtEntity(Audience audience, Sound sound, Entity entity) {
    Location loc = entity.getLocation();
    audience.playSound(sound, loc.getX(), loc.getY(), loc.getZ());
}

// Play sound following an entity
public void playSoundFollowingEntity(Audience audience, Sound sound, Entity entity) {
    audience.playSound(sound, entity); // Assuming entity implements Sound.Emitter
}

// Distance-based volume adjustment
public Sound adjustVolumeByDistance(Sound baseSound, double distance, double maxDistance) {
    float volume = Math.max(0.0f, Math.min(1.0f, (float)(1.0 - distance / maxDistance)));
    return Sound.sound()
        .type(baseSound.name())
        .source(baseSound.source())
        .volume(baseSound.volume() * volume)
        .pitch(baseSound.pitch())
        .build();
}

Dynamic Sound Effects

// Random pitch variation
public Sound withRandomPitch(Sound baseSound, float variation) {
    Random random = new Random();
    float pitchOffset = (random.nextFloat() - 0.5f) * variation;
    float newPitch = Math.max(0.5f, Math.min(2.0f, baseSound.pitch() + pitchOffset));
    
    return Sound.sound(baseSound.name(), baseSound.source(), baseSound.volume(), newPitch);
}

// Volume fade effect (requires multiple sound calls)
public void fadeInSound(Audience audience, Sound baseSound, int steps, long delayMs) {
    for (int i = 0; i <= steps; i++) {
        float volume = (float) i / steps * baseSound.volume();
        Sound fadedSound = Sound.sound(
            baseSound.name(), 
            baseSound.source(), 
            volume, 
            baseSound.pitch()
        );
        
        // Schedule sound with delay (implementation-specific)
        scheduleSound(audience, fadedSound, delayMs * i);
    }
}

// Sound sequence/chain
public void playSoundSequence(Audience audience, Sound... sounds) {
    for (int i = 0; i < sounds.length; i++) {
        // Schedule each sound with delay (implementation-specific)
        scheduleSound(audience, sounds[i], i * 500L); // 500ms between sounds
    }
}

Category-Based Sound Management

// Sound manager for different categories
public class SoundManager {
    public void playUISound(Audience audience, Key soundKey) {
        Sound sound = Sound.sound(soundKey, Sound.Source.MASTER, 0.5f, 1.0f);
        audience.playSound(sound);
    }
    
    public void playGameSound(Audience audience, Key soundKey, float volume) {
        Sound sound = Sound.sound(soundKey, Sound.Source.PLAYER, volume, 1.0f);
        audience.playSound(sound);
    }
    
    public void playAmbientSound(Audience audience, Key soundKey, float volume, float pitch) {
        Sound sound = Sound.sound(soundKey, Sound.Source.AMBIENT, volume, pitch);
        audience.playSound(sound);
    }
    
    // Stop sounds by category
    public void stopAllMusic(Audience audience) {
        audience.stopSound(SoundStop.source(Sound.Source.MUSIC));
    }
    
    public void stopAllAmbient(Audience audience) {
        audience.stopSound(SoundStop.source(Sound.Source.AMBIENT));
    }
    
    public void mutePlayer(Audience audience) {
        audience.stopSound(SoundStop.source(Sound.Source.PLAYER));
    }
}

Sound Keys and Registry

Common Minecraft Sound Keys

// Entity sounds
Key.key("entity.player.levelup")
Key.key("entity.player.death")
Key.key("entity.experience_orb.pickup")
Key.key("entity.villager.yes")
Key.key("entity.villager.no")

// Block sounds
Key.key("block.note_block.bell")
Key.key("block.note_block.bass")
Key.key("block.chest.open")
Key.key("block.chest.close")
Key.key("block.anvil.use")

// UI sounds
Key.key("ui.button.click")
Key.key("ui.toast.challenge_complete")
Key.key("ui.toast.in")
Key.key("ui.toast.out")

// Weather and environment
Key.key("weather.rain")
Key.key("weather.rain.above")
Key.key("entity.lightning_bolt.thunder")
Key.key("ambient.cave")

// Music
Key.key("music.overworld")
Key.key("music.nether")
Key.key("music.end")
Key.key("music.creative")

Custom Sound Registration

// For custom resource packs or plugins
public class CustomSounds {
    public static final Key CUSTOM_NOTIFICATION = Key.key("myserver", "notification");
    public static final Key CUSTOM_SUCCESS = Key.key("myserver", "success");
    public static final Key CUSTOM_ERROR = Key.key("myserver", "error");
    
    public static Sound customNotification() {
        return Sound.sound(CUSTOM_NOTIFICATION, Sound.Source.MASTER, 0.7f, 1.0f);
    }
    
    public static Sound customSuccess() {
        return Sound.sound(CUSTOM_SUCCESS, Sound.Source.PLAYER, 0.8f, 1.1f);
    }
    
    public static Sound customError() {
        return Sound.sound(CUSTOM_ERROR, Sound.Source.PLAYER, 0.6f, 0.8f);
    }
}

Best Practices

Volume and Pitch Guidelines

  • Volume: 0.0-1.0 range, with 0.5-0.8 being good for most UI sounds
  • Pitch: 0.5-2.0 range, with 1.0 being normal pitch
  • Use volume < 0.5 for ambient/background sounds
  • Use volume > 0.8 for important notifications

Source Category Usage

  • MASTER: Universal sounds that should respect master volume
  • PLAYER: Player action sounds (walking, attacking, etc.)
  • BLOCK: Block interaction sounds (breaking, placing)
  • AMBIENT: Background environmental sounds
  • MUSIC: Background music tracks
  • UI: Interface sounds (usually MASTER category)

Performance Considerations

  • Don't spam sounds - limit frequency of sound playback
  • Use sound stopping to prevent audio overlap
  • Consider client-side performance with many simultaneous sounds
  • Cache frequently used Sound objects rather than creating new ones

User Experience

  • Provide audio cues for important events
  • Use consistent sound themes for similar actions
  • Respect player audio preferences through source categories
  • Test sounds across different client settings and hardware

Install with Tessl CLI

npx tessl i tessl/maven-net-kyori--adventure-api

docs

audience-system.md

books-and-inventory.md

boss-bars.md

events-and-interactivity.md

index.md

nbt-data-components.md

resource-packs.md

sound-system.md

text-components.md

text-formatting.md

titles-and-subtitles.md

translation-system.md

tile.json