godot-audio
gamedev-skills/awesome-gamedev-agent-skills
Play, mix, and sync audio in Godot 4.7 with buses, effects, and beat-accurate timing.
What is godot-audio?
Godot Audio covers playing SFX and music via AudioStreamPlayer nodes, routing them through buses (Master/Music/SFX), controlling volume in decibels, adding effects, and syncing gameplay to music beats. Use this when implementing audio playback, bus mixing, volume control, or rhythm-locked mechanics in a Godot 4.x project.
- Play non-positional and 3D positional audio with AudioStreamPlayer, AudioStreamPlayer2D, and AudioStreamPlayer3D nodes
- Route audio through named buses with independent volume, mute, solo, and effect chains
- Control volume in decibels and convert between linear and dB scales using linear_to_db and db_to_linear
- Crossfade between music tracks with tweens and manage overlapping SFX with polyphonic streams
- Sync gameplay events to music playback with latency-compensated timing using get_playback_position() and get_time_since_last_mix()
- Add bus effects (reverb, compressor, EQ) and manage audio ducking patterns
How to install godot-audio
npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill godot-audio- Godot 4.7 or compatible 4.x version
- Audio assets in .ogg (music/loops) or .wav (short SFX) format already imported into the project
- Basic familiarity with Godot's node system and GDScript
How to use godot-audio
- 1.Create AudioStreamPlayer, AudioStreamPlayer2D, or AudioStreamPlayer3D nodes in your scene and assign audio streams to their stream property
- 2.Define named buses (Master, Music, SFX) in the Audio panel (bottom dock) and assign each player node to a bus via its bus property
- 3.Call play() on players or use autoplay for music that starts with the scene; use pitch_scale for variation on repeated SFX
- 4.Control bus volume from code using AudioServer.get_bus_index() and AudioServer.set_bus_volume_db(), converting linear 0–1 sliders with linear_to_db()
- 5.For beat-accurate timing, call get_playback_position() + AudioServer.get_time_since_last_mix() - AudioServer.get_output_latency()
- 6.Use tweens to crossfade between tracks by animating volume_db on two players, then swap their roles
Use cases
- Fire-and-forget sound effects with pitch variation to avoid listener fatigue
- Volume sliders in settings menus that control music and SFX buses independently
- Crossfading between exploration and combat music tracks
- Rhythm-game or beat-synced mechanic that triggers actions on the downbeat
- 3D positional audio for footsteps, ambient sounds, and directional effects in 3D scenes
- Godot game developers implementing audio systems
- Audio programmers setting up bus hierarchies and mixing workflows
- Game designers syncing gameplay mechanics to music timing
- Developers building rhythm games or music-driven interactive experiences
godot-audio FAQ
Audio is logarithmic; volume_db uses decibels, not linear scale. 0 dB is unchanged, -80 dB is nearly silent. Convert a 0–1 slider with linear_to_db(max(value, 0.0001)) to avoid -inf at zero.
Use separate AudioStreamPlayer nodes per sound, an AudioStreamPolyphonic stream for overlapping copies, or spawn players dynamically and free them on the finished signal.
Check the import settings: .ogg files need Loop enabled in the import panel, and AudioStreamWAV nodes need loop_mode set. Verify the stream itself supports looping.
Ensure an AudioListener3D or Camera3D exists in the scene to hear 3D players, set appropriate max_distance and attenuation curves, and confirm the bus is not muted.
get_playback_position() updates per audio mix, not per frame. Add get_time_since_last_mix() and subtract get_output_latency() for sub-frame accuracy.
Full instructions (SKILL.md)
Source of truth, from gamedev-skills/awesome-gamedev-agent-skills.
name: godot-audio description: > Play and mix audio in Godot 4.7: AudioStreamPlayer (2D/3D variants), audio buses with volume/mute and effects, music vs SFX routing, db/linear volume, and precise sync-to-beat playback timing. Use when playing sounds or music in a Godot project, routing AudioStreamPlayer nodes to buses, adjusting bus volume via AudioServer, or syncing gameplay to the beat.
Godot Audio (4.x)
Play SFX and music, route them through buses, control volume in decibels, and time gameplay to the beat. Targets Godot 4.7.
When to use
- Use when playing sound effects or music, routing audio to buses (Master/Music/SFX), adjusting volume/mute from code, adding bus effects (reverb, compressor), positional 3D audio, or syncing events to music.
When not to use: engine-agnostic audio design (adaptive music structure, mixing
philosophy, ducking patterns) → audio-design; importing/encoding assets outside Godot.
Core workflow
- Pick the player node:
AudioStreamPlayer— non-positional (music, UI, global SFX).AudioStreamPlayer2D/AudioStreamPlayer3D— positional; volume/pan from distance.
- Assign an
AudioStreamtostream(.oggfor music/loops,.wavfor short SFX) andplay(). Setautoplayfor music that starts with the scene. - Route to a bus. Set the player's
busto a named bus (e.g."Music","SFX"). Define buses in the Audio panel (bottom dock); each can have volume, mute, solo, and effects. - Control volume in dB, not linear (audio is logarithmic).
0 dB= unchanged,-80 dB≈ silent. Convert withlinear_to_db/db_to_linear. - Drive volume/mute from code with
AudioServerby bus index. - For rhythm, compute precise playback time using output latency compensation.
Patterns
1. One-shot SFX (fire-and-forget)
@onready var sfx: AudioStreamPlayer = $Sfx # stream assigned in the editor
func play_jump() -> void:
sfx.pitch_scale = randf_range(0.95, 1.05) # slight variation avoids fatigue
sfx.play()
# For many overlapping copies, use an AudioStreamPlayer with an
# AudioStreamPolyphonic stream, or spawn short-lived players and free on `finished`.
2. Set a bus's volume and mute via AudioServer
func set_music_volume(linear_0_to_1: float) -> void:
var bus := AudioServer.get_bus_index("Music")
# Convert a 0..1 slider to decibels; clamp avoids -inf at 0.
AudioServer.set_bus_volume_db(bus, linear_to_db(maxf(linear_0_to_1, 0.0001)))
func toggle_sfx(muted: bool) -> void:
AudioServer.set_bus_mute(AudioServer.get_bus_index("SFX"), muted)
3. Crossfade between two music tracks
@onready var a: AudioStreamPlayer = $MusicA
@onready var b: AudioStreamPlayer = $MusicB
func crossfade_to(stream: AudioStream, secs := 1.5) -> void:
b.stream = stream
b.volume_db = -40.0
b.play()
var tw := create_tween().set_parallel(true)
tw.tween_property(a, "volume_db", -40.0, secs) # fade out current
tw.tween_property(b, "volume_db", 0.0, secs) # fade in next
tw.chain().tween_callback(a.stop)
var tmp := a; a = b; b = tmp # swap roles
4. Beat-accurate timing (compensate for output latency)
@onready var music: AudioStreamPlayer = $Music
func get_playback_time() -> float:
# Add time since the last audio mix, subtract output latency, for sub-frame accuracy.
var t := music.get_playback_position() + AudioServer.get_time_since_last_mix()
return t - AudioServer.get_output_latency()
Pitfalls
- Treating volume as linear.
volume_db/set_bus_volume_dbare decibels. Settingvolume_db = 0.5is nearly full volume, not half. Map sliders withlinear_to_db. linear_to_db(0.0)is-inf. Clamp the linear value to a small minimum (e.g.0.0001) before converting, or special-case 0 → mute.- Bus name typos fail quietly.
get_bus_index("Muisc")returns-1; calls then error or no-op. Match the exact bus name from the Audio panel. - Short SFX cut off when the same player is retriggered. Use separate players, an
AudioStreamPolyphonic, orAudioStreamPlayerper-shot freed onfinished. - Music doesn't loop unless the import/stream loop is enabled (
.oggimport has a Loop option;AudioStreamWAVhasloop_mode). - Syncing to
get_playback_position()alone is jittery — it updates per audio mix, not per frame; addget_time_since_last_mix()and subtractget_output_latency(). - 3D audio inaudible → no
AudioListener3D/Camera3Dto hear it, ormax_distance/ attenuation too tight, or wrong bus muted.
References
- For the bus layout (
.tres), adding effects (reverb/compressor/EQ) and side-chain ducking,AudioStreamPolyphonic/AudioStreamInteractive, microphone capture, and procedural audio withAudioStreamGenerator, readreferences/buses-and-effects.md.
Related skills
audio-design— engine-agnostic adaptive music, mixing, and ducking practice.godot-animation— syncing animation/Tween toget_playback_position().godot-ui-control— volume sliders wired toAudioServer.
Related skills
More from gamedev-skills/awesome-gamedev-agent-skills and the wider catalog.

godot-csharp
Write Godot 4.7 game code in C# with type-safe nodes, signals as events, and GDScript interop.

godot-export
Export and build Godot 4.x projects for Windows, macOS, Linux, Web, Android, and headless servers.

godot-gdscript
Write idiomatic GDScript 2.0 for Godot 4.7 with static typing, lifecycle callbacks, and signals.

godot-multiplayer
Build networked Godot 4.7 games with ENet, RPCs, and state replication.

godot-nodes-scenes
Structure Godot 4.x games with scenes, nodes, and runtime instancing.

godot-physics
Configure Godot 4.x physics bodies, collision layers/masks, overlap detection, and raycasts in 2D and 3D.