Development report · Vertical slice

Bubble & Tumble 開発レポート

マザーグースの「落ちる歌」を舞台にした、シャボン玉で敵を弾いて落とし合うクォータービュー3Dアクション。UE5.8 / C++ で、バーチカルスライス(1ステージ+ボス)を作っている途中経過をまとめた。個人で開発中の作品で、ここに書いた内容は今後変わることがある。

個人制作期間 2026-09-27 〜 2026-10-08作業日 4日実質の作業 約9.5時間UE 5.8 / C++Steam・Steam Deck 向け
キービジュアル。麦わら帽子のジルと赤い帽子のジャックが、シャボン杖を手に浮島のあいだを落ちていく
キービジュアル(画像生成AI GPT-Image で作成したイメージ)。主人公は童謡「ジャックとジル」の兄妹で、タイトルの Tumble は「ジャックが転び、ジルも転げ落ちる」という一節から取っている。

At a glance

4日間の作業でできたもの

期間は 2026-09-27 〜 10-08 の12日間で、そのうち作業したのは 9/27・10/4・10/5・10/8 の4日。会話ログの時刻から数えた実質の作業時間は約9時間半で、そのうち Claude が作業していたのは約6時間20分(ビルドやテストの待ちを含む)。残りは返答を見て次の指示を決めていた時間で、10分を超える間は何もしていない時間として除いた。

9.5時間の実質作業(うち Claude の作業が約6時間20分)
47コミット(すべて GitHub にプッシュ済み)
1.1万行のゲーム本体 C++(プレイヤー・泡・敵・ギミック・カメラ)
5,700行のエディタ拡張 C++(MCP ツール・自動テスト・パネル)
6+1敵6種とボス1体(StateTree AI)
10ギミック(変形する足場・力場の2系統)
7区画(6区画+ボスアリーナ、配置は92アクタ)
30本の自動プレイテスト(全件約3分、すべて合格)

The game

どんなゲームか

ナムコの『メルヘンメイズ』(1988)に影響を受けたオリジナル作品。同作の「シャボン玉で敵を弾き、落とし合う」遊びを手がかりに、反射する弾、敵を泡で包んで蹴る「包み込み」、多方向に進むステージ、高低差を加えている。同作のタイトル・キャラクター・曲・ステージは使っていない。

バーチカルスライスで証明したいのは3つ。反射弾や包み込みで敵を落とすのが気持ちいいこと、落ちても理不尽に感じないこと、ギミックと敵の組み合わせで局面が毎回変わること。

ゲーム画面のイメージ。浮島の上でジルとジャックがシャボン玉を撃ち、黒い敵を弾き飛ばしている
目指すゲーム画面のイメージ(GPT-Image で作成。実際のゲーム画面ではない)。いまは灰色の箱で遊びの骨組みを作っている段階。
ジルの設定画。麦わら帽子に青いリボン、クリームのワンピースと青いエプロン
ジル(1P)の設定画(GPT-Image で作成)。真上から見ても分かるよう、帽子とリボンで識別する。
ジャックの設定画。先の尖った赤橙のフェルト帽と茶の半ズボン
ジャック(2P)の設定画(GPT-Image で作成)。2人協力は製品版に入れるが、カメラ・入力・復帰は最初から2人前提で作っている。

Timeline

4日間の歩み

  1. コアの手触りを作る(マイルストーン1)

    • 真上から斜めに見下ろす固定カメラと、区画ごとにカメラの向きを切り替える仕組み
    • 画面基準の移動、ジャンプの猶予と先行入力、地上と空中のダッシュ
    • シャボン杖:溜めで小玉・中玉・大玉、プールした泡、独自の反射計算、照準の予測線
    • 決定論的な吹き飛び(物理エンジンに任せない)、被弾の蓄積、落下と区画頭からの復帰
    • 反射壁、泡のキャッチとストック、包み込み(3秒浮かぶ泡を押す・蹴る・踏む)
    • Unreal MCP を有効にして、エディタを外から動かして検証する仕組みを作る
    • 敵の土台と StateTree AI、最初の敵トコトコ
  2. 敵とギミックを揃え、ステージを組む(マイルストーン2)

    • ギミックの2系統の土台(変形する足場、力場)と、昇降床・崩れる床・跳ね床・送風機・反射スイッチ
    • ポンプ、タテモチ、フワリ、ユカワリ
    • 溜め中の泡の表示と、段階ごとの泡の色
    • 回転盤とシーソー床。回転盤の上で照準を固定すると、向きを保ったまま横歩きで踏ん張る
    • 6区画の灰色の箱ステージを JSON から生成。上面図で確認してから通路を狭め、敵が立ちふさがる配置に
  3. 隊列の敵とボス(マイルストーン3へ)

    • 吹き飛んだ敵が他の敵にぶつかると、勢いが連鎖する
    • ナラビ:隊長と隊員4体が縦一列で巡回し、プレイヤーが来ると横一列に組み替えて壁のように迫る
    • ボス「ゼンマイ王」とアリーナ。3回落とすと撃破、落ちるたびにアリーナの形が変わる
    • 足踏みと突進の前に、床に赤い予兆を 0.8 秒以上出す
  4. 自動プレイテストの仕組み

    • シナリオ(JSON)でプレイヤーを自動で動かし、期待どおりかを判定する回帰テスト
    • 壁へのめり込み・すり抜け・落下を毎フレーム監視。ランダム入力で全区画を叩くモンキーテスト
    • エディタにテスト一覧のパネルとツールバーボタン、画像付きの HTML レポート

Enemies & gimmicks

敵とギミック

敵はすべて StateTree で動き、「徘徊・攻撃・被弾・包まれ中・落下中」の状態を共通の土台で持つ。重さで吹き飛び方が変わり、それぞれに攻略の筋がある。

敵重さ動き攻略初出
トコトコ軽主人公へ近づいて体当たり小玉の連射区画1
ポンプ中高所に陣取り、山なりの弾で押し出す段差越しの射撃、反射弾区画2
タテモチ重正面の盾で弾を弾く反射弾で背面を狙う、包んだ泡を蹴り当てる区画3
フワリ軽浮いて穴の上も移動する包むと浮力を失い、穴の上で割れると落ちる区画4
ユカワリ重跳んで床を叩き、崩れる床を落とす着地の隙に大玉、自分で開けた穴へ押す区画5
ナラビ軽5体の隊列で巡回し、横一列に組み替えて迫る隊長を落とすと隊列が崩れる。中玉で列ごと押し出す区画6
ゼンマイ王超重正面は装甲、足踏みと突進。落ちるたびにフェーズが進む背中のゼンマイに当ててよろけさせ、大玉で押すボス
反射壁反射スイッチと橋跳ね床崩れる床昇降床回転盤シーソー床送風機滑る床加速床

ギミックは「形が変わる足場」と「範囲内のものを押す力場」の2つの土台に収め、主人公・敵・弾・泡が同じ仕組みで影響を受ける。

区画6でナラビの隊列(水色の隊員と黄色の隊長)が並んで進んでくる
区画6。ナラビの隊(水色の隊員と黄色の隊長)が組み替えながら迫ってくる。
回転盤の上を歩いて渡るプレイヤー
回転盤。8秒で1周し、乗っている人や敵も一緒に回る。
照準の点線を伸ばしながら敵に向かうプレイヤー
照準の予測線(点線)。実際の弾と同じ反射計算で描いている。

Stage

6区画のステージとボスアリーナ

ステージは30〜90秒の「区画」の連なりで、区画ごとに敵とギミックの組み合わせを1つ出題する。落ちたら直前の区画の頭から戻るので、挑戦のコストが低い。

配置は Python のスクリプトが書き出す JSON を正とし、エディタのツールでレベルに生成する。レベル上で手で動かさないので、直したいときはスクリプトを直して作り直すだけで済む。

生成の前には必ず上面図の画像を作って確認してもらう、という約束にしている。2日目の確認では「広すぎて敵をすり抜けられる」という指摘から、通路を3〜5 m に狭め、2〜3 m の関門に敵を置く形に組み直した。

VSステージの上面図。区画1から区画6までが折れ曲がりながらつながり、上端に円形のボスアリーナがある
生成前に確認に使った上面図。床の色は高さ、丸は敵の種類を表す。上端の円がボスアリーナ。

Boss

ボス「ゼンマイ王」

3回場外へ落とすと撃破。落ちるたびにアリーナが変形する。フェーズ1は反射柱が4本ある平らな円、フェーズ2は外周が崩れる床になり、フェーズ3は外周が落ちて中央が丸ごとシーソーになる。

強い攻撃には床に赤い予兆を出す。足踏みは足元から円が広がり、1.0 秒後に衝撃波が来る。ジャンプしていれば当たらない。

ボスアリーナの3フェーズの上面図
ボスアリーナの3フェーズを描いた上面図。手順を相談するときに使った。
ボスの足元に赤い円の予兆が広がっている
足踏みの予兆。自動プレイテストが撮った画面で、このあとジャンプして衝撃波を避ける。
ボスアリーナの外周を照準しながら歩くプレイヤー
アリーナの外周。フェーズ2ではこの外周が崩れる床に変わる。

How it was built

作り方の工夫

ソロ開発で、コードだけでなくブループリント・アセット・レベルの編集まで Claude Code が受け持っている。速さと確かさを両立させるために、次の4つを決まりにした。

エディタを外から動かす

エンジン付属の Unreal MCP を使い、アセットの作成、プロパティの設定、マテリアル、PIE の開始と停止まで、すべてツールから行う。プロジェクト専用のツールも C++ で足している。

データを正にして生成する

Python→JSON→エディタのツール→アセット・レベル

敵の AI(StateTree)とステージの配置は、グラフやレベルを手で触らず JSON から生成する。差分がテキストで見え、何度でも作り直せる。

手触りは決定論的に

吹き飛び、反射、落下は物理エンジンに任せず自前で計算する。同じ入力なら同じ結果になるので、調整もテストもしやすい。調整値はすべて DataAsset に出している。

見せてから作る

マップは上面図、ボスは手順と図を先に見せて了承をもらってから作る。手触りや見た目の判断が要るところは、作ったあとに確認をお願いしている。

Automated playtests

自動プレイテスト

最初は、PIE に入力を注入して状態を記録するツールで、そのつど挙動を確かめていた。4日目にそれを、確かめた挙動をシナリオとして残し、何度でも流せる回帰テストに作り直した。

シナリオは「入力を押し続ける」「目標地点まで自動で歩く」「条件が成り立つまで待つ」「ランダムに操作する」といった手順と、その途中や終わりに成り立つべき条件を JSON で書く。ゲーム時間を 1/60 秒刻みで固定するので結果がぶれず、実時間より速く進む。

自動プレイテストの実行の様子(約1分)。テストが実際にプレイヤーを操作している画面に、いまのステップ、テストが入力しているスティックとボタン、合否を重ねている。順に、ボスの足踏みをジャンプで避ける/区画6を回転盤とシーソーを渡って歩き通す/最強の吹き飛びで薄い壁に飛ばす/崩れる床/区画6のランダム操作/わざと戻したバグをテストが捕まえるところ。
グループ件数確かめていること
Player7移動、ジャンプ、射撃、落下と復帰。壁で止まるか(歩き・ダッシュ・最強の吹き飛びを正面・斜め・空中から)
Gimmick6空のレベルにギミックを1つ置いた単体テスト。回転盤は「8秒で1周」まで確かめる
Enemy・Boss3トコトコの突進、足踏みの予兆が 0.8 秒以上出ること、ジャンプで避けられること、足踏み直後に突進しないこと
Stage3区画1・4・6を、敵を止めて歩き通せること(回転盤とシーソーの上も含む)
Monkey7全区画でランダム入力を20秒。1回あたり約75 m 動き、3〜6回落ちる中で、誰も壁や床にめり込まず、すり抜けないこと
Harness4仕組み自体の自己テスト。わざと壁の中に入れたり落としたりして、ちゃんと失敗として検出されること

本当にバグを見つけられるか、わざと壊して確かめた

3日目に直した「ボスが足踏みの直後にクールダウンを無視して突進する」バグを、コードに一時的に戻して流した。ボスのテストは2本とも失敗し、原因の分かるメッセージを出した。

[step 5 'stomp ends', t=2.33] expected enemies[S7_Zenmai].aiState contains "Wander", but was "Root/Ram"

修正を戻すと合格に戻る。この確認で、再発防止のつもりだったテストが実はこのバグを見逃していたことにも気づき、ちゃんと失敗するように書き直した。

エディタのパネルとレポート

Play ボタンの右に Playtests ボタンを足した。パネルでテストをグループごとにチェックして実行でき、合格・失敗・実行中がアイコンで分かる。結果は画像付きの HTML レポートにまとまり、テストごとにプレイヤーの経路の上面図と、ステップごとの画面が並ぶ。

Unreal Editor のツールバーに Playtests ボタンがあり、自動プレイテストのパネルにテストがグループごとに並んでいる
エディタの画面。ツールバーの Playtests ボタンと、Boss の2件をパネルから流し終えたところ。
HTMLレポートの冒頭。合格30、失敗0、未実行0
HTML レポートの冒頭。30件すべて合格。
HTMLレポートのステップごとの画像
テストの中身。ステップごとに、その瞬間の画面が並ぶ。

Bugs found and fixed

見つけて直した主な不具合

作るそばから挙動を数値で確かめているので、遊んで気づく前の段階で見つかったものが多い。

症状原因直し方
ボスが足踏みの直後に、クールダウンを無視して突進するStateTree は前の状態の終了処理より先に次の状態を選ぶため、クールダウンの記録が間に合っていなかった攻撃が終わったフレームで記録する。同じ問題があったユカワリの床叩きも直した
崩れる床と一緒に落ちるとき、プレイヤーが床にめり込んで見える(テストの動画で見つかった)床は世界の重力で、プレイヤーは2.5倍の重力で落ちるため、プレイヤーが床を追い越していた床は乗っている人の重力の1.2倍で落ちる。テストに「足が床の上面より下に入らない」チェックを足し、修正前に失敗することを確かめた
回転盤の上からテレポートすると大きく吹き飛ぶ回っている足場の速度を、移動先でも受け継いでいたテレポートや復帰の前に、乗っている足場から切り離す
回転盤の上で照準を固定していると、少しずつずれて落ちる横歩きアニメの移動量がキャラクターを動かしていた横歩き中はアニメの移動量を使わない
敵が勝手に落ちていく別の区画のプレイヤーを追う、風に流される、崩れる床に乗る、着地点の判定がプレイヤー自身に当たる敵は自分の区画のプレイヤーだけを狙い、崩れる床は崖として扱い、着地点は床だけで判定する
テストが、敵の復帰を「壁のすり抜け」と誤検出する瞬間移動を「6 m 以上の移動」だけで判定していたその敵の速度からありえない移動を瞬間移動とみなす

Next

これから

  1. ボスのフェーズ2:トコトコの召喚(プールから2体ずつ)と回転アーム
  2. ボスのフェーズ3:アリーナ中央のシーソー化、せり上がる送風機、ジャンプで傾きを変える攻撃、全方位の衝撃波
  3. 区画6からボス撃破までの通しプレイと、その自動テスト

新しい敵やギミックには、そのつど単体の自動テストを足していく。バグを直すときは、先にそのバグで失敗するテストを書いてから直す。