关于 scenario-godot-audio
面向游戏音频实现者的 Godot 4.7.2 音频技能。它将混音、总线布局、音乐转场和语音数量限制作为可测量数据,并检查导入、播放行为和渲染输出。
主要功能
- 01构建并审计音频总线布局
- 02设置并验证音频导入参数
- 03处理并调整生成的音频素材电平
- 04按限制池化音效语音
- 05创建并审计交互式音乐转场
- 06测量空间音频与渲染混音
适用场景
- 01控制战斗中的音效负载
- 02验证音乐转场和插曲返回
- 03检查定位音频电平与遮挡效果
- 04处理生成音频并验证响度
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-godot-audio安装后在 Claude Code 中输入/scenario-godot-audio确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/gd_audio.pyscripts/agentkit/audio/audio_audit.gdaudio_buses.gdaudio_meter.gdmusic_builder.gdoccluder_3d.gdsfx_pool.gdtone_generator.gd详细介绍
Godot 音频(音频实现者)
目标:Godot 4.7.2.stable,macOS Apple Silicon。
在专家级别,混音先作为数据进行设计,再进行测量。总线布局、音乐过渡和语音限制都以规格形式编写。由于 Agent 无法聆听,因此每项判断都要通过从混音器读取的数值进行核验。专家花在决定不播放哪些声音上的精力,远多于决定如何播放它们。这是战斗音频的核心。如果这里提到的某项同级技能不在你的可用技能中,请让用户安装它(npx skills add scenario-labs/skills --skill <name>);若需无人值守地继续,请依据工具模式操作,并标明这一缺口。
必备背景: scenario-godot-expert(通道、gd_run、审查流程、4.7 陷阱)。
状态(2026-10-02): 12 个测试组中的 18 个实时作业、第二轮检查(P15)以及 13 项离线测试,均已在 Godot 4.7.2 中通过(references/procedures.md、tests/code/godot-audio/)。
立场(专家补充)
- 在无头模式下测量;不要相信“没有声音”的警告。 版本差异说明
--headless使用 Dummy 驱动,且不会发出声音。这对扬声器来说确实如此。但在 4.7.2 中,Dummy 驱动仍会以 44.1 kHz 实时混音。峰值电平表、AudioEffectCapture和AudioEffectRecord在该模式下都能正常工作,-24.08 dBFS 的文件读数为 -24.07(实测)。需要精确计时时, 使用AudioStreamPlayback.mix_audio()离线渲染(audio_meter.render_stream), 可精确到采样点;实时录音会晚约 0.2 s 开始(实测)。 - 好的战斗音频,关键在于不播放声音。 Somberg:“很多音频技术都是关于不播放声音的”(Vjm-- 00:05:20)。为每种声音设置上限,将半径内同时播放的数量控制在约 2 个, 并在消耗一个语音通道前按距离剔除声音。此处用 200 个敌人以 10 Hz 开火进行了测量:朴素混音在限幅器之前峰值达到 +32.4 dBFS,而带上限的 32 通道池峰值为 +8.5 (P6)。
- 留意同步启动。 设置硬性上限但不设冷却时间时,所有 12 个语音通道都会在同一帧启动并同时结束。混音随后会呈现脉冲式爆发(波形图,P6)。每种声音设置 25 ms 的冷却时间,并准备 4 个随机变体,可将声音分散开来,峰值降至 -13.9 dBFS [新增,实测]。
- 将音乐写成转换表,并审核所有可达的状态组合。 Octodemy 逐格构建矩阵(spBa 00:03:59)。Bittmann 要求为每种状态变化都做好设计(dPXa 00:18:07)。未列出的状态组合并不会硬切。在 4.7.2 中,它会等到下一个节拍,然后在约一个节拍内淡出源音轨(实测,P9)。
music_builder.audit_interactive会列出缺失的状态组合。 - 将 hold 设置在离开目标片段的转换上,以便之后返回该片段。 文档和 Octodemy 都介绍了“hold previous”和返回 hold 的用法(spBa 00:07:49)。在 4.7.2 中,只有在更早的转换上设置 hold,也就是离开被打断片段的那次转换,返回才能正常工作。若在转换到提示音片段时设置 hold,6 种变体都会在提示音之后变为静音(实测,P9)。
- 所有内容都通过命名总线进行路由,并按名称引用总线。 先创建 Music 和 SFX 总线(DevWorm 07Ky、Game Dev Artisan h3_1)。将总线重命名后,播放器读回的总线名称会变成
"Master",并通过该总线播放。恢复原名称后即可恢复正常(实测)。审核场景,找出使用 Master 或缺失总线的播放器(P13)。 - 根据真实衰减曲线测量空间音频。 使用 4.7.2 的默认值(unit_size 10、max_db +3)时,3D 音源在 1 m 到 7 m 之间音量平坦,10 m 处下降 3 dB,80 m 处下降 21 dB。低通滤波器会使 20 m 处的 8 kHz 音量额外降低 22 dB。
area_mask默认为 0,因此必须将其设为 1,Area3D 的混响覆盖设置才会生效(P7)。 - 导入前处理生成的音频,并在资源加载后进行验证。 AI 生成的 MP3 音频电平偏高(一个测试文件为 -8.4 LUFS,峰值 +0.99 dB),且带有静音填充。较长的文件使用双遍 loudnorm 归一化。较短的单次音效按峰值调整电平,因为 loudnorm 在一个 0.5 s 的撞击音上比目标值低了 3 LU(实测,P4)。
先明确
| 输入 | 对方案的影响 | 未提供时的默认值 |
|---|---|---|
| 平台(桌面、移动端、Web) | Web 默认以 Sample 模式播放(default_playback_type.web = 1),该模式会绕过总线效果(文档) | 桌面端 |
| 2D 或 3D、监听器 | AudioStreamPlayer2D 或 3D、单位大小、最大距离 | 3D,Camera3D 监听器 |
| 同时播放的音源峰值数量 | 池大小、上限 | 200 个敌人、32 个语音 |
| 音乐风格(有节奏、环境音) | 小节或节拍结束时退出,还是立即退出;BPM 导入 | 有节奏,4/4 |
| 资源来源 | 处理方式:AI(scenario-audio、scenario-elevenlabs)或声音设计师 | AI 文件,已处理 |
| 中间件(FMOD、Wwise) | 原生节点或插件音色库 | Godot 原生 |
| 响度目标 | 各类音频的 LUFS | 音效、语音和音乐为 -18 LUFS;环境音为 -24 [新增] |
工作流
- 将总线作为数据(P1、P2)。 使用
build_layout从audio_buses.COMBAT_LAYOUT构建布局,将其保存到audio/buses/default_bus_layout指定的文件中,并在全新进程中重新加载。GATE:audit_layout不返回任何标记,重新加载后 HardLimiter 位于 Master 上。滑块设为 0.5 时会设置为 -6.02 dB,输出音量降低 6.02 dB。 - 导入设置(P3)。 使用
gd_audio.set_import_params编辑.import键,运行gd_run.import_project,然后读取已加载的资源。GATE:音乐的已加载流设置了loop、bpm和beat_count,且gd_audio.audit_imports不返回任何标记。 - 生成的素材(P4)。
prepare_ai_audio(src, dst, kind)会裁剪静音、调整文件音量,并将 SFX 转换为单声道 WAV。bars_for(seconds, bpm)会给出beat_count。GATE:每种类型的响度差小于 1 LU、开头没有静音,并且audio_meter.loop_seam(stream)测得的循环接缝延迟为 0 个采样。 - SFX 变化(P5)。 使用 AudioStreamRandomizer,至少准备 3 个片段,并设置以半音为单位的音高范围和音量偏移。GATE:播放 24 次以上不会重复、所有片段都被使用,且测得的音高在设定范围内。
- 语音(P6)。 使用
SfxPool,按类型设置limit、radius_m、radius_limit、cooldown_ms、max_distance_m,并启用优先级抢占。GATE:在 200 个敌人的突发场景中,活动语音数量不超过上限、节点数量保持稳定,且限幅器前的峰值低于 0 dBFS。然后打开波形图并查看。 - 空间(P7、P8、P15)。 先处理监听器:在 3D 中,如果没有当前 Camera3D 或 AudioListener3D,所有 3D 播放器都静音(-200 dB)。
AudioListener3D.make_current()会覆盖摄像机(移开 40 m:-12.1 降至 -29.8 dB,左右声道互换)。在 2D 中,如果没有监听器,视口中心可以听到声音:在玩家上添加一个AudioListener2D(DevWorm 07Ky 00:33:25,First Pancake 1PDU 00:04:05)。然后设置 unit_size、max_distance、房间总线的area_mask = 1,以及遮挡(射击声音在播放时发射一条射线,长时间发声的对象使用Occluder3D)。GATE:只有一个当前监听器;每个定位播放器都使用一个命名的非 Master 总线(audio_audit.scan);测量不同距离下的音量、左右声道平衡,以及被遮挡时 8 kHz 频段至少衰减 12 dB。 - 音乐(P9)。 使用
music_builder.build_interactive(spec)构建交互式流,审计后保存为.tres。使用 AudioStreamSynchronized 音轨制作分层效果。GATE:通过音调跟踪离线渲染可见,每次切换都发生在小节或节拍处,且提示音结束后会返回当前播放片段。 - 由游戏状态控制混音状态(P2、P15)。 Just Cause 4 会在投入战斗的敌人超过 5 个时静音环境音,并在约 1 秒内切换战斗混音(uN8R 00:19:07 至 00:21:12)。将状态写成游戏状态的函数,而不是音频的函数:
GATE:投入战斗的敌人数为 0、3 和 8 时,每条总线都在淡入淡出时长内达到目标(在 0.25 s 时进行精确测量)。不要手动切换总线来实现静音:Godot 会在静音总线持续几秒后自行将其禁用(见音频总线文档)。static func combat_mix(engaged: int) -> Dictionary: if engaged == 0: return {"Ambience": -6.0, "Music": -8.0} if engaged <= 5: return {"Ambience": -12.0, "Music": -6.0} return {"Ambience": -80.0, "Music": -4.0} # on change: audio_buses.apply_state(self, combat_mix(n), 1.0) - 渲染混音(P12)。 运行 Movie Maker,并使用
--write-movie x.avi --fixed-fps 60(窗口模式,160x90),然后运行gd_audio.movie_audio。GATE:输出为 48 kHz;两个使用相同种子的渲染结果具有相同的 MD5;综合响度在目标范围内;真峰值低于 -1 dBTP;并打开频谱图查看。
数值
| 数值 | 测量结果或来源 | 相对于 |
|---|---|---|
| 3D 音量,平坦区域 | 1 至 7 m 时为 0 dB,10 m 时为 -3 dB,20 m 时为 -8.9,40 m 时为 -14.8,80 m 时为 -20.7(500 Hz) | 反向模型,unit_size 10,max_db +3 |
| 距离低通 | 10 m 时无衰减;20 m 时 8 kHz 额外衰减 -22 dB,40 m 时衰减 -29 dB | 默认值为 5000 Hz、filter_db -24;filter_db 0 可禁用 |
| 声像,向右 5 m | L -16.0 / R -10.0 dB | panning_strength 1.0 乘以项目 3d 0.5 |
| 线性滑块 | 0.5 为 -6.02 dB;低于 0.05 时静音 | Game Dev Artisan(h3_1 00:09:23) |
| 音频池 | 32 个音源,循环使用玩家 | Michael Games(H-6p 00:09:44) |
| 半径规则 | 每个半径保留约 2 次播放 | Somberg(00:05:52),Murch 的“二点五规则” |
| 限制器前的战斗峰值 | 朴素方案 +32.4,池化方案 +8.5,调优后 -13.9 dBFS | 200 个敌人,10 Hz,2 s(P6) |
| 遮挡 | 经过 1 kHz 低通滤波器时,8 kHz 衰减 -58 dB;Occluder3D 在约 0.5 s 内将 20 kHz 降至 800 Hz | P8 |
| 响度目标 | SFX、语音、音乐为 -18 LUFS;环境音为 -24;真峰值 -1 dBTP | [添加] 起始值 |
| 短音阈值 | 短于 3 s 时,峰值电平设为 -3 dBFS | loudnorm 在 0.5 s 音频上漏掉了 3 LU(P4) |
| 主总线 | 绝不高于 0 dB;工作范围为 -60 至 0 dB | 音频总线文档 |
质量门槛
- 可测量:
audit_layout通过;audit_interactive通过,且没有缺失可达配对;audit_imports通过;audio_audit.scan通过(Master 上没有播放器、没有缺失流、Area 覆盖总线时已设置area_mask)。在压力突发测试中,限制器前的峰值低于 0 dBFS,实时音源数量不超过上限,节点数量保持稳定。 每个文件的analyze()结果:响度与目标相差不超过 1 LU,真峰值不高于 -1 dBTP,单次播放音效的lead_silence_s低于 0.01。循环接缝的滞后为 0。生成器get_skips()为 0。 - 视觉: 朴素、池化和调优后的压力渲染波形联系表,以及 Movie Maker 混音的频谱图。打开后检查是否存在大片削波、周期性突发和缺失的切换。
- 凭耳朵判断(用户): 转场的音乐性、重复感、混响的自然度。如实说明;不要声称自己做过判断。
常见错误
| 错误 | 表现 | 修复方法 |
|---|---|---|
| 每个敌人都使用一个 AudioStreamPlayer3D,每次射击都播放 | +32 dBFS 噪声墙、限制器泵动、200 个活动语音 | 使用带上限的 SfxPool、距离规则和冷却时间 |
| 设置上限但没有冷却时间 | 每个音频片段播放时,混音都会脉动 | cooldown_ms 设为 25 或更大,使用 Randomizer 抽取 |
| Area3D 混响区域不起作用 | 房间总线读数为 -200 dB | 在玩家上设置 area_mask = 1(4.7 默认值为 0) |
| 在布局中重命名总线 | 播放器显示 Master,不响应滑块 | 保持名称稳定;使用 audio_audit.scan |
相信 .import 文本 | 游戏中的循环仍处于关闭状态 | 检查已加载流的 loop 和 bpm |
| 对 0.5 秒的音效使用 loudnorm | 得到 -21 LUFS,而不是 -18 | 对短音效进行峰值电平处理(prepare_ai_audio) |
| 音乐使用 WAV,音效使用立体声 | 构建体积大,单声道折叠浪费 | 使用 audit_imports:音乐用 Ogg 或 MP3,音效用单声道 |
对循环音频等待 finished | 代码卡住 | 循环播放的 0.2 秒片段在 1 秒内触发 finished 0 次,不循环时触发 1 次(文档,P15) |
| 3D 场景中没有当前监听器 | 所有 3D 声音都静音,且没有错误 | 设置一个当前的 Camera3D 或 AudioListener3D(P15) |
同时设置 random_pitch 和 random_pitch_semitones | 后设置的属性会静默覆盖先设置的属性 | 只使用一个属性:2 个半音对应 random_pitch 1.1225;所有变化的默认值均为 0(文档,P15) |
使用 == 测试脚步计时器 | 完全没有脚步声:10 秒内为 0 次 | 使用 timer <= 0.0,然后 timer += interval:产生 28 次脚步声(FinePointCGI 7kD7 00:38:17,P15) |
在 Master 上使用 AudioEffectLimiter | 出现已弃用警告 | 使用 AudioEffectHardLimiter,上限设为 -1 dB |
| 在 Web 上使用总线效果 | 浏览器中没有混响或滤波效果 | 将这些播放器的播放类型设为 Stream(文档) |
使用 ffmpeg 的原生 vorbis 编码器制作 Ogg | 循环晚 32 个采样点衔接(文件时长为 8.0007 秒) | 使用 libvorbis,或使用带无缝衔接标头的 MP3;检查 audio_meter.loop_seam |
交接
- 接收: 来自 scenario-audio 和 scenario-elevenlabs 的 MP3/WAV,以及提示词、BPM 和时长
(通过
prepare_ai_audio,然后是 P3);来自 scenario-godot-gameplay 的事件、位置和已交战敌人数;来自 scenario-godot-architecture 的自动加载节点放置方式;来自 scenario-godot-ui 的滑块节点。 - 交付: 总线名称和
save_volumes/load_volumes给 scenario-godot-ui;返回 int id 的play(type, pos)API 给 scenario-godot-gameplay;池统计信息和 Web Sample 模式列表给 scenario-godot-performance-export;实时测试文件给 scenario-godot-pipeline-automation。 - 数据包: 项目路径、布局和音乐规格、结果 JSON、波形图、频谱图、
analyze()表格、未解决问题。
Godot 4.7 说明
- AudioStreamPlayer2D 和 AudioStreamPlayer3D 的
area_mask默认值为 0(4.7)。区域总线覆盖需要将其设为 1 (已验证)。 AudioEffectLimiter已弃用;请使用AudioEffectHardLimiter。AudioEffectSpectrumAnalyzer.tap_back_pos已移除。- 存在
set_bus_volume_linear、volume_linear和max_polyphony(默认值为 1)。 AudioStreamInteractive、Synchronized 和 Playlist 均从 4.3 开始提供。 - MP3 和 Ogg 一样包含
bpm和beat_count(已验证)。AudioStreamWAV 没有bpm,因此 节拍同步片段必须使用 Ogg 或 MP3。 - WAV 导入默认使用 QOA(
compress/mode为 2,格式为 3)。 - 无头模式使用 Dummy 驱动进行混音(状态 1)。Movie Maker 需要窗口。
- 应摒弃 Godot 3 的习惯:
yield、Tween 节点、ResourceSaver.save(path, res)。
参考资料
references/procedures.md(P1 至 P15,含代码和结果; 生成器、池开销和 Movie Maker 数值见此处),expert-notes.md(按专家整理的原则及时间戳),critique.md(评分标准),gui-paths.md(Audio 面板、过渡矩阵、Import 停靠面板、Profiler),sources.md。scripts/gd_audio.py:安装、导入编辑与审计、analyze、音调跟踪、AI 音频接收、影片音频、图片。scripts/agentkit/audio/:audio_meter、audio_buses、music_builder、sfx_pool、occluder_3d、tone_generator、audio_audit。
评论
支持 Markdown