Przejdź do treści
Biblioteka skilli
Programowanie · Budowanie i kod

godot-audio-systems

/godot-audio-systems

Dostarcza wzorce dźwięku w Godot: warianty AudioStreamPlayer, miksowanie przez AudioBus, efekty, pule odtwarzaczy, przejścia muzyki i generowanie dźwięku proceduralnego.

Repozytorium
dotfiles ↗
Licencja
MIT
Ostatnia zmiana repozytorium
27.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
14
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
0
Przestarzałość

Brak sygnałów. Repozytorium zmienione 27.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Dostarcza wzorce dźwięku w Godot: warianty AudioStreamPlayer, miksowanie przez AudioBus, efekty, pule odtwarzaczy, przejścia muzyki i generowanie dźwięku proceduralnego.

Oryginalny opis (EN)

Expert patterns for Godot audio including AudioStreamPlayer variants (2D positional, 3D spatial), AudioBus mixing architecture, dynamic effects (reverb, EQ,compression), audio pooling for performance, music transitions (crossfade, bpm-sync), and procedural audio generation. Use for music systems, sound effects, spatial audio, or audio-reactive gameplay. Trigger keywords: AudioStreamPlayer, AudioStreamPlayer2D, AudioStreamPlayer3D, AudioBus, AudioServer, AudioEffect, music_crossfade, audio_pool, positional_audio, reverb, bus_volume.

Jak działa

  1. NEVER Do (Expert Audio Rules)
  2. Available Scripts
  3. AudioStreamPlayer Variants
  4. AudioBus Architecture
  5. Audio Pooling (Performance)
  6. Music Transitions
  7. Dynamic Audio Effects
  8. Procedural Audio
  9. Advanced Patterns
  10. Performance Optimization
Sekcje z nagłówków SKILL.md, w oryginale · 489 linii, 1 613 słów
Podgląd SKILL.md
---
name: godot-audio-systems
description: "Expert patterns for Godot audio including AudioStreamPlayer variants (2D positional, 3D spatial), AudioBus mixing architecture, dynamic effects (reverb, EQ,compression), audio pooling for performance, music transitions (crossfade, bpm-sync), and procedural audio generation. Use for music systems, sound effects, spatial audio, or audio-reactive gameplay. Trigger keywords: AudioStreamPlayer, AudioStreamPlayer2D, AudioStreamPlayer3D, AudioBus, AudioServer, AudioEffect, music_crossfade, audio_pool, positional_audio, reverb, bus_volume."
---

# Audio Systems

Expert guidance for Godot's audio engine and mixing architecture.

## NEVER Do (Expert Audio Rules)

### Mixing & Buses
- **NEVER set bus volume with linear values** — `set_bus_volume_db()` is logarithmic. Use `linear_to_db()` for sliders OR everything will sound too loud until the last 5%.
- **NEVER skip 'Bus Routing'** — Playing music on the 'SFX' bus makes volume menus useless. Strictly route every player to its dedicated sub-bus (Music, SFX, UI, Voice).
- **NEVER use 'Master' for gameplay sounds** — Dedicate Master to final limiting. Route all gameplay to sub-groups so you can mute/duck categories.

### Positional & Spatial
- **NEVER use 3D players without an Attenuation Model** — Default is NONE. If you don't set it to `Inverse Distance`, a whisper on the other side of the map will be global volume.
- **NEVER play 3D sounds exactly on top of the listener** — Causes "Panning Jitter" where the sound snaps between Left/Right speakers. Offset by `0.1` units.
- **NEVER forget Doppler for high-speed objects** — A car flying by without `DOPPLER_TRACKING_PHYSICS_STEP` feels flat and static.

### Performance & Polish
- **NEVER spam same-frame sounds** — Playing 50 explosions at once causes constructive interference (clipping/distortion). Use a `Limiter` (`audio_voice_limiter_manager.gd`).
- **NEVER instantiate nodes for one-shots** — Creating a node, playing a 0.5s clap, and `queue_free()`ing causes frame-time spikes. Use a Pool.
- **NEVER skip Crossfades/Transitions** — Abrupt music cuts break immersion. Always use a 0.5s-1.0s `Tween` to bridge tracks.

---

## Available Scripts

> **MANDATORY**: Read the appropriate script before implementing the corresponding pattern.

### [audio_voice_pool_manager.gd](scripts/audio_voice_pool_manager.gd)
Expert high-performance voice pooler with priority-based 'voice stealing' logic.

### [audio_occlusion_raycast.gd](scripts/audio_occlusion_raycast.gd)
Professional Raycast-based audio occlusion for dynamic muffling behind walls.

### [audio_adaptive_music_player.gd](scripts/audio_adaptive_music_player.gd)
BPM-synced horizontal re-sequencer for seamless musical transitions.

### [audio_reactive_visualizer_component.gd](scripts/audio_reactive_visualizer_component.gd)
Expert FFT spectrum analysis component for driving logic-to-data visuals.

### [audio_bus_ducker_logic.gd](scripts/audio_bus_ducker_logic.gd)
Professional sidechain-style bus ducking (Dialogue-over-Music).

### [audio_procedural_generator_synth.gd](scripts/audio_procedural_generator_synth.gd)
Expert real-time synthesizer for procedural hums, engines, and signals.

### [audio_environmental_reverb_zone.gd](scripts/audio_environmental_reverb_zone.gd)
Dynamic reverb/bus effect management via Area3D trigger zones.

### [audio_voice_limiter_manager.gd](scripts/audio_voice_limiter_manager.gd)
Concurrency manager that prevents 'Ear Bleed' by capping identical SFX instances.

### [audio_linear_volume_interpolator.gd](scripts/audio_linear_volume_interpolator.gd)
Expert helper for smooth, musically-accurate UI volume slider mapping.

### [audio_footstep_surface_selector.gd](scripts/audio_footstep_surface_selector.gd)
Physics-driven surface detection and sound-bank selector for footsteps.

---

## AudioStreamPlayer Variants

### AudioStreamPlayer (Global/UI)

```gdscript
# No spatial positioning, same volume everywhere
# Use for: Music, UI sounds, voiceovers

@onready var music := AudioStreamPlayer.new()

func _ready() -> void:
    music.stream = load("res://audio/music_main.ogg")
    music.volume_db = -10  # Quieter
    music.autoplay = false
    music.bus = "Music"  # Route to Music bus
    add_child(music)
    music.play()
```

### AudioStreamPlayer2D (Positional)

```gdscript
# 2D panning based on distance from camera
# Use for: 2D games, top-down audio cues

extends Area2D

@onready var footstep := AudioStreamPlayer2D.new()

func _ready() -> void:
    footstep.stream = load("res://audio/footstep.ogg")
    footstep.max_distance = 500  # Audible range (pixels)
    footstep.attenuation = 2.0  # Falloff curve (higher = faster fadeout)
    add_child(footstep)

func play_footstep() -> void:
    if not footstep.playing:
        footstep.play()
```

### AudioStreamPlayer3D (Spatial)

```gdscript
# 3D spatial audio with doppler, reverb send
# Use for: 3D games, realistic sound positioning

extends Node3D

@onready var explosion := AudioStreamPlayer3D.new()

func _ready() -> void:
    explosion.stream = load("res://audio/explosion.ogg")
    explosion.unit_size = 10.0  # Size of sound source
    explosion.max_distance = 100.0  # Range
    explosion.attenuation_model = AudioStreamPlayer3D.ATTENUATION_INVERSE_DISTANCE
    explosion.doppler_tracking = AudioStreamPlayer3D.DOPPLER_TRACKING_PHYSICS_STEP
    add_child(explosion)
    
    explosion.play()
```

---

## AudioBus Architecture

### Bus Setup (Project Settings)

```
Master (always exists)
  ├─ Music
  │   └─ Effects: Compressor, EQ
  ├─ SFX
  │   └─ Effects: Reverb (for environment)
  └─ Ambient
      └─ Effects: LowPassFilter (muffled ambience)
```

### Volume Control (Decibels)

```gdscript
# ❌ BAD: Linear volume (doesn't work)
AudioServer.set_bus_volume_db(music_bus_idx, 0.5)  # WRONG!

# ✅ GOOD: Use decibels
var music_bus := AudioServer.get_bus_index("Music")
AudioServer.set_bus_volume_db(music_bus, -10)  # -10 dB (quieter)

# Convert linear (0.0-1.0) to dB:
var linear_volume := 0.5  # 50%
var db := linear_to_db(linear_volume)  # ~-6 dB
AudioServer.set_bus_volume_db(music_bus, db)

# Convert dB to linear:
var current_db := AudioServer.get_bus_volume_db(music_bus)
var linear := db_to_linear(current_db)
print("Current volume: %d%%" % int(linear * 100))
```

### Mute Bus

```gdscript
func toggle_mute(bus_name: String) -> void:
    var bus_idx := AudioServer.get_bus_index(bus_name)
    var is_muted := AudioServer.is_bus_mute(bus_idx)
    AudioServer.set_bus_mute(bus_idx, not is_muted)
```

---

## Audio Pooling (Performance)

### Problem: Creating Players Every Frame

```gdscript
# ❌ BAD: Creates 60 new nodes/second at 60 FPS
func play_footstep() -> void:
    var player := AudioStreamPlayer.new()
    add_child(player)
    player.stream = load("res://audio/footstep.ogg")
    player.finished.connect(player.queue_free)
    player.play()
    # Result: 3600 nodes created in 1 minute!
```

### Solution: Audio Pool

```gdscript
# audio_pool.gd (AutoLoad)
extends Node

const POOL_SIZE = 10
var pool: Array[AudioStreamPlayer] = []
var pool_index := 0

func _ready() -> void:
    # Pre-create players
    for i in range(POOL_SIZE):
        var player := AudioStreamPlayer.new()
        player.bus = "SFX"
        add_child(player)
        pool.append(player)

func play_sound(stream: AudioStream, volume_db := 0.0) -> void:
    var player := pool[pool_index]
    pool_index = (pool_index + 1) % POOL_SIZE  # Round-robin
    
    # Stop previous sound if still playing
    if player.playing:
        player.stop()
    
    player.stream = stream
    player.volume_db = volume_db
    player.play()

# Usage:
AudioPool.play_sound(load("res://audio/coin.ogg"), -5.0)
```

---

## Music Transitions

### Crossfade Between Tracks

```gdscript
# music_manager.gd (AutoLoad)
extends Node

@onready var track_a := AudioStreamPlayer.new()
@onready var track_b := AudioStreamPlayer.new()

var current_track: AudioStreamPlayer
var fade_duration := 2.0

func _ready() -> void:
    track_a.bus = "Music"
    track_b.bus = "Music"
    add_child(track_a)
    add_child(track_b)
    current_track = track_a

func crossfade_to(new_stream: AudioStream) -> void:
    var next_track := track_b if current_track == track_a else track_a
    
    # Start new track at 0 dB
    next_track.stream = new_stream
    next_track.volume_db = -80  # Silent
    next_track.play()
    
    # Fade out current, fade in next
    var tween := create_tween().set_parallel(true)
    tween.tween_property(current_track, "volume_db", -80, fade_duration)
    tween.tween_property(next_track, "volume_db", 0, fade_duration)
    
    await tween.finished
    
    # Stop old track
    current_track.stop()
    current_track = next_track
```

### BPM-Synced Transitions

```gdscript
# Transition on beat boundary
var bpm := 120.0  # Beats per minute
var beat_duration := 60.0 / bpm  # 0.5s per beat

func queue_transition_on_beat(new_stream: AudioStream) -> void:
    # Wait for next beat
    var current_time := current_track.get_playback_position()
    var time_to_next_beat := beat_duration - fmod(current_time, beat_duration)
    
    await get_tree().create_timer(time_to_next_beat).timeout
    crossfade_to(new_stream)
```

---

## Dynamic Audio Effects

### Add Effect at Runtime

```gdscript
# Add reverb to SFX bus
var sfx_bus := AudioServer.get_bus_index("SFX")
var reverb := AudioEffectReverb.new()
reverb.room_size = 0.8  # Large room
reverb.damping = 0.5
reverb.wet = 0.3  # 30% effect, 70% dry
AudioServer.add_bus_effect(sfx_bus, reverb)
```

### Underwater Effect

```gdscript
func set_underwater(enabled: bool) -> void:
    var sfx_bus := AudioServer.get_bus_index("SFX")
    
    if enabled:
        # Add low-pass filter (muffled sound)
        var lowpass := AudioEffectLowPassFilter.new()
        lowpass.cutoff_hz = 500  # Cut frequencies above 500 Hz
        AudioServer.add_bus_effect(sfx_bus, lowpass)
    else:
        # Remove all effects
        for i in range(AudioServer.get_bus_effect_count(sfx_bus)):
            AudioServer.remove_bus_effect(sfx_bus, 0)
```

---

## Procedural Audio

### Synthesize Beep

```gdscript
# Generate simple sine wave
func create_beep(frequency: float, duration: float) -> AudioStreamGenerator:
    var stream := AudioStreamGenerator.new()
    stream.mix_rate = 44100  # Sample rate
    
    var playback := stream.instantiate_playback()
    
    var increment := frequency / stream.mix_rate
    var phase := 0.0
    
    for i in range(int(stream.mix_rate * duration)):
        var sample := sin(phase * TAU)
        playback.push_frame(Vector2(sample, sample))  # Stereo
        phase += increment
        phase = fmod(phase, 1.0)
    
    return stream

# Usage:
var beep_stream := create_beep(440.0, 0.1)  # 440 Hz (A4), 0.1s
$AudioStreamPlayer.stream = beep_stream
$AudioStreamPlayer.play()
```

---

## Advanced Patterns

### Audio Ducking (Lower Music During Dialogue)

```gdscript
# auto_duck.gd (on Dialogue AudioStreamPlayer)
extends AudioStreamPlayer

func _ready() -> void:
    playing.connect(_on_playing)
    finished.connect(_on_finished)

func _on_playing() -> void:
    # Duck music to -15 dB
    var music_bus := AudioServer.get_bus_index("Music")
    var tween := create_tween()
    tween.tween_method(set_music_volume, 0.0, -15.0, 0.5)

func _on_finished() -> void:
    # Restore music to 0 dB
    var tween := create_tween()
    tween.tween_method(set_music_volume, -15.0, 0.0, 0.5)

func set_music_volume(db: float) -> void:
    var music_bus := AudioServer.get_bus_index("Music")
    AudioServer.set_bus_volume_db(music_bus, db)
```

### Randomize Pitch for Variation

```gdscript
# Prevent identical sounds (footsteps, gunshots)
func play_varied_sound(stream: AudioStream) -> void:
    $AudioStreamPlayer.stream = stream
    $AudioStreamPlayer.pitch_scale = randf_range(0.9, 1.1)  # ±10% pitch
    $AudioStreamPlayer.play()
```

### Layered Music (Adaptive)

```gdscript
# Intensity-based music layers (start quiet, add layers as intensity increases)
# Example: Peaceful exploration → Combat

@onready var layer_drums := $Music/Drums
@onready var layer_bass := $Music/Bass
@onready var layer_melody := $Music/Melody

var intensity := 0.0  # 0.0 = calm, 1.0 = intense

func _ready() -> void:
    # Start all layers in sync
    layer_drums.play()
    layer_bass.play()
    layer_melody.play()
    
    # Mute high-intensity layers
    layer_bass.volume_db = -80
    layer_melody.volume_db = -80

func set_music_intensity(new_intensity: float) -> void:
    intensity = clamp(new_intensity, 0.0, 1.0)
    
    # Fade in layers based on intensity
    var tween := create_tween().set_parallel(true)
    
    # Layer 1 (drums): always audible
    tween.tween_property(layer_drums, "volume_db", 0, 1.0)
    
    # Layer 2 (bass): fade in at 33% intensity
    var bass_db := -80 if intensity < 0.33 else lerp(-80.0, 0.0, (intensity - 0.33) / 0.67)
    tween.tween_property(layer_bass, "volume_db", bass_db, 1.0)
    
    # Layer 3 (melody): fade in at 66% intensity
    var melody_db := -80 if intensity < 0.66 else lerp(-80.0, 0.0, (intensity - 0.66) / 0.34)
    tween.tween_property(layer_melody, "volume_db", melody_db, 1.0)

# Usage (combat system):
func _on_enemy_spotted() -> void:
    MusicManager.set_music_intensity(1.0)  # Full intensity

func _on_all_enemies_defeated() -> void:
    MusicManager.set_music_intensity(0.0)  # Back to calm
```

---

## Performance Optimization

### Disable Far Audio

```gdscript
# Don't play sounds the player can't hear
extends AudioStreamPlayer3D

func _process(delta: float) -> void:
    var listener := get_viewport().get_camera_3d()
    if not listener:
        return
    
    var distance := global_position.distance_to(listener.global_position)
    
    if distance > max_distance * 1.5:  # 1.5x max range
        if playing:
            stop()
```

---

## Edge Cases

### Audio Doesn't Play

```gdscript
# Check:
# 1. Is stream assigned?
if not $AudioStreamPlayer.stream:
    push_error("No audio stream assigned!")

# 2. Is bus muted?
var bus_idx := AudioServer.get_bus_index($AudioStreamPlayer.bus)
if AudioServer.is_bus_mute(bus_idx):
    print("Bus is muted!")

# 3. Is volume too low?
if $AudioStreamPlayer.volume_db < -60:
    print("Volume too quiet (< -60 dB)")
```

---

## Decision Matrix: Which AudioStreamPlayer?

| Feature | AudioStreamPlayer | AudioStreamPlayer2D | AudioStreamPlayer3D |
|---------|------------------|---------------------|---------------------|
| **Spatial** | ❌ Global | ✅ 2D panning | ✅ 3D positioning |
| **Doppler** | ❌ | ❌ | ✅ |
| **Attenuation** | ❌ | ✅ Distance-based | ✅ 3D falloff |
| **Reverb send** | ❌ | ❌ | ✅ |
| **Use for** | Music, UI | 2D games | 3D games |
| **Performance** | Fastest | Medium | Slowest |


## Reference
- Master Skill: [godot-master](../godot-master/SKILL.md)
Pliki w paczce (14)
  • SKILL.md 15 KB
  • scripts/audio_adaptive_music_player.gd 1 KB
  • scripts/audio_bus_ducker_logic.gd 1 KB
  • scripts/audio_bus_manager.gd 2 KB
  • scripts/audio_environmental_reverb_zone.gd 1 KB
  • scripts/audio_footstep_surface_selector.gd 1 KB
  • scripts/audio_linear_volume_interpolator.gd 1 KB
  • scripts/audio_manager.gd 1 KB
  • scripts/audio_occlusion_raycast.gd 1 KB
  • scripts/audio_procedural_generator_synth.gd 1 KB
  • scripts/audio_reactive_visualizer_component.gd 1 KB
  • scripts/audio_visualizer.gd 1 KB
  • scripts/audio_voice_limiter_manager.gd 1 KB
  • scripts/audio_voice_pool_manager.gd 1 KB

Wersje

RepozytoriumWynikLicencja
Ta strona · ahmet-cetinkaya/dotfiles100MIT
thedivergentai/game-dev-agentic-skills90LGPL

Migawka bazy z 28.10.2026 · wersja paczki 76d0b2e212ed (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 91godot-setup-audio-buses
    Konfiguruje hierarchię magistrali audio w Godot, pule AudioStreamPlayer, dźwięk przestrzenny 3D i łańcuchy efektów.
  • 100audio-system
    Pomaga zaimplementować system audio w grze: szyny dźwiękowe, AudioStreamPlayer, dźwięk przestrzenny, zarządzanie muzyką, pule efektów i dynamiczne miksowanie.
  • 100godot-audio
    Odtwarza i miksuje dźwięk w Godot 4.7: AudioStreamPlayer, szyny audio z efektami, routing muzyki i efektów, głośność oraz synchronizację z rytmem.
  • 100audio
    Wdraża audio w Godot: efekty dźwiękowe, muzykę, autobusy audio i dźwięk przestrzenny 3D, w tym crossfade, pooling źródeł i dźwięk pozycyjny w scenach 2D i 3D.
  • 100audio-system
    Wdraża audio w silniku gier: busy audio, AudioStreamPlayer, dźwięk przestrzenny, zarządzanie muzyką, pooling SFX i dynamiczny miks.
  • 100scenario-godot-audio
    Dodaje i naprawia dźwięk w Godot 4.7: magistrale i efekty audio, suwaki głośności, dźwięk 3D, reverb, okluzja, muzyka adaptacyjna, pętle muzyczne, AudioStreamRandomizer i import dźwięku z AI.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.