Development report · Vertical slice
Bubble & Tumble 開発レポート
マザーグースの「落ちる歌」を舞台にした、シャボン玉で敵を弾いて落とし合うクォータービュー3Dアクション。UE5.8 / C++ で、バーチカルスライス(1ステージ+ボス)を作っている途中経過をまとめた。個人で開発中の作品で、ここに書いた内容は今後変わることがある。
At a glance
7日間の作業でできたもの
期間は 2026-09-27 〜 10-21 の25日間で、主に作業したのは 9/27・10/4・10/5・10/8・10/14〜15・10/17・10/21 の7日(ほかに数分だけの日がある)。会話ログの時刻から数えた実質の作業時間は約12時間で、そのうち Claude が作業していたのは約8時間(ビルドやテストの待ちを含む)。残りは返答を見て次の指示を決めていた時間で、10分を超える間は何もしていない時間として除いた。このレポートや記事の作成・公開の時間も含む。
The game
どんなゲームか
ナムコの『メルヘンメイズ』(1988)に影響を受けたオリジナル作品。同作の「シャボン玉で敵を弾き、落とし合う」遊びを手がかりに、反射する弾、敵を泡で包んで蹴る「包み込み」、多方向に進むステージ、高低差を加えている。同作のタイトル・キャラクター・曲・ステージは使っていない。
バーチカルスライスで証明したいのは3つ。反射弾や包み込みで敵を落とすのが気持ちいいこと、落ちても理不尽に感じないこと、ギミックと敵の組み合わせで局面が毎回変わること。
Timeline
7日間の歩み
-
コアの手触りを作る(マイルストーン1)
- 真上から斜めに見下ろす固定カメラと、区画ごとにカメラの向きを切り替える仕組み
- 画面基準の移動、ジャンプの猶予と先行入力、地上と空中のダッシュ
- シャボン杖:溜めで小玉・中玉・大玉、プールした泡、独自の反射計算、照準の予測線
- 決定論的な吹き飛び(物理エンジンに任せない)、被弾の蓄積、落下と区画頭からの復帰
- 反射壁、泡のキャッチとストック、包み込み(3秒浮かぶ泡を押す・蹴る・踏む)
- Unreal MCP を有効にして、エディタを外から動かして検証する仕組みを作る
- 敵の土台と StateTree AI、最初の敵トコトコ
-
敵とギミックを揃え、ステージを組む(マイルストーン2)
- ギミックの2系統の土台(変形する足場、力場)と、昇降床・崩れる床・跳ね床・送風機・反射スイッチ
- ポンプ、タテモチ、フワリ、ユカワリ
- 溜め中の泡の表示と、段階ごとの泡の色
- 回転盤とシーソー床。回転盤の上で照準を固定すると、向きを保ったまま横歩きで踏ん張る
- 6区画の灰色の箱ステージを JSON から生成。上面図で確認してから通路を狭め、敵が立ちふさがる配置に
-
隊列の敵とボス(マイルストーン3へ)
- 吹き飛んだ敵が他の敵にぶつかると、勢いが連鎖する
- ナラビ:隊長と隊員4体が縦一列で巡回し、プレイヤーが来ると横一列に組み替えて壁のように迫る
- ボス「ゼンマイ王」とアリーナ。3回落とすと撃破、落ちるたびにアリーナの形が変わる
- 足踏みと突進の前に、床に赤い予兆を 0.8 秒以上出す
-
自動プレイテストの仕組み
- シナリオ(JSON)でプレイヤーを自動で動かし、期待どおりかを判定する回帰テスト
- 壁へのめり込み・すり抜け・落下を毎フレーム監視。ランダム入力で全区画を叩くモンキーテスト
- エディタにテスト一覧のパネルとツールバーボタン、画像付きの HTML レポート
-
ボスのフェーズ2
- トコトコの召喚(戦闘前に用意した4体から、2体ずつ)と、床すれすれの回転アーム
- 包んだトコトコを蹴っても、歩いているボスに当たらず素通りする不具合を見つけて直した
-
ボスのフェーズ3
- アリーナ中央を全方向に傾く円盤シーソーに。左右からせり上がる送風機
- 着地点を予告するジャンプと、アリーナ全体に広がる衝撃波
- 重いボスには風と傾きが弱く効くようにし、勝手に落ちないことをテストで確認
-
ボス撃破までの通しプレイ(マイルストーン3の完了)
- 区画6を歩き通し、3つのフェーズをそれぞれの攻略法で落として撃破する自動テスト
Enemies & gimmicks
敵とギミック
敵はすべて StateTree で動き、「徘徊・攻撃・被弾・包まれ中・落下中」の状態を共通の土台で持つ。重さで吹き飛び方が変わり、それぞれに攻略の筋がある。
| 敵 | 重さ | 動き | 攻略 | 初出 |
|---|---|---|---|---|
| トコトコ | 軽 | 主人公へ近づいて体当たり | 小玉の連射 | 区画1 |
| ポンプ | 中 | 高所に陣取り、山なりの弾で押し出す | 段差越しの射撃、反射弾 | 区画2 |
| タテモチ | 重 | 正面の盾で弾を弾く | 反射弾で背面を狙う、包んだ泡を蹴り当てる | 区画3 |
| フワリ | 軽 | 浮いて穴の上も移動する | 包むと浮力を失い、穴の上で割れると落ちる | 区画4 |
| ユカワリ | 重 | 跳んで床を叩き、崩れる床を落とす | 着地の隙に大玉、自分で開けた穴へ押す | 区画5 |
| ナラビ | 軽 | 5体の隊列で巡回し、横一列に組み替えて迫る | 隊長を落とすと隊列が崩れる。中玉で列ごと押し出す | 区画6 |
| ゼンマイ王 | 超重 | 正面は装甲。落ちるたびにフェーズが進み、攻撃が変わる(足踏み・突進→召喚・回転アーム→ジャンプ・全方位衝撃波) | 背中のゼンマイでよろけさせて押す/包んだトコトコを蹴り当てる/傾きと風を使う | ボス |
ギミックは「形が変わる足場」と「範囲内のものを押す力場」の2つの土台に収め、主人公・敵・弾・泡が同じ仕組みで影響を受ける。
Stage
6区画のステージとボスアリーナ
ステージは30〜90秒の「区画」の連なりで、区画ごとに敵とギミックの組み合わせを1つ出題する。落ちたら直前の区画の頭から戻るので、挑戦のコストが低い。
配置は Python のスクリプトが書き出す JSON を正とし、エディタのツールでレベルに生成する。レベル上で手で動かさないので、直したいときはスクリプトを直して作り直すだけで済む。
生成の前には必ず上面図の画像を作って確認してもらう、という約束にしている。2日目の確認では「広すぎて敵をすり抜けられる」という指摘から、通路を3〜5 m に狭め、2〜3 m の関門に敵を置く形に組み直した。
Boss
ボス「ゼンマイ王」
ボスも「落として倒す」。直径24 m の円いアリーナで3回場外へ落とすと撃破で、落ちるたびにアリーナの形と攻撃が変わる。正面は装甲で泡を弾き、背中のゼンマイに当てると「よろけ」、よろけている間は普段の5倍吹き飛ぶ。
| フェーズ | アリーナ | ボスの攻撃 | 攻略 |
|---|---|---|---|
| 1 | 平らな円。反射柱が4本 | 突進、足踏みの衝撃波 | 反射柱や背後から背中のゼンマイを撃ち、よろけている間に完璧玉で押し出す |
| 2 | 外周16枚が崩れる床になる | トコトコを2体ずつ呼ぶ、床すれすれの回転アーム | 呼ばれたトコトコを大玉で包み、ボスに蹴り当てると強くよろけて吹き飛ぶ |
| 3 | 外周が落ち、中央の直径16 m が全方向に傾くシーソーになる。左右から送風機がせり上がり、交互に風を送る | プレイヤーの方へジャンプして円盤を傾ける、アリーナ全体に広がる衝撃波 | 傾きと風を使い、下り側へ押し出す |
強い攻撃には必ず床に赤い予兆を 0.8 秒以上出す。足踏みは足元の円、回転アームは腕の届く範囲、ジャンプは着地点、衝撃波はアリーナ全体。床すれすれの攻撃(足踏み・回転アーム・衝撃波)は、来る少し前にジャンプすればかわせる。
召喚するトコトコは戦闘の前に4体だけ作っておき、戦闘中には新しく作らない(ヒッチ対策)。フェーズ3で円盤が傾いても予兆の円が床に沿うよう、床の向きを調べて置いている。
作りながら決めたこと
- 回転アームは背中側から振り始める。正面から振ると、目の前のプレイヤーには予兆が終わった瞬間に当たり、避けようがなかった。
- フェーズ3では最初、ボスにも風が全力で当たり、風と傾きだけでボスが勝手に落ちそうだった。重いボスには風も傾きによる滑りも3割だけ効くようにし、プレイヤーが何もしなければ20秒たっても落ちないことをテストで確かめている。
- アリーナの送風機は区画4のものより弱くした。円盤の上にはつかまる物がないため。
How it was built
作り方の工夫
ソロ開発で、コードだけでなくブループリント・アセット・レベルの編集まで Claude Code が受け持っている。速さと確かさを両立させるために、次の4つを決まりにした。
エディタを外から動かす
エンジン付属の Unreal MCP を使い、アセットの作成、プロパティの設定、マテリアル、PIE の開始と停止まで、すべてツールから行う。プロジェクト専用のツールも C++ で足している。
データを正にして生成する
敵の AI(StateTree)とステージの配置は、グラフやレベルを手で触らず JSON から生成する。差分がテキストで見え、何度でも作り直せる。
手触りは決定論的に
吹き飛び、反射、落下は物理エンジンに任せず自前で計算する。同じ入力なら同じ結果になるので、調整もテストもしやすい。調整値はすべて DataAsset に出している。
見せてから作る
マップは上面図、ボスは手順と図を先に見せて了承をもらってから作る。手触りや見た目の判断が要るところは、作ったあとに確認をお願いしている。
Automated playtests
自動プレイテスト
最初は、PIE に入力を注入して状態を記録するツールで、そのつど挙動を確かめていた。4日目にそれを、確かめた挙動をシナリオとして残し、何度でも流せる回帰テストに作り直した。
シナリオは「入力を押し続ける」「目標地点まで自動で歩く」「条件が成り立つまで待つ」「ランダムに操作する」といった手順と、その途中や終わりに成り立つべき条件を JSON で書く。ゲーム時間を 1/60 秒刻みで固定するので結果がぶれず、実時間より速く進む。
| グループ | 件数 | 確かめていること |
|---|---|---|
| Player | 7 | 移動、ジャンプ、射撃、落下と復帰。壁で止まるか(歩き・ダッシュ・最強の吹き飛びを正面・斜め・空中から) |
| Gimmick | 6 | 空のレベルにギミックを1つ置いた単体テスト。回転盤は「8秒で1周」まで確かめる |
| Enemy | 2 | トコトコの突進、包んで蹴った泡が別の敵に当たって吹き飛ばすこと |
| Boss | 13 | 強い攻撃の予兆が 0.8 秒以上出ること、床すれすれの攻撃をジャンプで避けられること、召喚、蹴り当てで強くよろけること、フェーズ3のアリーナの変形と傾き、ボスが勝手に落ちないこと、3回目の落下で撃破になること |
| Stage | 4 | 区画1・4・6を、敵を止めて歩き通せること。区画6からボス撃破までの通しプレイ |
| Monkey | 7 | 全区画でランダム入力を20秒。1回あたり約75 m 動き、3〜6回落ちる中で、誰も壁や床にめり込まず、すり抜けないこと |
| Harness | 4 | 仕組み自体の自己テスト。わざと壁の中に入れたり落としたりして、ちゃんと失敗として検出されること |
本当にバグを見つけられるか、わざと壊して確かめた
3日目に直した「ボスが足踏みの直後にクールダウンを無視して突進する」バグを、コードに一時的に戻して流した。ボスのテストは2本とも失敗し、原因の分かるメッセージを出した。
[step 5 'stomp ends', t=2.33] expected enemies[S7_Zenmai].aiState contains "Wander", but was "Root/Ram"
修正を戻すと合格に戻る。この確認で、再発防止のつもりだったテストが実はこのバグを見逃していたことにも気づき、ちゃんと失敗するように書き直した。
エディタのパネルとレポート
Play ボタンの右に Playtests ボタンを足した。パネルでテストをグループごとにチェックして実行でき、合格・失敗・実行中がアイコンで分かる。結果は画像付きの HTML レポートにまとまり、テストごとにプレイヤーの経路の上面図と、ステップごとの画面が並ぶ。
Bugs found and fixed
見つけて直した主な不具合
作るそばから挙動を数値で確かめているので、遊んで気づく前の段階で見つかったものが多い。
| 症状 | 原因 | 直し方 |
|---|---|---|
| ボスが足踏みの直後に、クールダウンを無視して突進する | StateTree は前の状態の終了処理より先に次の状態を選ぶため、クールダウンの記録が間に合っていなかった | 攻撃が終わったフレームで記録する。同じ問題があったユカワリの床叩きも直した |
| 崩れる床と一緒に落ちるとき、プレイヤーが床にめり込んで見える(テストの動画で見つかった) | 床は世界の重力で、プレイヤーは2.5倍の重力で落ちるため、プレイヤーが床を追い越していた | 床は乗っている人の重力の1.2倍で落ちる。テストに「足が床の上面より下に入らない」チェックを足し、修正前に失敗することを確かめた |
| 包んだトコトコを蹴っても、歩いているボスに当たらず素通りする(ボス戦のテストで見つかった) | 泡の殻は体より大きく、殻が先にボスを押しのけるので、体どうしが触れず「当たった」ことにならなかった | 動いている泡は殻の大きさで当たりを調べる。先にこのバグで失敗するテストを書いて確かめた |
| 回転盤の上からテレポートすると大きく吹き飛ぶ | 回っている足場の速度を、移動先でも受け継いでいた | テレポートや復帰の前に、乗っている足場から切り離す |
| 回転盤の上で照準を固定していると、少しずつずれて落ちる | 横歩きアニメの移動量がキャラクターを動かしていた | 横歩き中はアニメの移動量を使わない |
| 敵が勝手に落ちていく | 別の区画のプレイヤーを追う、風に流される、崩れる床に乗る、着地点の判定がプレイヤー自身に当たる | 敵は自分の区画のプレイヤーだけを狙い、崩れる床は崖として扱い、着地点は床だけで判定する |
| テストが、敵の復帰を「壁のすり抜け」と誤検出する | 瞬間移動を「6 m 以上の移動」だけで判定していた | その敵の速度からありえない移動を瞬間移動とみなす |
Next
これから
- 実際に遊んで手触りを調整する(ボスの攻撃の強さと速さ、フェーズ3の風と傾き)
- ボス撃破後の流れと、スコア・リザルト
- マイルストーン4:トゥーン表現、主人公、UI、仮サウンド
新しい敵やギミックには、そのつど単体の自動テストを足していく。バグを直すときは、先にそのバグで失敗するテストを書いてから直す。