Wiki 9Minecraft Wiki 9Minecraft

Playsound Command Recipes and Custom Audio Setup

How to trigger vanilla and custom sounds using /playsound, functions, and sound_definitions.json.

5Sections
4Code examples
4Known errors

The /playsound command is the primary method for playing audio cues to specific players at defined world locations in Minecraft Bedrock Edition. Add-on creators rely on it inside mcfunction files, entity animation timelines, and script events to provide instant audio feedback for custom mechanics, UI interactions, and boss encounters.

Syntax and Parameters

At its core, the /playsound command dispatches an instruction from the server to the client, telling the client to play a specific sound event registered in the active resource packs. It does not stream audio data over the network; instead, it sends a string identifier alongside spatial coordinates and volume multipliers. If the client does not have a matching sound definition in its loaded resource packs, nothing happens and no error is thrown in the chat.

Understanding how the volume and minimumVolume parameters interact is the most confusing part of the command. In Bedrock Edition, the volume argument rarely makes a sound louder once it exceeds 1.0. Instead, values above 1.0 increase the radius of the audible sphere. By default, a sound with a volume of 1.0 can be heard within a 16-block radius, attenuating linearly down to zero at the edge. Multiplying the volume multiplies this 16-block attenuation distance.

The minimumVolume parameter guarantees that even if a targeted player is completely outside the audible sphere calculated by the volume argument, they will still hear the sound played right in their ears at this fallback level. This parameter is clamped between 0.0 and 1.0, making it the primary tool for global announcements or background stingers where player distance to the origin should not cause the audio to cut out completely.

ParameterTypeWhat it doesNotes
soundstringThe sound event identifier defined in sound_definitions.json.Uses dot notation by convention (e.g., random.orb, mob.villager.yes).
playertargetThe target selector determining which clients receive the packet.Optional. If omitted, defaults to the command executor if it is a player.
positionx y zThe world coordinates where the sound originates.Supports relative (~) and local (^) coordinates.
volumefloatControls gain between 0.0 and 1.0; controls audible distance above 1.0.A value of 2.0 creates a 32-block audible radius.
pitchfloatPlayback speed and frequency multiplier.1.0 is normal speed. 0.5 is one octave lower (half speed); 2.0 is one octave higher.
minimumVolumefloatFallback volume (0.0 to 1.0) for targeted players outside the audible range.Set to 1.0 to make the sound equally loud everywhere for the target.

Core Command Recipes for Functions

When writing .mcfunction files in your behavior pack, how you structure the /playsound command determines whether the audio feels like a personal UI click, a 3D world event, or a global broadcast. A common mistake is executing a sound at a central command block or world spawn and wondering why players hundreds of blocks away cannot hear it.

To play a sound directly in a player's ears without spatial panning—ideal for custom shop interfaces, quest completions, or error buzzers—you must execute the command at the player's own location, targeting only that specific player (`@s`). By pairing `execute as <target> at @s` with a standard volume of 1.0, the sound originates inside the player's head, ensuring consistent stereo balance regardless of where they are looking or moving.

Conversely, if you are building a custom environmental hazard, like a geyser or a ticking bomb entity, you want true 3D positional audio that fades out naturally as players walk away. In this case, you execute at the entity's position, target all players within a reasonable radius (`@a[r=32]`), and keep the minimumVolume at 0.0. If you want to layer sounds to create a richer custom effect without adding new audio files, you can fire multiple /playsound commands on the same tick with slightly varied pitch values.

BP/functions/audio_recipes.mcfunction
# 1. Personal UI feedback (only the executing player hears it, full volume)
execute as @a[tag=opened_menu] at @s run playsound random.click @s ~ ~ ~ 0.8 1.2 0.8

# 2. Global boss spawn alert (everyone in the dimension hears it regardless of distance)
execute as @a at @s run playsound mob.wither.spawn @s ~ ~ ~ 1.0 0.8 1.0

# 3. Positional 3D world sound from a custom entity (fades out over 32 blocks)
execute at @e[type=my_pack:lava_geyser] run playsound liquid.lavapop @a[r=35] ~ ~ ~ 2.0 0.6 0.0

# 4. Pitch-layered vanilla sounds to fake a custom magic chime
execute at @s run playsound note.chime @a[r=16] ~ ~ ~ 1.0 0.75
execute at @s run playsound note.chime @a[r=16] ~ ~ ~ 1.0 1.0
execute at @s run playsound note.chime @a[r=16] ~ ~ ~ 1.0 1.5
execute at @s run playsound random.orb @a[r=16] ~ ~ ~ 0.4 1.8

Registering Custom Sounds in the Resource Pack

While combining vanilla sounds with pitch shifts is useful, most add-ons eventually need custom `.ogg` or `.fsb` audio files. You cannot reference a file path directly inside the /playsound command. Instead, you must place your audio file inside the `RP/sounds/` directory and map it to a custom string identifier inside `RP/sounds/sound_definitions.json`. Notice that the file path inside the JSON omits the `.ogg` file extension; the engine resolves the extension automatically.

The `category` field in your sound definition dictates which slider in the player's Audio Settings menu controls the volume of your sound. For example, setting it to `ui` ensures that players who turn down `weather` or `hostile` sounds can still hear your custom menu clicks. The `max_distance` and `min_distance` fields give you granular control over spatial attenuation directly in the resource pack, overriding standard distance behavior when needed.

If you are adding long ambient tracks or custom music discs, you must set `stream` to `true` inside the sound array object. Streaming tells the Bedrock audio engine to read the audio file in chunks from the disk rather than loading the entire decompressed waveform into memory at once. Failing to stream long audio files is a frequent cause of memory spikes and crashes on mobile and console devices.

RP/sounds/sound_definitions.json
{
  "format_version": "1.14.0",
  "sound_definitions": {
    "my_pack.ui.quest_complete": {
      "category": "ui",
      "sounds": [
        {
          "name": "sounds/custom/ui/quest_chime",
          "volume": 0.9,
          "pitch": 1.0,
          "load_on_low_memory": true
        }
      ]
    },
    "my_pack.ambient.Generator_hum": {
      "category": "block",
      "max_distance": 24.0,
      "min_distance": 2.0,
      "sounds": [
        {
          "name": "sounds/custom/blocks/hum_loop_1",
          "volume": 0.7,
          "weight": 10
        },
        {
          "name": "sounds/custom/blocks/hum_spark",
          "volume": 0.85,
          "weight": 2
        }
      ]
    },
    "my_pack.music.boss_theme": {
      "category": "music",
      "sounds": [
        {
          "name": "sounds/custom/music/ancient_guardian",
          "stream": true,
          "volume": 0.5
        }
      ]
    }
  }
}

Triggering Playsound from Entity Timelines

Hardcoding /playsound inside behavior pack animations is a reliable way to synchronize audio with entity states, attack windups, or death sequences. While resource pack animations have their own `sound_effects` key that plays audio purely client-side, using behavior pack timelines gives you full access to target selectors, conditional command execution, and pitch randomization via separate commands.

To set this up, define a behavior animation in `BP/animations/` and list your /playsound commands at specific timestamp keys (measured in seconds). When you link this animation in your entity's `BP/entities/` definition and trigger it via an animation controller or the `scripts/animate` array, the server dispatches the sound commands at the exact tick corresponding to the timestamp.

When running /playsound from an entity timeline, the execution context (`@s` and `~ ~ ~`) automatically defaults to the entity itself and its current coordinates. You should almost always target `@a[r=<distance>]` in these commands rather than `@a` globally, unless your entity is a world boss whose roar is meant to be heard across the entire dimension.

BP/animations/mech_golem.animation.json
{
  "format_version": "1.10.0",
  "animations": {
    "animation.mech_golem.slam_attack": {
      "animation_length": 2.0,
      "loop": false,
      "timeline": {
        "0.0": [
          "/playsound mob.irongolem.throw @a[r=24] ~ ~ ~ 1.2 0.6"
        ],
        "0.75": [
          "/playsound my_pack.ambient.Generator_hum @a[r=24] ~ ~ ~ 1.0 1.4"
        ],
        "1.2": [
          "/playsound random.explode @a[r=32] ~ ~ ~ 1.5 0.8",
          "/playsound block.anvil.land @a[r=24] ~ ~ ~ 0.6 0.5"
        ]
      }
    }
  }
}

Playing Sounds via the Script API

If your add-on uses the `@minecraft/server` Script API, you do not need to call `runCommandAsync("playsound ...")` to trigger audio. Both the `Player` class and the `Dimension` class provide native methods for playing sounds, which avoid command string parsing overhead and allow you to compute dynamic pitch and volume values directly in JavaScript.

The difference between `Player.playSound()` and `Dimension.playSound()` mirrors the difference between personal UI sounds and positional 3D world sounds. Calling `player.playSound(soundId, PlayerSoundOptions)` sends the audio packet exclusively to that individual player. If you omit the location property inside the options object, the sound plays right at the player's current position.

In contrast, `dimension.playSound(soundId, location, WorldSoundOptions)` broadcasts the sound from a fixed `Vector3` coordinate in that dimension to all nearby players who are within audible range. This method is ideal for custom block interactions, projectile impacts, or environmental mechanics managed by script events.

BP/scripts/audio_manager.js
import { world } from "@minecraft/server";

// Example 1: Personal UI sound with randomized pitch when using a custom item
world.afterEvents.itemUse.subscribe((event) => {
  const player = event.source;
  if (event.itemStack.typeId === "my_pack:magic_wand") {
    const randomPitch = 0.9 + Math.random() * 0.3;
    player.playSound("my_pack.ui.quest_complete", {
      pitch: randomPitch,
      volume: 0.8
    });
  }
});

// Example 2: 3D positional sound in the world when a specific block is broken
world.afterEvents.playerBreakBlock.subscribe((event) => {
  if (event.brokenBlockPermutation.type.id === "my_pack:crystal_ore") {
    const dim = event.dimension;
    const loc = event.block.location;
    
    dim.playSound("random.glass", loc, {
      pitch: 0.6,
      volume: 1.5
    });
  }
});

Which versions this applies to

Applies to all modern Minecraft Bedrock versions (1.16.0 through 1.21+). The /playsound command, mcfunctions, and sound_definitions.json require no experimental toggles. Using the Script API methods requires declaring the @minecraft/server dependency in your behavior pack manifest.json, which is stable and does not require the Beta APIs toggle for playSound.

When it does not work

What you seeWhyThe fix
Command outputs 'Played sound ... to [Player]', but no audio is heard in-game.The /playsound command only validates that a target player was found; it does not check if the sound string actually exists in the resource pack. This happens when the identifier in sound_definitions.json is misspelled, the file path inside the definition includes the '.ogg' extension by mistake, or the audio file is encoded as a renamed MP3/WAV instead of a true Vorbis OGG file.Remove '.ogg' from all paths in RP/sounds/sound_definitions.json, verify the exact string identifier, and re-export your audio file using a proper converter (like Audacity) set to OGG Vorbis, 44100Hz, Mono or Stereo.
Positional sounds play across the entire map at the exact same loudness instead of fading with distance.Your audio file is exported in Stereo (2 channels) instead of Mono (1 channel). The Bedrock 3D audio engine cannot spatially pan or attenuate stereo files in world space; it plays them flatly in the player's headphones until they cross the hard cutoff boundary.Convert all 3D world, block, and entity sound effects to Mono (single channel) .ogg files. Reserve Stereo files strictly for background music and non-positional UI sounds.
Chat or Content Log shows 'No targets matched selector' when running /playsound from an entity or command block.You omitted the player target parameter or used '@s' inside a command block or a non-player entity timeline. Because /playsound sends a client packet to a player's device, a pig or a command block cannot be the recipient of a sound.Always specify a player selector such as '@a[r=24]' or '@p' when executing /playsound from a non-player source.
Custom music or long ambient sound cuts off abruptly or fails to play on mobile devices.The audio file is large (several megabytes), and 'stream': true is missing from its entry in sound_definitions.json, causing the audio engine to reject loading the full uncompressed buffer into RAM.Add '"stream": true' inside the sound object in RP/sounds/sound_definitions.json for any audio track longer than a few seconds, and pair it with the /stopsound command if you need to cut it off early.

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.