Skills に戻る
gamedev-skills/awesome-gamedev-agent-skillsチェック済み

SKILL DETAIL

godot-audio

gamedev-skills/awesome-gamedev-agent-skills/godot-audio

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.

インストール · 287出典を見る

Installation

npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill godot-audio

スキルファイル

SKILL.md

最終同期 · 2026/10/22

references/buses-and-effects.md›
# Audio buses & effects reference (Godot 4.7)

Depth companion to `godot-audio`.

## The bus layout

Buses are configured in the editor's **Audio** panel (bottom dock) and saved as a bus
layout resource (`default_bus_layout.tres` by default; set in Project Settings > Audio).

- **Master** always exists and is the final output. Every other bus routes to Master (or
  to another bus via **Send**).
- Add buses like `Music`, `SFX`, `UI`, `Ambience`. Set each player node's `bus` to route.
- Per bus: **volume (dB)**, **mute**, **solo**, **bypass effects**, and a chain of effects.

## AudioServer API

```gdscript
var i := AudioServer.get_bus_index("Music")
AudioServer.set_bus_volume_db(i, linear_to_db(0.8))
AudioServer.set_bus_mute(i, true)
AudioServer.set_bus_solo(i, true)
AudioServer.get_bus_count()
AudioServer.add_bus(at_position)              # runtime bus creation
AudioServer.set_bus_send(i, "Master")
AudioServer.add_bus_effect(i, AudioEffectReverb.new())
AudioServer.get_bus_effect(i, effect_idx)
AudioServer.set_bus_effect_enabled(i, effect_idx, false)
AudioServer.get_output_latency()
AudioServer.get_time_since_last_mix()
```

Volume helpers: `linear_to_db(linear)` and `db_to_linear(db)`.

## Effects

Add `AudioEffect*` resources to a bus (editor or `add_bus_effect`):

- `AudioEffectReverb`, `AudioEffectDelay`, `AudioEffectChorus`, `AudioEffectDistortion`.
- `AudioEffectEQ6/EQ10/EQ21`, `AudioEffectLowPassFilter`, `AudioEffectHighPassFilter`.
- `AudioEffectCompressor`, `AudioEffectLimiter` (mastering).
- `AudioEffectPitchShift`, `AudioEffectSpectrumAnalyzer` (for visualizers/beat detection).
- `AudioEffectCapture` / `AudioEffectRecord` (read/record bus output).

## Side-chain ducking (music dips under dialogue/SFX)

1. Put music on a `Music` bus and add an `AudioEffectCompressor` to it.
2. Set the compressor's **Sidechain** to the bus whose loudness should trigger ducking
   (e.g. `Voice`). When `Voice` is loud, the compressor lowers `Music`.
3. Tune threshold/ratio/attack/release for a natural dip and recovery.

## Polyphony and interactive music

- `AudioStreamPolyphonic` — one player that can play many overlapping streams; grab a
  `AudioStreamPlaybackPolyphonic` from `get_stream_playback()` and call `play_stream(...)`.
- `AudioStreamInteractive` — define clips and transitions for adaptive music that switches
  between sections on cue (4.7). `AudioStreamSynchronized` plays layered stems together.
- `AudioStreamRandomizer` — pick a random stream/pitch per play (great for footsteps).

## Positional audio (2D/3D)

- `AudioStreamPlayer2D`: `max_distance`, `attenuation`, `panning_strength`, `area_mask`.
- `AudioStreamPlayer3D`: `unit_size`, `max_distance`, `attenuation_model`
  (inverse/inverse-square/log/disabled), `panning_strength`, doppler via the player or
  camera. A `Camera3D` acts as the default listener; add an `AudioListener3D` to override.

## Procedural / generated audio

`AudioStreamGenerator` + `AudioStreamGeneratorPlayback.push_frame(Vector2)` lets you push
raw stereo samples for synthesis. Set `mix_rate` and `buffer_length`; keep the buffer
filled in `_process` to avoid underruns.

## Sync-to-beat recipe

```gdscript
const BPM := 120.0
var sec_per_beat := 60.0 / BPM
var last_beat := -1

func _process(_d: float) -> void:
    var t := music.get_playback_position() + AudioServer.get_time_since_last_mix() \
             - AudioServer.get_output_latency()
    var beat := int(t / sec_per_beat)
    if beat != last_beat:
        last_beat = beat
        _on_beat(beat)        # spawn, flash, or step a rhythm here
```
SKILL.md›
---
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

1. **Pick the player node:**
   - `AudioStreamPlayer` — non-positional (music, UI, global SFX).
   - `AudioStreamPlayer2D` / `AudioStreamPlayer3D` — positional; volume/pan from distance.
2. **Assign an `AudioStream`** to `stream` (`.ogg` for music/loops, `.wav` for short SFX)
   and `play()`. Set `autoplay` for music that starts with the scene.
3. **Route to a bus.** Set the player's `bus` to a named bus (e.g. `"Music"`, `"SFX"`).
   Define buses in the Audio panel (bottom dock); each can have volume, mute, solo, and
   effects.
4. **Control volume in dB**, not linear (audio is logarithmic). `0 dB` = unchanged,
   `-80 dB` ≈ silent. Convert with `linear_to_db`/`db_to_linear`.
5. **Drive volume/mute from code** with `AudioServer` by bus index.
6. **For rhythm**, compute precise playback time using output latency compensation.

## Patterns

### 1. One-shot SFX (fire-and-forget)

```gdscript
@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

```gdscript
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

```gdscript
@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)

```gdscript
@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_db` are decibels. Setting
  `volume_db = 0.5` is nearly full volume, not half. Map sliders with `linear_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`, or `AudioStreamPlayer` per-shot freed on `finished`.
- **Music doesn't loop** unless the import/stream loop is enabled (`.ogg` import has a
  Loop option; `AudioStreamWAV` has `loop_mode`).
- **Syncing to `get_playback_position()` alone is jittery** — it updates per audio mix,
  not per frame; add `get_time_since_last_mix()` and subtract `get_output_latency()`.
- **3D audio inaudible** → no `AudioListener3D`/`Camera3D` to hear it, or `max_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 with `AudioStreamGenerator`, read `references/buses-and-effects.md`.

## Related skills

- `audio-design` — engine-agnostic adaptive music, mixing, and ducking practice.
- `godot-animation` — syncing animation/Tween to `get_playback_position()`.
- `godot-ui-control` — volume sliders wired to `AudioServer`.