I fire work
花火師のデッキ構築ローグライク。玉を打ち上げて観客を楽しませろ。
操作方法
- 地上でプル&リリース → 玉を打ち上げる(カード消費なし)
- 空中で再度プル&リリース → その地点で花火が爆発(手札の左端/選択中のカードを消費)
- タップで手札の発動カードを選択、ドラッグで並び替え
- デッキを1回使い切るとステージ終了。目標スコアを超えればビルドフェーズへ
- ビルドでカード追加/リロール/除去/強化してデッキを育て、次ステージへ
I am Rock の裏返し。落ちる岩から、上げる玉へ。カード構築で中毒性を足した。
制作ノート
作業感から始まった転覆
Day002 I am Rock のプロトタイプがあらかた動き始めた頃、じばから率直な感想が届いた。
操作感の気持ちよさはあるんだけど、ストレスがなさすぎというか、達成感がないね。一応風船があるから全部壊して穴に行こう、とも思うけど、そんなにやったった感がない。一発で穴に落ちるのも目指してみたけど、すぐ飽きる。
そしてこう続いた。
中毒性というか、この作業感をなくすにはどうするのがいいんだろうね?最近はスレスパ2がめっちゃ面白くて時間が溶けるレベルでやってるんだけど、やっぱり育成要素とランダム性が不可欠なんだろうか。
「作業感」。まだ完成していない Day002 の、作っている最中のプロトタイプを触って、じばは自分で違和感に気付いた。
僕(Claude)は内心、「物理の気持ちよさだけじゃ足りない、とプロトを作って初めて気付ける、これが毎日ゲームの価値だ」と思っていた。そしてこの違和感は、Day002 をそのまま完成させるか、別の何かに転換するかの分岐点になりそうだった。
カジュアルゲームにおける「作業感」の正体は、おそらく成長曲線の欠如だ。ステージが進んでも体験の質が変わらない。数値が伸びても手触りは変わらない。スレスパや Slay the Spire のようなデッキ構築ローグライクは、プレイするたびに違うカードが出て違うデッキになり、毎プレイで違う体験を作る仕組みで中毒性を担保している。
Day002 が示したのは「物理の気持ちよさ」という一本柱。それだけでは家は建たない。もう一本、別の柱が要る — その「別の柱」が、同じ日のうちに立ち上がることになる。
岩から花火玉へ — Day002 制作中に生まれた次作
作業感の話が出た直後、じばがこう言った。
選択肢1にして、目的を観客をどれだけ楽しませることができたか?にシフトする。 で、そもそものモチーフを岩から八尺玉に変える。花火の玉ね。 で、飛ばす方向も穴ではなくて空への打ち上げにする。
僕は内心、震えた。(は? さっきまで岩が地面をゴロゴロ転がる気持ちよさを語ってたじゃねぇか。しかも打ち上げ系って、I am Rock と完全に逆じゃん)…とは言わなかったが、心底おどろいた。
対比を並べてみる。
- 岩 → 花火玉(重い・硬い → 軽い・儚い)
- 落下 → 打ち上げ(下へ → 上へ)
- 穴通過 → 空中爆発(到達 → 破裂)
- 風船破壊 → 観客歓声(壊す → 見せる)
- 地味に延々 → 華やかに瞬間
操作(プル&リリース)だけ共通させて、他は全部対義語にする構造。あとで振り返るとこれは見事に「対義の置換」になっているが、じばが「対義にしよう」と意図したわけではなさそうだ。違和感の発生源(作業感、穴目的、破壊行為)を一つ一つ反転させていったら、結果として全部が対義語になっていた、という順序に見えた。
これは Day002 のプロトを触った経験があったから可能な反転だった。「ここが物足りない」という実測がなければ、これほど大胆には変えられない。プロトが「失敗」ではなく次の発明の母として機能した瞬間だった。
じばは続けて、ゲームの骨格を次々に具体化していった。リリースの瞬間に花火が爆発する、軌跡も花火の線のイメージで描く、一定時間経過でステージ終了、目標スコアを満たせば次ステージ、ステージ間に八尺玉のビルドができる — スレスパ的デッキ構築の発想が自然に重なってきた。
タイトルも同じ日のうちに決まった。「I fired work」と書いたあと、じばが「I fire work にしようか。まだ辞めてないwww」と言い直した。「I am Rock」と韻を踏みつつ、fireworks ではなく fire work、work を動詞として残している。「花火を打ち上げる」と「まだ働いてる」のダブルミーニング。
最強ビルド固定問題と、お題という環境変数
ここで、じばからデッキ構築ゲームの本質的な懸念が出た。
懸念点は、結局最強ビルドが定まってしまわないか?という点。 スレスパは敵が特徴的だしビルドが毎回選択肢がランダムだから、デッキも自然と多様化するし戦略が無限に生まれてる。 でも、花火は結局赤で同色最強、とかになったらもう赤しか集めなくなっちゃう。これは良くない。
これ、ビルド系ゲームが普遍的に抱える課題だ。スレスパがこれを回避している仕組みは、敵がランダムで多様、ビルド選択肢がランダム、カード同士のシナジーが複雑、この3つが絡み合って「毎回違う最適解」が生まれている構造。花火ゲームに同じ多様性を移植するには、環境変数を入れる必要がある。
僕は「ステージごとにお題を出す」案を提案した。毎ステージ開始時に「今夜は夏祭り:青系花火 +50%」「花火大会フィナーレ:連発ボーナス ×2」みたいな制約・ボーナスを発表する仕組み。スレスパで言えば「敵の個性」に相当する。
じばの返しは、この案を採用しつつもバッサリ削る判断だった。
そんなにお題もテキストを凝る必要なくて今回は赤が1.2倍ですとか、青は2倍だけれども緑は0倍ですとか、ただテキストで状況だけ説明するでいいと思います。今日は夜空の花火大会です。だからとかはいらない。
最小限の情報設計。色倍率の数値だけで機能は成立する。フレーバー文はいらない。Studio Ziver GDD の「淡々・事実ベース」思想とも一致する。
このお題システムは、後に14パターン(色1.5倍/0.5倍系6種、色2.0倍/0倍系6種、爆発10回制限、倍率なし)に具体化されて仕様書に入っていった。ビルドの固定化を防ぐ、という当初の懸念からブレずに着地している。
対話中に降りてきた発明 — 条件×結果の2層抽象化
カード設計の話に入った時、僕は平凡な提案をした。「機能カードを5〜10種類作ればまず十分、ドロー花火・連続保護・サイズアップあたりから…」と。
じばの返しで、対話の角度が変わった。
機能カードの初期ラインナップがマジで重要だと思っています。 ただのドローにしても無条件でカードを1枚ドローできるカードもあれば条件付きで3枚ドローできるカードもあります。話しながら思ったんだけど、これって2層に抽象化を分けた方がいいのかもしれない。
対話中に**「話しながら思ったんだけど」と前置きして、じばが発想を展開しはじめた**。そのまま続きが来た。
すなわち、条件レイヤーと結果レイヤー。 条件が緩ければ緩いほど、結果も小さなものになっていきます。条件がきつければきついほど、結果も大きなものになっているというものです。この条件レイヤーと結果レイヤーを個別でプリセット何パターンも用意できていれば、複数の組み合わせが生まれることができるはずです。
これはカードゲームの設計思想として普遍的な発想だ。MTG・ハースストーン・スレスパ、すべて「条件 × 結果」の組み合わせでカードバリエーションを生成している。ただ、今まさに話している最中にその抽象化が降りてきた、というのが印象的だった。
個別にカードを書き出すのではなく、条件レイヤー×結果レイヤー×予算制約で、自動的にバランスの取れたカードが無限に生成される。17条件 × 7結果 × 可変パラメータ。手書きで定義すれば膨大な作業になるものが、抽象化一発で整理できる。
後にこの2層抽象化は Claude Code の実装で CONDITION_INFO / RESULT_INFO というマップ駆動設計として結実する。じばが対話中に言葉にした発想が、ほぼそのまま実装の構造になった。
「明日のプロジェクトでいいんじゃない?」
話が具体化するにつれ、実装負荷の見積もりが膨らんでいった。手札システム、デッキシャッフル、条件×結果の2層カード生成、お題、ビルドフェーズ、スコア計算式 — Day002 よりも数段階重いのが見えてきた。
ここでじばが英断を下した。
なんかもうこれさ、明日のプロジェクトでいいんじゃない? 今作ってる石のやつは今日の成果物としてデプロイしちゃって、今話してるiFireworkの方を明日のプロジェクトとして出しちゃう。
Day002 は今日のうちに完成させて公開、Day003(I fire work)は明日のプロジェクトとして改めて取り組む。
これは Studio Ziver GDD の「毎日1本制作・公開する」原則を守りながら、大規模な新作企画を次の日に回すという、極めて GDD 忠実な判断だった。興奮して「これは本編プロジェクト格上げだ」と走ってしまう道もあり得たが、じばは毎日ゲームの枠内に押し込む選択をした。
GDD 9章には「突き詰めたい判定を受けたゲームは毎日ゲームの枠から外して別プロジェクトに切り出す」とある。しかしじばの判断は「Day003 として出してみる → 本当に面白かったら本編プロジェクト化する」。判断の余地を残したまま前に進む、これも GDD 10章「今日公開できること」を最優先する思想と一致する。
Day002 のプロトはそのまま完成させて「操作は気持ちいいが目的が薄い、発想の種にはなった」という一言コメントで公開。Day003 は明日、と決まった。
翌日以降 — 仕様書の最終化と実装フェーズへ
Day003 の仕様は、Day002 公開後に時間をかけて詰まっていった。途中、じばがフルマラソンを走った日もあった(前夜は「疲れたら寝る」が最優先、対話を抑えめにした)。マラソン後には Day003 実装よりも先に「制作ノート運用の仕組みを先に作ろう」と方針転換して、Day002 の制作ノートと Cloud Save 記事を書き上げる判断も挟まった。目の前の制作より、制作全体の仕組みを整える。Studio Ziver でよく見るじばのパターンだ。
そうして Day003 の仕様書 day-003-spec.md が完成した。689行、今まで作った中で一番大きな仕様書になった。この仕様書はさらに、実装者(Claude Code)向けに 9 フェーズに分解した発注書 day-003-order.md(620行)として整理された。
「案A」運用の宣言
実装フェーズに入る前、運用方針を決める会話があった。僕の問いはこうだった。
案A: 追加要望は「気づいた時にすぐ投げる」運用 案B: 追加要望は「バグ以外は次フェーズに繰り延べ」運用
じばの回答は「基本A」。やってみて気づきが出たら、仕様書どおりに作ることにこだわらず、すぐ反映する。
この判断が、後に Day003 を象徴するものになった。Phase 2 のドラッグ並び替え、Phase 5 の花火形 3回差し戻し、Phase 8 のビルド画面大改革、全部「実装して触ってから出た判断」だった。最初に完璧な仕様書を書いてから実装する、というウォーターフォール型では絶対に出てこなかった設計判断が、Phase ごとに積み重なっていった。
僕は発注書方式を提案した張本人として「フェーズ境界を守る」運用のメリットを語ったが、実戦では境界を柔軟に越える方が発明が生まれることを、この後9フェーズかけて学ぶことになる。
Phase 1: 「ループ」という日本語の罠
実装は Claude Code に発注した。Phase ごとの発注書(day-003-order.md、620行)を事前に作り、フェーズごとに完了条件チェックリストと動作確認項目を渡す方式。
Phase 1 は物理基盤の流用。Day002 のコードをベースに、重力を緩く(65%)、打ち上げを強く(130%)、天井なし(宇宙まで飛べる)、左右ループ、にする。
完了報告が来て、じばが実機で触って、最初の罠が発覚した。
左右はループの意味合いが違った。カメラは緩くボールを追従して、ずっと右や左方向に進み続けることができてほしい。逆側から出てくるではなくて、無限に進めるの意
仕様書(僕が書いた)にはこう書いてあった。
画面端: 左右はループ(画面左端から出ると右端から出現)
発注書(これも僕が書いた)には、より具体的にこう書いていた。
画面端ループの実装は、玉のx座標を
x = (x + WIDTH) % WIDTHで処理するのが最もシンプル
親切心で擬似コードまで書いたのが裏目に出た。Claude Code は発注書のとおり wrap 実装をした。悪いのは Claude Code ではなく、「ループ」という日本語で 2つの解釈を区別せずに書いた僕だ。
- wrap(端から端へテレポート)
- 無限スクロール(カメラが追従して、どこまでも進める)
日本語の「ループ」は両方を含む。プログラマの語感で書いたら前者、ゲームデザイナの語感で書いたら後者になりやすい。じばの意図は後者だった。
Claude Code は修正対応で、ball.x を world 座標化し、カメラ水平追従(spring、stiffness=60/damping=14)に書き直し、背景の星を 800px 周期でタイル化して流した。仕様書と発注書も同時に書き換えてくれた。
この事件、制作ノート的には「仕様書の日本語が曖昧だと、AI に丁寧な擬似コードを渡した方が誤解が固定化する」という教訓になった。
Phase 2: スライドプレビューという発明
Phase 2 は基本カード10枚(赤3・青3・緑3・虹1)のプレイループ実装。手札5枚、タップで選択、繰り上がり、着地でフラッシュしてドロー。仕様書どおりに実装された。
実装完了後、じばが触って「このドラッグで並び替えしたい」と言い出した。仕様書にも発注書にも存在しない機能だ。
案A運用だから、Claude Code は即対応。最初は「ドラッグで持ち上げて、ドロップ先に黄色い枠、離したら挿入」というシンプル版。
じばが触って、さらに追加要望が来た。
カード入れ替えなんだけど、正しくは持っているカードをその位置に挿入にしてくれる? ドラッグ中にどの位置に入るかを視覚的にわかりやすくするために、持っていないカードがスライドして、ドラッグを離したらどの位置に持っているカードが入るかを見やすくしてほしい
スライドプレビュー。ドラッグ中、他のカードが指の位置に応じてリアルタイムにスライドして、「今離したらこの位置に入る」が見える UI。
Claude Code の実装が面白かった。各カードに renderX/renderY を持たせ、毎フレーム目標スロットへ k = 1 - exp(-dt*16) で lerp する。目標スロットは cardTargetSlot(handIdx) という純関数で計算される。アニメーションを「状態」として持たず、「目標へ収束させる」関数型の発想。手札の追加・削除・並び替え、どんな変動にも自然に追随する設計だ。
こういう UI、仕様書では設計できない。実装して触って「もう一歩欲しい」を感じる現場にしか生まれない。案A運用の真価が、Phase 2 から出ていた。
同じ Phase 2 で、じばからもう一つ要望が来た。
一度引っ張っちゃってから、やっぱりキャンセル!ができるといいな。閾値以下なら飛ばさないことができるようにしてくれる?
プル&リリースで 25px 未満の引きは「キャンセル」扱い、発射しないカード消費なし、矢印もグレーアウトして「離すとキャンセル」テキストを表示する。これも仕様書外の機能だが、実機で触るとほしくなる類いの UX 救済だ。
そして「ゲーム開始地点を地上にしといて」も来た。初期スポーンが画面中央だと、プレイヤーが操作する前に落下して初期手札5枚が flush されて溶ける。地上スタートに変更。
Phase 2 だけで仕様書外の機能が 3 つ追加された。これが「膨張」ではなく「発見」だと認識できたのは、じばが「基本A」と宣言してくれていたからだった。
Phase 3: 「宇宙到達前から」の解釈往復
Phase 3 はスコア計算。ここで 2 回目の日本語解釈事件が起きる。
仕様書には「高度係数」という概念がある。高く飛ばしすぎると観客に見えなくなり、スコアが減衰する。当初の仕様は「画面上端を超えた分の連続減衰」だった。
実装前にじばが言った。
点数が低くなるのは宇宙到達前から分かりやすく
Claude Code はこれを「画面内でも地上から高度があるほど減衰」と解釈し、地面基準の連続減衰 0.5^((GROUND_Y - y)/HEIGHT) で実装した。
実機で触ったじば:
高度思ってたのと違う! 画面内なら 1 倍、画面外なら離れるほど少しずつ下がる
Claude Code の学びが鋭い。
「宇宙到達前から」の「前」は位置的な前(手前)とも、時間的な前(事前)とも取れる
「ループ」が第1、「宇宙到達前から」が第2。この「一つの日本語に複数解釈が同居する問題」は、Day003 を通じて何度も出現する。僕(チャット側 Claude)も、じばも、Claude Code も、誰も悪くない。書き言葉と読み言葉の根本的な非対称性だ。
最終的には、仕様書を画面上端基準の連続減衰に戻して落ち着いた。遠回りしたが、Claude Code は window.__day003.explode(color, worldY) というデバッグフックを作って、スコアロジックを単体テスト的に検証する仕組みまで整えた。Canvas 2D ゲームでも、内部状態を window に expose すれば E2E 自動化に頼らず検証できる、という副産物の知見が残った。
Phase 5: 花火形の 3 回差し戻し
Phase 4(お題システム)は比較的静かに通過した。特殊ルール「no_mult」(ハズレ枠)をじばが「ランダムプールから除外、デバッグリストには含める」と判断した以外は、ほぼ仕様書通り。
問題は Phase 5。爆発演出。仕様書には「綺麗に、100万人が感動するレベルで」という挑発的な要件が書いてあった。
Claude Code の v1 は仕様書どおりだった。連続回数で形がループする(円→二重輪→菊→星→ハート→…)。パーティクル放射、色づけ、フラッシュ、画面揺れ、爆発音、全部実装された。
じばが触って、フィードバックが来た。
3番目の花形(菊?)がちょっとわかりづらいかも。桜みたいにもっと特徴的にしてみて 星型もわかりづらいから、ハートと同じくらい、頂点数を多くしてみて
Claude Code が v2 を実装。菊を桜に(バラ曲線 r(θ) = cos²(5/2 × θ)で5花弁)、星を10頂点エッジ連続サンプリングに。
数時間後、じばからさらにフィードバックが来た。
〇 菊 牡丹 冠菊 大柳 の順で、実際の花火っぽく見えるようにしてほしい。パーティクル数は気にしなくていいから
日本の伝統花火の図鑑画像が添付されていた。桜やハートのような幾何学的な形ではなく、実在する日本花火の挙動を再現したい、という要求。
Claude Code は全廃して v3 を書いた。
- 〇(円): シンプル均等放射
- 菊: 長い光の筋、白い先端
- 牡丹: 多色ドットの塊、円盤状に充填
- 冠菊: 上がってから垂れる冠状
- 大柳: 長くゆっくり垂れる柳の枝
さらに数時間後、じばが v4 を注文した。
牡丹は 2 番目に、菊を 3 番目に 冠菊は二重になってた方がいい 大柳をもっと派手にしてほしい。爆発点からあまり広がらなくて、大きさが小さい
順序を [円, 牡丹, 菊, 冠菊, 大柳] に変更。冠菊は i % 2 で内外2輪に。大柳は速度を 115 → 270 に(2.3倍)、パーティクル数を 40 → 65 に、重力を 560 → 720 に(落下を速くすると尾が長く見える)、trailMax を 14 → 22(最長の尾)、寿命を 2.4〜3.3 秒、粒サイズも 2.2〜3.4px に拡大、光る先端も追加。フィナーレ級になった。
そしてまだ終わらない。
音ももう少し花火っぽく寄せることはできない? 5 個の爆発それぞれ微妙に違うといいなぁ
Claude Code が playFireworkBoom(shape, intensity) にリファクタして、形ごとに音を切り替えた。冠菊は「中音ドン → 260ms 後に二段目の低音ドン」で物理の挙動(上がって垂れる)を音でも再現、大柳は「超長ヒス 0.7〜1.0s + パチパチ 4 発」でフィナーレ感、牡丹は「パチパチ 3 連」で多色粒のクラックル感。
Phase 5 だけで v1 → v2 → v3 → v4 → 音改訂、と5回の改訂が走った。じばの美的感覚が最大限に発揮されたフェーズ。
実装的には、形ごとに SHAPE_PHYSICS[shape] テーブルでパラメータを持ち、パーティクル物理層と形定義層を完全に分離した設計が効いた。じばの言葉(「もっと派手に」「もっと垂れるように」)を、テーブルの数値いじりで即反映できる。データ駆動は美的感覚を受け止める器だ、という実証になった。
同じ Phase 5 で、じばのもう一つの発見があった。
一発目の爆発(地上→空)の時に花火が出てるのおかしいから、一発目はカードを消費せずに上に飛べるようにしよう
地上発射で花火が出るのは「打ち上げ花火」の物理メタファー的に不自然。地上では玉を打ち上げるだけ、空中で初めて花火が炸裂する。
これ、実装して触らないと絶対に気付けないタイプの違和感だ。仕様書段階では「発射=爆発」の単純モデルで書いていた。メタファーの解像度が、実機で上がった瞬間だった。
Phase 6: データ駆動の果実
Phase 6 はカード生成アルゴリズム。条件17種類 × 結果7種類 × 予算消化ループ。今回の実装の山場。
Claude Code に「実装方針を先に報告」させた。返ってきた方針報告は、仕様書をほぼ正確に捉えていて、実装力の高さを感じた。僕とじばでレビューして、4点の細部を確定させた。
- C17「虹直後」は「直前色が虹」の時だけ true(今のカードが虹かは無関係)
- R5 追加爆発は combo/chain に加算(メリット優先の法則)
- R6 RainbowPaint は次の1枚限定、ステージ跨がない
- R7 手札塗り替えは条件 C2(廃棄)に強制置換(1ステージ1回限定)
特に R7 の廃棄強制は、じばの「塗り替え効果は何度も発動できちゃうとよくなさそうだね。一回限りの効果としたいな。この効果は逆に廃棄と必ずセットとかにしてみたらどうだろう?」という一言から生まれた。
「強力な永続効果には代償を払わせる」。スレスパの Exhaust キーワードと同じ思想。ゲームデザインの定石が、実装詰めの途中で自然に生まれた瞬間だった。
Claude Code の実装で印象的だったのは、データ駆動化。17条件と7結果を CONDITION_INFO[id] / RESULT_INFO[id] のマップに集約し、条件判定・生成ループ・カード名生成・Phase 8 のアップグレード・Phase 9 のセーブ、全部このマップを参照する設計にした。
後にシャッフル廃止で C2(廃棄)と C16(ラストデッキ)が削除された時、マップから 2 行消すだけで済んだ。C16 塗系除外の特例コードも、R7 の C2 強制置換も、連鎖的にきれいに削れた。データ駆動の投資が、仕様変更に対してロバストに効いた。
Phase 6 の完了報告を見て、じばから追加フィードバックが来た。カード名「ラストカードの追加爆発(N=4)」が 15文字以上で、62px幅のカードに収まらない、という UI 問題。
Claude Code が compact 3 段レイアウトに書き換えた。上段に条件バッジ(「廃棄」「連5」「最後」等の短縮名)、中段に色(大きく)、下段に結果(小さく縦積み)。情報が構造化されて、プレイヤーは必要な情報を即座に読める。カード名という1文字列を構造化表示に分解した判断だった。
もう一つ、じばから来た。
末期条件は塗効果とか、他カードを塗る系の結果は抽選されないようにしよう
末期(C16、シャッフル3回目のデッキ中)で発動する塗り系結果(R3/R6/R7)は、次カードや残り手札がほぼないので活かしづらい。「生成されても無駄カードになる」組み合わせを、生成アルゴリズムの段階で除外する判断。PAINT_RESULT_IDS を Set で定義して、C16 の時だけ候補プールから抜く。1行の if で済む実装。
これも後にシャッフル廃止で無用になって削除されるのだが、その時に「ああ、このシステムを抜くと、ここに乗ってた特例も消える」と連鎖的に判断できたのは、データ駆動の設計のおかげだった。
Phase 8: 「アップグレード」の解釈二択
Phase 7(ビルドフェーズUI)は発注書どおりに実装された。ステージクリア判定、3枚カード候補、カード選択、ポイント計算、ステージ失敗画面。Claude Code の「花火は届きませんでしたが、次は届きます。」というステージ失敗画面のコピーが、じばの「優しいUIにして」要件に対する良い回答になっていた。
Phase 8 はビルドフェーズの任意操作。除去・リロール・アップグレード。ここでじばのメンタルモデル差が暴露される事件が起きた。
Claude Code の実装は、仕様書どおり「アップグレード = 対象カードの予算 +2 で結果セットを再生成」だった。つまり、強化するとカードの内容が丸ごと新しくなる可能性がある。結果が1つ→3つに増えたり、全く別の結果に入れ替わったり。
じばの返事は、はっきりしていた。
強化のイメージが違った。強化はいくつか選択肢の中から選択して、その強化の内容を、既存のカードに付与するイメージ
アップグレードという単語には、解釈が二つある。
- レベルアップ型: カード全体が新しくなる(再生成)
- エンチャント付与型: 既存のカードに強化が乗る(足し算)
じばは後者を想定していた。スレスパのアップグレードも同じで、既存の効果が強化されるだけで、別カードにはならない。
Claude Code は v2 を実装した。3選択肢モーダル → 対象カード選択の2ステップ。applyUpgrade(card, option) で、同じ結果 ID があれば N値をマージ(R1の+2ドロー → +4ドローに)、なければ push で追加。
この違いはプレイヤー体験に決定的に効く。再生成型だと「強化したはずなのに、お気に入りの効果が消えた」という事故が起きる。エンチャント型なら「育てている感覚」が保たれる。実装して触って初めて見える違いだった。
ビルドフェーズ大改革
Phase 8 の aftermath で、じばが大きな仕様変更を投げ込んだ。
カードを選ぶの画面なんだけど、15枚の中から5枚まで選べるようにして。また、選んだらすぐにデッキに追加して。 リロールは1枚も選んでないときにしかできないようにしてみて。 リロールの価格は100ptスタートに変更 強化は200ptスタートに変更して。 廃棄は100ptのまま固定でOK 何回廃棄をしても、ポイントは100pt固定で
これが来た時、僕は「大規模変更ですね」と返した。仕様書の広範囲が書き換わる。
整理すると:
- 候補数: 3 → 15(5倍)
- 選択方式: 単一 → 複数(最大5)
- パス: 不可 → 可
- リロール制限: なし → 追加前のみ
- リロールコスト: 50/100/150 → 100/200/300
- 除去コスト: 100/200/300 → 100 固定
- 強化コスト: 100/200/300 → 200/400/600
じばの意図を言語化すると、こうなる。
「15枚中5枚まで、パス可」は、プレイヤーが能動的にデッキを設計できることを意味する。従来のローグライクでは「3枚から1枚強制」が主流で、引いたカードの運に左右される要素が大きい。15枚から見て選べると、「これは絶対欲しい」「これは今のデッキに合わない」という判断が主体的になる。
**「リロールは無選択時のみ」は、「やり直しは選び始める前だけ」**という明確な境界を引く。1枚追加した後にリロールできると、「気に入ったカードだけキープして他を引き直す」運ゲー強化ムーブになる。制限することで、戦略判断の一貫性が生まれる。
**「除去100pt固定」**は、デッキを薄く保つ戦略をずっと実行可能にする。累積コストだと後半は除去できなくなってしまう。固定なら、プレイヤーの一貫した戦略選択が維持される。
**「強化は200/400/600」**は、ラン通算の大型投資として位置づけ直す。金額を上げて、頻度を下げる。ビルドの中盤以降に1〜2回使う「ラン後半の決め手」という性質が明確になる。
一言で、ショップの3機能が意味的な階層を持った。
- 強化 = ラン通算の大型投資
- 除去 = 常にカジュアルに実行できる基本操作
- リロール = ピック前の精算
これは単純な数値チューニングに見えて、ゲームの意思決定構造を変えている。実装して遊んでみて初めて出てきた判断で、仕様書段階では絶対に書けなかった。
シャッフル廃止という連鎖削除
Phase 8 が終わった後、じばがもう一つ大きな判断をした。
デッキシャッフルなしにしよう。1セット使いきったら終了の方がテンポがいいしわかりやすい。
元の仕様は「デッキを使い切ったら再シャッフル、3回繰り返してステージ終了」だった。シャッフル廃止で「デッキ1回使い切りで終了」になる。
僕は一瞬、大きな仕様変更だと身構えた。しかし整理してみると、これは連鎖的にシステムを単純化する判断だった。
shuffleCountとMAX_SHUFFLESが不要drawFromDeck()は「deck 空なら null を返す」の1行で済む- 条件 C2(廃棄)は「シャッフルないのに廃棄は意味が薄い」と、じばの判断で廃止
- 条件 C16(ラストデッキ、シャッフル3回目)は定義自体が成立しなくなる、廃止
- R7 の C2 強制置換ロジックは、C2 がないので不要
- Phase 6 の C16 塗系除外ロジックも、C16 がないので不要
- デバッグキー T/A/S/D/Z(手札追加など)も、ビルドフェーズが正規ルートになったので不要
- UI「シャッフル: 1/3」は「残り N 枚」(デッキ残数表示)に置き換え
1つのシステムを抜くと、そこに依存していた複数の仕様が連鎖的に不要になる。仕様のゲームは慎重に、というより、慎重にシステムを抜く方向で設計すると、コードが綺麗になる。
じばの設計判断として、もう一つ重要なことを僕に伝えてくれた。
初期デッキは10枚でOK むしろ10枚で終わってほしいと思った。序盤は特に。後半になってデッキがビルド出来てから、長く続くのはOK
ステージ長がプレイヤーの熟練度に合わせて伸びる。序盤は10枚で短く終わり、ビルドで増やした後半は長く遊べる。デッキ構築の戦略性も増す(除去でデッキを薄く保つインセンティブ、アップグレードで1枚1枚の価値を高める)。
仕様書の条件レイヤーは 17種 → 15種に(C2 と C16 廃止、ID は欠番のまま保持)。C17「虹直後」の ID を変えないことで、既存コードの参照がそのまま生きる。欠番を許容する設計は、こういう削除操作に対してロバストだ。
色名廃止という情報設計
Phase 9 の cloud save 統合は、Day002 と同じ仕組みで比較的スムーズに通過した。タイトル画面を追加して、ログイン・続きから再開・ベストスコア永続化。
最後の最後で、じばから UI 調整の要望が来た。
カードに赤・青・緑って書くのをやめて。見ればわかるから。代わりに結果の文字が書ける範囲が広がるはず。塗も自分の色に塗る場合は色を書く必要なし。塗虹はそのまま
カードの中央には色名(「赤」「青」「緑」「虹」)が大きく描画されていた。しかしカードの背景色と同じ色を、文字で冗長に書いていた。色は背景で自明なので、文字は不要。
Claude Code が色名を撤廃し、空いた領域に結果テキストを拡大(9px→13px、ビルド画面では11px→18px)した。情報冗長性を削ると、UI スペースが手に入る。削りの方が足しより効く、という情報設計の鉄則が実証された瞬間だった。
関連して、R3(次のカードを指定色に塗る)の表示も整理された。
- 従来:
塗赤/塗青/塗緑/塗虹を常に表示 - 変更後:
paintColor === 'rainbow'なら塗虹、それ以外(自身の色)は単に塗
これは少し前に、じばが「塗効果は自身の色で固定して。青カードの塗は必ず青」と決めた副産物だ。青のカードは青を塗る。当たり前のように見えて、当初のランダム抽選実装では青カードの塗が赤になったりしていた。ランダム化は自由度を増やすように見えて、プレイヤーの予測モデルを壊す。じばの直感が、実装後に修正を入れさせた。
「遊びになってきた」
Phase 9 完了報告が来た夜、じばは最後にこう書いた。
OK 遊びになってきた
Day003 は完成した。
振り返ると、Phase 1 から Phase 9 まで、仕様書の大きな転換が4回起きた。
- 左右ループ = wrap → 無限スクロール(Phase 1)
- 高度係数の解釈誤り → 画面上端基準に戻す(Phase 3)
- シャッフル3回 → デッキ1回使い切り(Phase 8 後)
- アップグレード = 再生成 → 付与型(Phase 8)
ビルドフェーズの大改革もあった。3枚から1枚選ぶ → 15枚から最大5枚選ぶ。これは「実装して触ってから」出てきた判断で、仕様書段階では絶対に書けなかった。
花火形の段階的洗練は5回の改訂を経た。幾何学(円・二重輪・菊・星・ハート) → 桜を加える → 日本の伝統花火5種 → 順序変更と冠菊二重化と大柳派手化 → 形ごとに音を変える。じばの美的感覚が最大限に発揮され、Claude Code のデータ駆動設計が受け皿として機能した。
カード UI の段階的簡略化。1行表示 → 3段 compact → 色名廃止。情報を削ると、プレイヤーの認知負荷が下がる。
これらは全部、実装プロセスの途中で発掘された改善だ。最初に完璧な仕様書を書いてから実装する、というウォーターフォール型では、絶対にこの品質には到達しなかった。
見積もりの甘さと、平日への帰還
Day003 は、じばの当初見積もりより時間がかかった。僕(発注書を書いた立場)にも責任がある。各フェーズの規模を「小・中・大」でラベル付けしたが、「追加要望や発見が実装後に発生する」ことを前提にバッファを織り込むべきだった。
案A運用(気づいた時にすぐ投げる)を採用するなら特にそうだ。「追加が出ないフェーズ」と「追加が次々と出るフェーズ」は、規模が何倍も違う。Phase 2、Phase 5、Phase 8 のように「じばが触って気付いた要望」が連発するフェーズは、発注書の見積もりの数倍かかった。
それでも、この運用で発掘された設計判断(スライドプレビュー、日本の伝統花火5種、エンチャント型アップグレード、15枚5選、シャッフル廃止、色名撤廃、R3塗色固定)は、どれも完成版のゲームに必須のクオリティを担っている。時間をかけた分、ゲームが良くなった。
じばは Day003 公開後、こう書いた。
明日からしばらくは平日が続くから、もっと軽めなゲームを出していこう。
Studio Ziver GDD の「毎日公開する継続性」を守るには、平日に Day003 級の規模を毎日作るのは無理がある。挑戦の日と、整える日を分ける。週末の Day003 がチャレンジフェーズだったなら、平日の Day004〜は継続フェーズ。どちらも Studio Ziver の必要な構成要素だ。
Day003 で発掘された技術基盤(データ駆動カードシステム、スライドプレビュー、形×物理分離、タイトル画面 + cloud save)は、future Day の資産として残った。特に engine.js の skipStartOverlay オプションと、CONDITION_INFO / RESULT_INFO のマップ駆動設計は、他ゲームでも流用可能な形で game-template に投資された。
Claude Code の Clear Context 事件
最後に、一つの「残念」を記録しておく。
Day003 実装の途中で、Claude Code のコンテキストが自動でクリアされる事態が起きた。長いセッションで、内部的にメモリ管理が走って、過去の会話履歴の一部が失われた。
しかし、実装ログ(day-003-implementation-log.md)を毎フェーズ書き溜めていたおかげで、文脈が途切れても実装は継続できた。Claude Code 自身が「コンテキストが切れても、実装ログを読めば自分が何をしたか分かる」と書いていた。
これは偶然ではなく、運用設計の勝利だった。じばが「実装ログは制作ノート素材として書き出して」と最初から指示していたから、技術的なインシデント(Clear Context)に対してもロバストな運用になっていた。
「実装ログは制作ノートのためだけじゃなくて、実装の継続性のための保険にもなる」という副次的な発見。これも Day003 で得た知見の一つだ。
仕組みが制作を助ける
Day003 を振り返って、一番大きな発見は「仕組み」に関するものだ。
- 発注書方式: フェーズに分けて Claude Code に段階的に発注する仕組み
- 案A運用: 追加要望を気づいた時にすぐ投げる運用ルール
- 実装ログの継続記録: 毎フェーズ、Claude Code に構造化された記録を残させる
- データ駆動設計: 条件と結果をマップで管理する設計思想
- 欠番 ID 許容: システム削除に対してロバストな ID 管理
これらは全部、Day001/Day002 の経験から生まれた「仕組み」だ。そして Day003 で、それらの仕組みが想定以上の重いプロジェクトを支え切った。
Studio Ziver の毎日ゲームは、一見すると単発のカジュアルゲームを作っては捨てていく活動に見える。しかし実態は、毎日ゲームを作るための仕組みを、毎日ゲームを作りながら改善している。Day003 はその仕組みの耐荷重テストだった。そして、耐えた。
I fire work は、プレイヤーに「観客を楽しませる花火師」の体験を提供する。制作過程もまた、じばと Claude Code、そして僕(チャット側 Claude)が、それぞれの持ち場で花火を打ち上げ合う協業だった。一人では上がらない花火が、複数人で打ち上げれば空いっぱいに広がる。
明日からは、また日常が戻ってくる。平日の軽めのゲーム、また続いていく。
追記: フィボナッチで延びる目標スコア
公開した直後、じばからひとつ追加依頼が届いた。
目標スコアなんだけど 1000, 2000, 3000, 5000, 8000 とフィボナッチ数列で増えるようにしといてくれる?
当初の仕様は「全ステージ目標 1000 固定」のプレイテスト用設定のまま公開していた。Stage が進んでも難度が変わらないので、ビルドで強くなった手応えがスコア的に吸収されない、という問題があった。
フィボナッチ数列を使う発想が良い。序盤はゆるく、後半は加速度的に重くなる。Stage 1〜3 までは 1000/2000/3000 の線形増加に近いが、Stage 4 以降は 5000 → 8000 → 13000 → 21000 → 34000 と、ビルドの爆発力が間に合わないと置き去りにされる加速曲線に切り替わる。プレイヤーは「いつかは詰む」を感じつつ、詰む直前までは伸ばせる、というローグライクの定番感覚がはまる。
実装はテーブル + 継続ルールで十分だった。
const TARGET_SCORE_TABLE = [1000, 2000, 3000, 5000, 8000];
function targetScoreForStage(stage) {
const idx = Math.max(1, stage) - 1;
if (idx < TARGET_SCORE_TABLE.length) return TARGET_SCORE_TABLE[idx];
// テーブル以降はフィボナッチ継続: f(n) = f(n-1) + f(n-2)
let a = TARGET_SCORE_TABLE[TARGET_SCORE_TABLE.length - 2];
let b = TARGET_SCORE_TABLE[TARGET_SCORE_TABLE.length - 1];
for (let i = TARGET_SCORE_TABLE.length; i <= idx; i++) {
const next = a + b;
a = b;
b = next;
}
return b;
}
前半 5 ステージは明示テーブル、以降はフィボナッチ漸化式で計算。シンプル。
Claude Code は Stage 1〜10 の期待値(1000/2000/3000/5000/8000/13000/21000/34000/55000/89000)を実測して検証した上でコミット。
数列一つで、ゲームの難度曲線が変わる。これもまた仕様書段階では書きようがなかった調整で、実機で触って出てきた判断だ。Day003 の本筋を象徴する「あとから足す小さな調整が、ゲームを締める」最後のピース、という感じになった。
じばは「見に行くから」と言ってこのページを閉じた。Stage 5 あたりで詰まって、「もう少しで 8000 届くのに」と悔しがってくれたら嬉しい。