← Back to list
INS-836
`shortSound API 新設: preload/play/release 統合 + やられボイス不具合解消`
StatusDone
TeamInstansys
Assigneeasuki.uehata@instansys.co.jp
PriorityNo priority
Created2026/06/10 06:09
Completed2026/06/12 04:05
Archived2026/06/19 04:54
Description
背景
- INS-817 で
playOneShotAPI を新設・マージ。 - 並行して develop 側で
playOneShotVoiceByUrl/preloadUrlSound(やられボイス用)が別 PR で追加され、命名・所有層がplayOneShotと混乱。 battle-1-1(academy-1-normal-1)でヤンキー学生1/2 がやられた際に、ボイスが鳴らない不具合を確認(enemy-defeat-voice.ts:29→playOneShotVoiceByUrl経路)。SE(キラーン)は鳴っているためdefeatEffectハンドラ自体は通っており、voice の preload / play 経路に問題がある。
目的
- 短音再生の抽象再設計: 連打・頻発・preload 前提の短音群(やられボイス、SE群、キャラ standby voice 等)を扱う
shortSound抽象を新設し、preload と release を柔軟に管理できるようにする。 - やられボイス不具合の同時解消: 新 API への置換により、旧
playOneShotVoiceByUrlのロード/再生経路を捨てる。 - API 表面の整理: 旧
playOneShotVoiceByUrl/preloadUrlSoundを削除し、命名混乱を解消。
スコープ
- 未完了
soundManager.shortSound名前空間を新設(apps/client/src/lib/sound.ts) - 未完了以下 API を実装:
preload(alias, url): voidplay(alias, options?): void— 既定category: "voice"、未ロード時は 50ms × 60 = 3秒 pollingrelease(alias): voidreleaseMatching(pattern): void— glob (*のみサポート)releaseAllExceptMatching(pattern): void— glob 除外releaseAll(): void
- 未完了内部所有層
_shortSoundOwnedAliases(Set) をregisteredSoundAliases/_scenarioOwnedAliases/_oneShotOwnedAliasesと独立に管理(INS-817 の所有層独立原則を踏襲) - 未完了
enemy-defeat-voice.ts:29:playOneShotVoiceByUrl→shortSound.play置換 - 未完了
Battle.tsx:1995-1999:preloadUrlSound→shortSound.preload置換 + バトル離脱時 cleanup でshortSound.releaseMatching("https://*supabase*")等で sweep - 未完了旧
playOneShotVoiceByUrl/preloadUrlSoundを sound.ts から削除
スコープ外
- 既存
playOneShotのリネーム(playShortSound化等)は別チケット - 既存
_scenarioOwnedAliases体系(シナリオ voice)との統合は別途検討 - 参照カウント方式(シーン跨ぎ alias 重複対応)は今回入れない
受け入れ条件
- 動作確認:
bun run debug-cmd skip-to test academy-1-normal-1でバトル開始 → ヤンキー1/2 をやられさせた時に「ちくしょう...」「そうか...」が鳴る - メモリ解放: バトル離脱時に shortSound 所有 alias が
sound.removeまで届いている(DevTools のsound.exists(url)で false 確認) - 既存
playOneShotの回帰なし: リザルトボイス(ChapterResult / StageResultView)・編成 standby ボイス(PartyEditModal)が引き続き正常動作 bun lint/ 該当ファイル型チェック通過
関連
- instansys/ultemist#693(マージ済 —
playOneShot本体) - 引き継ぎ docs:
docs/audio-memory-leak-handoff.md
Comments (3)
asuki.uehata@instansys.co.jp2026/06/10 06:21
統合する必要はなさそう。
でも、私が実装したAPIと名前が混同するのでわけるべき
あと、"playOneShotVoiceByUrl" って OneShot じゃなくて、重ね再生の方だから 実際には、 OneShot という機能ではなさそう。
asuki.uehata@instansys.co.jp2026/06/10 09:48
API仕様 予定 草案
正規表現でまとめてメモリ解放できるようにする。
soundManager.shortSound = {
preload(alias: string, url: string): void,
play(alias: string, options?: { volume?: number; category?: "voice" | "battle" | ...; pitch?: number; ... }): void,
release(alias: string): void,
releaseMatching(pattern: string): void,
releaseAllExceptMatching(pattern: string): void,
releaseAll(): void,
}
asuki.uehata@instansys.co.jp2026/06/10 13:39
INS-836 Enemy.tsx で dead transition 時にやられボイス発火
playEnemyDefeatVoice の呼出が AnimationDebug.tsx のプレビュー用しか
存在しておらず、バトル中の Enemy.tsx から発火されていなかった (機能未実装)。
Enemy.tsx に useRef + useEffect で enemy.state の "dead" 立ち上がりを
検知する仕組みを追加し、shortSound 経由でやられボイスを発火する。
manualControl 経由の手動 "dead" 切替 (AnimationDebug) は既に
AnimationDebug 側で playEnemyDefeatVoice を呼んでいるため、
!isManualControl ガードで二重発火を回避。