soak-test について
soak-test は、ゲームプロジェクト向けに長時間プレイのテスト手順書と分析文書を作成するスキルです。メモリ、安定性、性能変化、ゲームプレイの疲労を観察でき、実際のプレイは人が行います。
主な機能
- 01時間別の観察チェックポイント生成
- 02メモリ・安定性・バランスへのフォーカス
- 03エンジン別の監視ガイダンス
- 04セッション予算と観察結果の記録
- 05QAテスト手順書の作成
活用シーン
- 01長時間プレイ中のメモリ増加の追跡
- 02クラッシュや経時的な性能変化の確認
- 03コンテンツ不足やゲームプレイ疲労の評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ donchitos/ claude-code-game-studios --skill soak-testインストール後、Claude Code で/soak-testを入力して読み込まれたか確認します。
詳細
!bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation,workflow
自動化モード:modes.automation を解決します(project.local.yaml →
project.yaml → デフォルトの collaborative)。すべての AskUserQuestion 呼び出しと
すべてのファイル書き込みは、.claude/docs/automation-modes.md に従います
(collaborative は常に質問 · guided は主要な項目のみ質問 · autonomous は記録して続行;
automation_always_ask カテゴリは常に質問)。
長時間プレイテスト
長時間プレイテスト(耐久テストとも呼ばれます)は、特定の観察目標に沿って長時間プレイするテストです。広範なクリティカルパスを約10分間確認するスモークチェックや、単一機能を約30分間テストするプレイテストとは異なり、長時間プレイテストは30分から数時間実施し、次の問題を明らかにします。
- メモリリーク — シーン遷移後にのみ現れる、ヒープの緩やかな増加
- パフォーマンスの劣化 — 時間の経過とともに悪化するフレーム時間
- 状態蓄積の不具合 — メカニクスをN回繰り返した後にのみ現れる問題(インベントリの満杯、スコアのオーバーフロー、AI状態の破損)
- 楽しさの減衰 — 初回のプレイでは楽しく感じられるものの、長時間プレイすると単調になるメカニクス
- コンテンツの枯渇 — プレイヤーが新鮮なコンテンツを使い切る時点
このスキルが作成するのは観察プロトコルと分析用ハーネスです。実際にプレイするのは人間です。
出力: production/qa/soak-test-[date]-[duration].md
実施するタイミング:
- ブラッシュアップ段階 —
/gate-check releaseの前 - メモリまたは安定性の問題を修正した後(回帰長時間テスト)
- 長時間プレイが正式に記録されていない場合
1. 引数を解析する
時間(デフォルト:1h):
30m— 短時間テスト。単一のメカニクスまたはシーンのテストに適しています1h— 標準テスト。一般的なリークの種類のほとんどを確認できます2h— 長時間テスト。初回の本格的なブラッシュアップテストに推奨されます4h— 徹底テスト。長時間のセッションを想定したゲーム(RPG、シミュレーション)で必要です
フォーカス(デフォルト:all):
memory— ヒープサイズ、オブジェクト数、リークのパターンに焦点を当てますstability— クラッシュ、フリーズ、ハングの検出に焦点を当てますbalance— 楽しさの減衰、コンテンツの枯渇、難易度の感じ方に焦点を当てますall— 上記すべて
2. コンテキストを読み込む
次を読みます。
project.yaml—engine.name(エンジン固有のメモリ監視ガイダンス用)とperformance.*の予算(メモリ上限、目標FPS)。キーが存在しない、または空の場合 (project.yamlにperformanceブロックもengineブロックもない場合を含む)は、.claude/docs/technical-preferences.mdにフォールバックしますdesign/gdd/game-concept.md— 想定セッション時間(長時間テストの時間と比較するため)、 コアループの説明(または、rigor: minimalではこれに代わる1ページの ブリーフであるdesign/game-brief.md— コアループ、および「Who it's for」の行に セッション時間が記載されている場合に限りその時間)。セクション単位で読みます。 Grep ツールで必要な見出しを検索し(パターン^#、content モード)、 Read ツールで offset と limit を指定して該当範囲を読みます。production/qa/playtests/の最新ファイル — 以前のプレイテストでの指摘事項 (既知の問題を再記録しないため)production/qa/qa-plan-*.mdの最新ファイル — 現在のスプリントでのテストカバレッジ (正式にテスト済みの内容と、長時間テストで確認する内容を把握するため)
パフォーマンス予算の目標をメモします(project.yaml の performance.*、なければ .claude/docs/technical-preferences.md)。
- メモリ上限:[N MB、または「未設定」]
- 目標FPS:[N、または「未設定」]
- フレーム予算:[N ms、または「未設定」]
3. 観察チェックポイントを定義する
時間に基づいて、次のチェックポイントを生成します。
30m テスト:T+0、T+10、T+20、T+30
1h テスト:T+0、T+15、T+30、T+45、T+60
2h テスト:T+0、T+20、T+40、T+60、T+80、T+100、T+120
4h テスト:T+0、T+30、T+60、T+90、T+120、T+180、T+240
各チェックポイントで、観察者はフェーズ4で定義する観察項目を記録します。
4. 長時間プレイテストのプロトコルを生成する
メモリ/安定性の観察項目(focus = memory または all の場合)
エンジン固有のモニタリングに関するガイダンスです。
ツールに表示される単位を記録してください。決して換算せず、単位を推測しないでください。 ソークテストでは増加を確認するため、以下のしきい値はすべて、このセッションの T+0 ベースラインに対する比率または差分です。単位に依存せず、エディターが数値をどのように表示しても正しく使えます。T+0 で単位を表示どおりに正確に記録し、残りの実行でも一貫して使用してください。
参照元なし — 以下のツール、パネル、カウンター名は
docs/engine-reference/で扱われていません:Godot の Debugger → Monitors とそのメモリカウンター、Unity の Memory Profiler とそのフィールド、Unreal のstat memory。プロトコルではその旨を明記してください。これらはテスターが T+0 に自分のエディターで確認するための手がかりであり、検証済みのパスではありません。メモリツールが見つからない場合、測定は行われておらず、Verdict セクションの NOT ASSESSED が適用されます。
Godot 4:
- Debugger → Monitors タブを開き、チェックポイントごとに
Memory → Static MemoryとObject Count → Objectsを追跡します - 記録項目:Static Memory(表示された単位)、Object Count、Orphan Nodes の数
- 警告しきい値:最初の 15 分経過後に、T+0 からメモリが 20% を超えて増加(ロード時の多少の増加は想定内ですが、増加が続く場合はリークを示します)
- 絶対値で監視する価値があるのは Orphan Nodes だけです:シーンのアンロード後に T+0 の値に戻るはずです。比率ではそれが隠れてしまいます。ゼロ以外の基準値が上昇し続ける場合は、単位に関係なくリークです
Unity:
- Memory Profiler(Window → Analysis → Memory Profiler)を開きます
- 各チェックポイントで Total Reserved Memory、GC Allocated、Object Count を記録します (表示された単位)
- 警告しきい値:GC Allocated が 3 つ以上のチェックポイントにわたって単調に増加すること — 単調性を確認するもので、意図的に単位に依存しません
Unreal Engine:
- 各チェックポイントでコンソールコマンド
stat memoryを使用します - 記録項目:Physical Memory Used、Physical Memory Available(表示された単位)
- 警告しきい値:この実行の T+0 を基準として、ソーク全体を通じた Physical Memory Used の増加が 20% を超えること。「> 50MB」のような絶対しきい値は、単位とプロジェクトの規模の両方を暗黙に仮定しています。あるゲームでは 50MB は丸め誤差ですが、別のゲームでは致命的です
安定性の観察項目(focus = stability または all の場合)
各チェックポイントで、以下を記録します:
- 前回のチェックポイント以降、クラッシュ、ハング、フリーズが発生していない
- フレームレートが引き続き目標予算([target FPS] fps)内である
- 音声が引き続き正しく再生されている(同期ずれや無音がない)
- すべての HUD 要素が引き続き正しく表示されている
- 入力が想定どおりに反応している(入力の喪失やラグスパイクがない)
バランス/疲労の観察項目(focus = balance または all の場合)
各チェックポイントで主観的な観察結果を記録します:
- コアメカニクスに引き続きやりがいを感じる(Y/N)
- 体感難易度:[簡単すぎる / 適切 / 難しすぎる]
- 前回のチェックポイント以降、「これ、前にも見た」という瞬間はあったか(新しいコンテンツの枯渇)
- 前回のチェックポイント以降、苛立ちを感じた瞬間はあったか。原因を記録してください。
- 前回のチェックポイント以降、強く没頭した瞬間はあったか。原因を記録してください。
5. プロトコル文書を生成する
# Soak Test Protocol
> **Date**: [date]
> **Duration**: [duration]
> **Focus**: [memory | stability | balance | all]
> **Engine**: [engine]
> **Generated by**: /soak-test
---
## Pre-Session Setup
Before starting the soak:
- [ ] Game is running from a **fresh launch** (not resumed from a prior session)
- [ ] All background applications closed (minimise OS memory interference)
- [ ] Performance monitoring tool open and recording:
- **Godot**: Debugger → Monitors tab → Memory section visible
- **Unity**: Memory Profiler window open
- **Unreal**: `stat memory` ready in console
- Tool actually used, as named in this editor: [record it — the names above
are NOT SOURCEABLE from `docs/engine-reference/`; none found → NOT ASSESSED]
- [ ] Soak target confirmed: [session design intent from game concept]
- [ ] Prior known issues to watch for: [from most recent playtest / qa-plan]
---
## Baseline (T+0) — Record Before Playing
| Metric | Baseline Value |
|--------|---------------|
| Memory / Heap | [record before first frame of gameplay] |
| Object Count | [record] |
| FPS (first 30 seconds) | [record] |
| [Engine-specific metric] | [record] |
---
## Checkpoint Log
### T+[N] minutes
**Memory / Stability** *(if applicable)*:
| Metric | Value | Δ from Baseline | Alert? |
|--------|-------|-----------------|--------|
| Memory / Heap | | | |
| Object Count | | | |
| FPS | | | |
| Crashes / Hangs | | | |
**Stability checks**:
- [ ] No crash or hang since last checkpoint
- [ ] Frame rate within budget ([N] fps target)
- [ ] Audio correct
- [ ] HUD rendering correctly
- [ ] Input responding correctly
**Balance / Fatigue** *(if applicable)*:
- Core mechanic still rewarding: Y / N
- Difficulty perception: too easy / appropriate / too hard
- Notable moments: [note any peak engagement or frustration]
- Content exhaustion signs: Y / N — [describe]
**Free observations**:
*(Note anything unexpected observed since the last checkpoint)*
---
[Repeat Checkpoint Log section for each timed checkpoint]
---
## Post-Session Analysis
### Memory Trend
| Checkpoint | Memory | Δ/hr extrapolated |
|------------|--------|-------------------|
| T+0 | | |
| [T+N] | | |
**Leak detected?** Y / N
**Estimated time to OOM at current rate**: [N hours / not applicable]
### Stability Summary
Total crashes: [N]
Total hangs: [N]
Worst FPS observed: [N] fps at [checkpoint]
Performance degradation: stable / mild / severe
### Balance / Fatigue Summary
Fun curve: [engaged throughout / fatigue onset at T+N / repetitive from start]
Content exhaustion point: [never / at T+N / early]
Difficulty arc: [appropriate / too easy throughout / difficulty spike at T+N]
### Issues Found
| ID | Severity | Checkpoint | Description |
|----|----------|------------|-------------|
| SOAK-001 | S[1-4] | T+[N] | [description] |
---
## Verdict: PASS / PASS WITH CONCERNS / NOT ASSESSED / FAIL
**PASS**: No leaks detected, stability maintained, fun factor consistent
**PASS WITH CONCERNS**: Minor drift or fatigue noted; addressable in Polish
**NOT ASSESSED**: The soak did not run to a length that could show what it looks
for — say how far it got and which checkpoints were never reached
**FAIL**: Memory leak confirmed, stability breach, or severe fun fatigue
> **A short soak cannot return PASS.** Everything this protocol exists to detect
> — slow leaks, fatigue, late-appearing edge cases — is by definition invisible
> early, so a session that ended before the checkpoints it was built around has
> not shown stability; it has shown nothing yet. Record `NOT ASSESSED — reached
> T+[N] of [duration]; checkpoints [list] not reached`. Ranks **above both pass
> values** and **below FAIL**: a crash observed at T+20 is a real finding no
> matter how short the run, and must not be demoted behind the run's length.
> The same applies when the build crashed for reasons unrelated to the soak, when
> no memory instrumentation was available (nothing was measured, so "no leaks
> detected" means "no leaks could have been detected"), or when the protocol was
> written but never executed — a protocol document is not a result.
---
## Sign-Off
- **Tester**: [name] — [date]
- **QA Lead review**: [name] — [date]
6. 出力する
会話内でプロトコルの概要を提示してから、次のように尋ねます:
「このソークテストプロトコルを
production/qa/soak-test-[date]-[duration].md に書き込んでもよろしいですか?」
承認を得てから書き込みます。
書き込み後:
「プロトコルを書き込みました。ソークテストを実行するには:
- ファイルを開き、Pre-Session Setup のチェックリストに従います
- プレイしながら各チェックポイントを記録します
- 終了後、Post-Session Analysis セクションを完了します
- 'Issues Found' に記載されたバグを
production/qa/bugs/に登録します - セッション後に
/bug-triage sprintを実行し、S1/S2 の問題を統合します(workflow: minimalではスプリントがないため、/bug-triage fullを実行します)
判定が FAIL の場合は、問題を修正した後に /smoke-check を再度実行してください。」
協調プロトコル
- このスキルはプロトコルを生成し、人間が実行します — ソークテストを自動で実行しようとしないでください。観察には人間の観察者が必要です。
- 期間はゲームのセッション設計に合わせてください — 5分のゲームに4時間のソークテストは必要ありませんが、都市建設ゲームなら必要になる場合があります。判断に迷う場合は確認してください。
- 最初のソークテストではフォーカスに
allを指定してください — フォーカスを絞る(メモリのみ)のは、特定の修正後に行う回帰ソークテスト用であり、初回の実行ではありません。 - 書き込む前に確認してください — プロトコルファイルを作成する前に、必ず確認を取ってください。