Coding Quests
The Scroll Library
Tutorials

Godot 4 Audio Tutorial: Sound Effects and Music

June 16, 20265 min read

Audio is the cheapest way to make a game feel alive and the easiest thing to leave until last. A jump with a sound is twice the jump. A hit that goes "thunk" lands harder than the same hit in silence. Godot's audio system is small once you see the three pieces, so let's wire it up properly.

The player nodes

Godot plays sound through three node types, and picking the right one matters:

  • AudioStreamPlayer plays a sound at the same volume everywhere. Use it for music and UI clicks.
  • AudioStreamPlayer2D plays from a position in a 2D world, so it gets quieter with distance and pans left or right. Use it for footsteps, explosions, anything in the world.
  • AudioStreamPlayer3D is the same idea in 3D.

Drop one in, set its stream to a sound file, and play it:

GDScript
@onready var jump_sound: AudioStreamPlayer = $JumpSound
func jump() -> void:
velocity.y = jump_velocity
jump_sound.play()

Audio buses: mix once, control everywhere

Open the Audio panel at the bottom of the editor. By default there's one bus, Master. Add two more, Music and SFX. Then set each player node's Bus property to the right one.

Now every sound effect flows through SFX and all music through Music, which means you can change the volume of one without touching the other. This is exactly what an options menu needs. Set it up early and a volume slider becomes trivial later.

Volume sliders done right

Here's the part that confuses people. Audio volume in Godot is measured in decibels, which aren't linear. A slider that goes 0 to 1 needs converting, or the bottom half of the slider does almost nothing. Use linear_to_db():

GDScript
func _on_music_slider_changed(value: float) -> void:
# value is 0.0 to 1.0 from the slider
var bus := AudioServer.get_bus_index("Music")
AudioServer.set_bus_volume_db(bus, linear_to_db(value))

linear_to_db() maps a friendly 0-to-1 range onto the decibel scale so the slider feels natural the whole way down. Skip it and your slider will feel broken.

Music that survives scene changes

If you play music with a node in your level, it restarts every time you change scenes. Annoying. The fix is an autoload: a small persistent script that holds your music player and keeps it going across scenes.

GDScript
# music.gd (autoload named "Music")
extends Node
@onready var player: AudioStreamPlayer = $AudioStreamPlayer
func play(track: AudioStream) -> void:
if player.stream == track and player.playing:
return # already playing this track, don't restart it
player.stream = track
player.play()

Call Music.play(my_track) from anywhere and the music keeps rolling through scene transitions.

A sound effect tip

If the same sound fires rapidly (rapid gunfire, coins), a single player cuts itself off on each new play(). For those, use AudioStreamPlayer with a polyphony setting bumped up, or keep a small pool of players and rotate through them. For most sounds, though, one node per sound is perfectly fine. Don't over-engineer it until you actually hear the problem.

Where to use it

Sound is the layer of polish that makes everything you've built feel finished. Hook it into the systems from your other quests: a pickup sound on inventory items, a hit sound on the health and damage system, a click on every menu button. The free Inventory System quest is a good place to practice, since every item pickup is begging for a satisfying sound.

FAQ

What's the difference between AudioStreamPlayer and AudioStreamPlayer2D?

AudioStreamPlayer plays at a constant volume everywhere, which suits music and UI sounds. AudioStreamPlayer2D plays from a location in the world, so it fades with distance and pans based on position, which suits footsteps, explosions, and other in-world sounds.

How do I make a volume slider in Godot 4?

Route your sounds through an audio bus like Music or SFX, then in the slider's changed handler convert the 0-to-1 value with linear_to_db() and pass it to AudioServer.set_bus_volume_db(). The conversion is what makes the slider feel natural across its whole range.

How do I keep music playing between scenes?

Put your music player in an autoload, a persistent script Godot keeps alive across scene changes. Call its play function from anywhere, and guard against restarting the same track so the music continues smoothly instead of resetting on every scene load.

godottutorialaudiosound

Reading is the map. The quest is the territory.

Build this for real in the Inventory System Quest. It's free, no card needed.

Start the Quest
Written by Coding Quests

We teach Godot 4 by making you build complete systems: inventories, save systems, souls-like controllers, enemy AI. The scrolls are free. The quests are where it sticks.