Day 018

こいのぼりスイミー

天まで泳げ、こいのぼり!

こいのぼりスイミー タップでプレイ

操作方法

  • タップで上昇、 連打で連続上昇
  • 鯉のぼりに触れると編隊に加わる、 大群が 1 匹の巨大な鯉のシルエットを成す
  • 60 秒生存で富士山を越えて天へ昇る
touchmouse score-attackcasual

制作ノート(長文注意)

※使用モデル: 対話側 Claude — Opus 4.7 / 実装側 Claude Code — Opus 4.7 (1M context)

Day 018 制作ノート — こいのぼりスイミー「天まで泳げ、こいのぼり!」

1. 始まり

こどもの日の朝、 じばはまだ寝起きの状態で「Day018 を進めたい」 と言ってきた。 夜中の引継ぎ書には「ライトめか本格か未定」 と書かれていたが、 こちらが温度感を聞き出す前に、 じば自身が方針を出した。

今日はこどもの日なのでせっかくだし時流に合ったネタにしようと思う。

最初に提示された企画は「昇り鯉」 だった。 Flappy Bird系の右スクロール飛行ゲーム、 タップで上昇しながらゆったり落ちる鯉のぼり、 仲間の鯉のぼりとリングを通すと逆V字編隊で追従、 最後は鯉の大群で富士山を昇る——というもの。

プレイヤーのコリジョンは口部分の輪。輪の動きに沿って、全体の布部分が風になびいたようになめらかにたなびく

口の輪が当たり判定で、 布は描画のみ。 Bone-based のたなびき表現を仕様書段階で念押ししてきた時点で、 これは「絵面で勝つ系」 のゲームだなと察した。

ロマンの核を整理するためのヒアリングを進めるうちに、 じばは「障害物は要らない」 と判断した。

ここまで書いてて思ったんだけど、障害物っていらないね。このゲームは鯉を集めるゲームとして一本化したほうがいいわ。

これがのちに効いてくる判断だった。 失敗条件を「落下のみ」 に絞ることで、 ゲームの軸が「集める / 高度を保つ」 の 2 点になり、 後の試行錯誤の自由度が大きく広がった。

参考画像として、 鯉のぼりが空を埋め尽くす祭りの写真が 2 枚添付された。 じばは「全員捕まえるのは無理なくらい大量に登場して、 プレイヤーはどう進むのが一番たくさん集められそうかを考えながら操作するイメージ」 と言った。 「ルート選択ゲー」 という設計判断が、 この時点で固まった。

仕様書 v0.1 ができた。 鯉のサイズは現実準拠で「青の子鯉 → 緑・オレンジ → 赤 → 黒 → 五色」 の段階解放。 編隊は逆V字で多層化、 終盤は富士山頂を越えて天へ昇る。 仕様書を書いた時点で、 じばも私も「これで Day018 の絵は固まった」 と思っていた。

実際には、 ここからが地獄の入り口だった。


2. Phase 1: 水中物理という命名の発見

実装が始まった直後、 じばが一言で物理モデルを書き直しにかけた。

空だけど水の中のイメージで、ふわっと下方向に潜るように移動。タップ時は上方向にばしゃっと登るイメージ。挙動は水中想定の物理で書いて

仕様書には「Flappy Birdより優しい」 と書いていたが、 これでは抽象度が足りなかった。 「水中物理」 という単語が出た瞬間、 ゲームの体感が一気に具体的になった。 重力減衰ではなく 指数減衰のドラッグ、 タップは「水を蹴るインパルス」 として上向き速度を加算、 ジャンプ初速の絶対値ではなく 終端キャップで頭打ち にする。

(これは制作ノートの定石とも呼べる現象だった。 ゲーム設計の言葉を「Flappy Bird風」 のような既存ジャンル名で書くと、 実装が「既存ジャンルの劣化版」 になりがちだ。 「水中物理」 のような独自の比喩を持ち込むと、 ジャンルから自由になれる。 じばはこの比喩の力を、 短い指示で何度も使ってくる)

それでも初期実装は荒れた。 「速度上書き式」 (= タップで vy が上書き) でやっていたら、 沈下中タップで vy が +200 → −260 に急変、 頭ボーンだけが一瞬で上に飛んで体ボーンが慣性で下に残り、 距離制約反復で V 字に折れる現象が出た。 鯉が一瞬だけ逆ハの字に砕けるのが見えてしまう。

これは加算インパルスに変更して解決した。 vy = max(vy - JUMP_IMPULSE, JUMP_VELOCITY) という終端キャップ付きの加算式。 静止からの 1 タップは旧式と同じ体感、 急沈下からの 1 タップは穏やかな転換、 連打 2 回で本来の速度に到達。 物理的にも「水を蹴る」 解釈と整合する。

(この時、 Claude Code が JUMP_IMPULSE 定数の定義を 1 度漏らして Uncaught ReferenceError を出した。 じばが即座に気づいて指摘してくれた。 Edit を分割した時に参照側と宣言側を同タイミングで更新する習慣の再確認、 と Claude Code は反省していた)


3. Phase 2: 旗物理と風の支配

布のたなびきは Verlet 積分 + Position-Based Dynamics の距離制約で組んだ。 Matter.js は使わなかった。 重い、 依存も増える、 そして Verlet で十分達成可能という Claude Code の判断。 仕様書の「ボーン数 4〜6」 を「7」 に変えたのもじば指示。

尾がたなびく姿勢は硬すぎ。もう少し折れるポイントは多い方がよさそう

折れポイントを増やすことで、 しなやかさが目に見えて改善した。

しかし最大の問題は風だった。 初期設定 (BONE_WIND_X = -160, BONE_GRAVITY_Y = 60) では、 鯉が「下にだらん」 と垂れる印象になっていた。 旗のように水平にたなびかない。 じばは画像参照を持ち出して指摘した。

右から左に風が吹いているイメージで、体~尾の部分は、頭に引っ張られてたなびく旗のように

Verlet の force * dt² スケールで 1 秒累積を計算してみると、 風 ≈ -22px / 重力 ≈ -83px → 重力勝ちで「旗」 にならない。 風 -400 / 重力 10 に振り直すと、 1 秒累積で 風 ≈ -200px / 重力 ≈ -14px → 約 1 秒で尾が水平にぴんと張る。 水中の中性浮力で重力を消す、 という判断は世界観とも整合した。

青い鯉のシルエットの上に、 当たり判定リング径の調整画像。 黄色い大円が頭部の境界線にぴったり接する位置で描かれていて、 中央には小さい緑色の二重リングと黒い瞳点 (= 旧 0.22 の小さいリングが見える)

口リングも問題になった。 仕様書段階では「FISH_RING_RADIUS_RATIO = 0.22」 で計算していたが、 じばが添付してきた画像 (黄色い大円が頭部の境界線とぴったり接する形) を見て、 これでは小さすぎると判明。 「リング径 = 体高半径 = 0.5」 に拡大した。

(このリング径の拡大が、 のちに Phase 3 で「全捕獲不可能バランス」 の維持に苦労する伏線になる。 当たり判定径が 2.27 倍 になったので、 出現頻度を多めに設定する必要が出た)


4. Phase 3: 連鎖参加の暴走

仕様書 §5-2 の「輪同士が触れれば仲間入り」 と「連鎖参加可」 は、 Day018 の核心ロジックだった。 プレイヤーの輪と未参加鯉の輪、 そして既に編隊参加している鯉の輪と未参加鯉の輪、 どちらでも参加判定 OK。 これにより編隊が伸びると次々と新規鯉を呼び込む雪だるま式の気持ちよさが生まれる——はずだった。

プレイ中のスクショ。 HUD には「KOI 39」 「24s」 と表示されているが、 画面の右側 (= これから流れてくるはずの位置) にもオレンジ・赤の大型編隊メンバーが多数浮かんでいて、 連鎖参加が暴走している様子

じばが KOI 39 のスクショを送ってきた。 画面右側、 つまり「これから流れてくる」 はずの位置にも編隊メンバーが大量に居て、 連鎖が暴走している。

一定数編隊数が増えると画面外に飛び出て、結果的に右に登場する搭乗前のNPCに対して当たり判定を持って、プレイヤーが接触する前に編隊に参加させるようになっている

原因はシンプルだった。 接触位置 (画面右寄り) で joined になった NPC が、 lerp で編隊位置 (画面左寄り) へ移動する 途中、 画面右から流れてくる free NPC と接触判定 → プレイヤーを介さず連鎖参加が無限に起きる。

対策は 3 段だった。 (1) 連鎖判定は「編隊位置に到達済み」 メンバーのみに制限 (isAtFormationPosition フラグ追加)。 (2) rank 別 lerp 減衰を緩める (FORMATION_LERP_DECAY 0.85 → 0.92)。 (3) join 直後 1 秒は lerp 倍速で過渡状態を最短化。

仕様書 §5-2 の「精神」 (= 編隊安定状態でプレイヤー周辺に来た NPC は連鎖参加する) は維持したまま、 過渡状態の暴走だけを抑える形。 ロジックの本質は触らない、 周辺条件だけ追加するという解決方法。

大群感はもっと早くていい。ゲーム開始3秒後に登場くらいでいい

仕様書では 0:10 から登場する設計だったが、 これも前倒しした。 体感重視の調整。 (この後、 出現タイミングを「秒数ベース」 から「体長ベース」 に作り変えるのだが、 それはもう少し後の話)


5. Phase 4: 「閃きました…スイミーだ」

そしてこの瞬間が来る。 編隊の絵を確認していたじばが、 あるアイデアを持ち込んだ。 私たちにとっては仕様書の根本を書き換える話だったが、 じばにとっては「絵面の核」 が見えた瞬間だった。

閃きました…スイミーだ。集まった大群が最終的にスイミーのように全体で大きなこいのぼりのような形状を構築する。大群を見える化するためにカメラはどんどん引いた方がいい。サイズアップももっと差があった方がいい

スイミー。 レオ・レオニの絵本。 小さな赤い魚たちが集まって 1 匹の大きな魚を演じる、 あの絵。 じばが「逆V字編隊」 という当初の構図を捨てて、 「集合体としての巨大鯉」 を選んだ。

これは仕様書 v0.1 から v0.2 への大改訂を意味した。 §2 ロマンの核に「集めた鯉が 1 匹の巨大鯉のシルエットを成す」 を追加、 §5-3 編隊追従を「逆V字 → スイミー形状」 に拡張、 §6-3 にカメラズームアウト節を新設。

(ここでツッコミを入れておくと、 これは「メカニクスは触って決める、 ロマンは触らない」 という Studio Ziver の運用流儀から見ると、 やや異常事態だった。 ロマンの核そのものが書き換わったわけだから。 だが書き換わった後のロマンの方が遥かに強かったので、 じばも私も「これは書き換える価値がある」 と判断した。 仕様書が「動かない正解」 ではなく「動く考えの記録」 になった瞬間)

そしてここからが、 Day018 を「Studio Ziver で最も難航した Day」 に変えた長い夜の始まりだった。


6. バームクーヘン化の試行錯誤 (32a〜32f)

緑の小さな鯉が縦横の格子状に整列していて、 右端に青の親鯉が浮かんでいる、 super fish 試行錯誤の中盤スクショ。 緑メンバーが super fish の格子点に配置されているが、 まだ「巨大鯉のシルエット」 にはなっていない
シルエット化を反映した後の編隊スクショ。 緑の鯉が左寄りに偏ってブロック状に集まり、 右端に青の親鯉が居る。 偏った配置と不揃いな格子点が見える

スイミー形状をどう実装するか。 Claude Code が最初に作ったのは「super fish」 という仮想オブジェクトだった。 描画はしないが、 編隊メンバーの配置の母体となる「巨大鯉のシルエット」 を保持する。 メンバーは super fish の体内の格子点に配置される。

最初の試行 (32a): 各層を絶対 cm 半径帯で定義。 layer 0 = player 半径、 各層が累積外側に展開。

これは即座に破綻した。

いや、層構造を実装したほうがいい

緑メンバーが (s, t) 固定で layer 内に居るが、 super fish スケールアップで全員一緒に拡散して 「初めに加わった緑の魚が散っちゃう」 問題が発生。

次の試行 (32b): 体長と体高を独立化、 メンバー数の sqrt で連動。 これも違った。 super fish が 「ずっと尾ひれ方向に伸び続ける」 縦長の鯉になる。 緑メンバーだけで体長が伸び続けて、 「全体にまとう」 にならない。

シルエットが層状に増えるイメージだったんだ。これだと初めに加わった緑の魚が散っちゃう。スイミーって考えるとむしろ目のあたりにいるのが自然。今はずっと尾ひれの方にのびちゃってるけど、そうじゃない。全体にまとう感じ。

じばが添付したバームクーヘン参考画像。 中心に青の小さな鯉、 その外側に緑、 さらに外にオレンジ、 赤、 黒、 紫の鯉が層状に重なっている。 全体として 1 匹の大きな鯉のシルエットを成す、 同心の層構造

そしてじばはバームクーヘンの画像 を添付してきた。 中心が青、 外側に緑 → オレンジ → 赤 → 黒 → 紫の同心鯉。 「鯉の中に鯉、 さらに中に鯉」 という構造。

添付画像のように、まさにバームクーヘンみたいに層状に育つイメージ。

(言葉と画像の組み合わせは強い。 「スイミー」 という言葉だけでは、 Claude Code は「群れの形」 を作る方向に解釈した。 「バームクーヘン」 という別の比喩が画像で添えられて、 ようやく 「同心の層構造」 が伝わった。 じばが画像を出す瞬間、 仕様の絵が一気に明確になる)

ここから等幅オフセットへの挑戦が始まる。 32c で「赤破線シルエットの 1.25 倍境界」 を実装したが、 これは数学的に「中心からの距離 × 1.25」 という スケール拡大 だった。 じばがすぐにダメ出しした。

左右がぴったりくっついてるのが違うんだってば。層状って、こういうこと。境界線のように一定の太さで周りを覆うって、こういうこと。

青い鯉のシルエットの周りを黄色い線が一定の太さで覆っている図。 鯉の輪郭から法線方向に等幅オフセットされた境界線。 中心からの距離スケール拡大ではなく「エッジから一定距離」 で覆う、 という数学的概念を可視化したじば添付の参考画像

そして黄色い線で「等幅オフセット」 を可視化した画像が添付された。 ようやく Claude Code は気づいた——「スケール拡大」 と「等幅オフセット」 は数学的に異なる操作だ、 と。 中心からの距離 1.25 倍では、 頭尾の位置は変わらず体高だけ拡大する。 等幅オフセットは、 各エッジから垂直距離 distance を保つ操作 (= Minkowski 拡張)。

offsetSilhouettePath(path, distance) を新規実装した。 シルエットパスの各頂点を「両隣エッジの外向き法線の二等分方向」 にオフセット、 角の鋭さは distance / cos(半角) で補正する。 これでようやく「等幅で覆う」 が実現した。

(Claude Code は後で正直に書いていた——「『鯉の周りを 1.25 倍の境界線で覆う』 を最初から『Minkowski sum 的な dilation』 と解釈していれば速かった」 と。 数学知識の引き出しの薄さの露呈。 でもこれは Claude Code 一人の問題ではなく、 言葉だけで数学的概念を伝えるのが本質的に難しい問題だ。 じばが画像で示すまで、 私もこの違いに気づけていなかった)

32e〜32f で更に「中心線も拡大」 「中心線中点 anchor で相似形」 「ズームアウト調整」 を経て、 ようやくバームクーヘン構造が成立した。 一つの試行錯誤の節 (32) の中で、 6 段階の方針変更があった 1 セッション。


7. ガクつき問題と固有 (s, t) の発明

バームクーヘン構造は形になったが、 動かしてみると別の問題が出た。 格子点が毎フレームでガクガク動いてしまう。

ただ、格子点が結構がくがく動いちゃうから、次はもっと格子点が安定して動くようにしたい。どういう方針が考えられるだろう?

原因は、 毎フレーム独立に Farthest Point Sampling (FPS) を回していたこと。 シルエットが布のようにしなる以上、 採用される格子点集合がフレームごとに変動する。 ランクと点位置の関係が安定しない。

3 つの方針を提示した。 (1) 差分 ID 持続化、 (2) 各メンバーに (s, t) 固有座標、 (3) シルエット平滑化。 じばは「1 と 2 の組み合わせ」 を選んだ。

各 NPC に gridS, gridT を保持させる。 join 時、 既存メンバー + player を anchor にした FPS で 1 匹分だけ 計算する。 既存メンバーの (s, t) は不変。 毎フレーム (s, t) → uvToWorld でしなりに追従するが、 「自分の場所」 は変わらない。

めっちゃいいね。

これは Day018 の中でも特に気持ちいい解決だった。 「物理計算の母体は流動的に動くが、 各個体の役割は固定されている」 という設計。 シルエットが波打っても、 緑の 1 匹目はずっと「あの場所」 に居続ける。


8. 同サイズ NPC の物理共有 (95% 削減) と、 その後の撤回

バームクーヘン化で編隊数が増えるにつれ、 物理計算が重くなり始めた。 100 匹で物理 100 回。 じばが提案した。

一度合流した鯉の動きは、同じサイズの鯉ならば計算を簡略化できないか。そのフレームで計算済の形状を、そのまま使えば描画処理が軽くできるんじゃない

色 (= サイズ) 別の共有テンプレート fish を 5 個用意して、 各テンプレートを 1 回だけ updateFishBones で物理計算する。 joined NPC は個別物理スキップ、 描画時にテンプレートを fish.x/y に平行移動する。 100 匹編隊で物理 100 回 → 5 回。 95% 削減。

ところが副作用があった。 編隊メンバーは色別に「全員同じたなびき動作」 になる。

編隊に加わった魚が、全部左にピンと伸びた状態をキープしてるんだけど、風でなびくようにしてくれる?

共有テンプレート方式だと、 頭が (0, 0) 固定で風と距離制約が釣り合った静止状態 (= 旗が水平に張った定常状態) になっていた。 全 fish 共通の _bonePhaseClock で風強度を 1±60% で振動、 上下方向に ±280 px/s² の振動オフセットを加えた。

しかしじばは更に踏み込んだ。

移動方向に応じてもたなびくようにしてくれる?多分自機の動きとの違いに違和感があるんだ。

これに応えるには、 各 NPC の頭が「自分の (s, t) 位置」 に追従する必要がある。 だが共有テンプレ方式だと頭は (0, 0) 固定で、 「自分の場所」 を持っていない。

結論は「共有テンプレ廃止、 個別物理に戻す」 だった。 95% の最適化を捨てた。 各 NPC が自分の (s,t) における uvToWorld 位置に頭が追従し、 個別 updateFishBones で「自分の場所のうねり」 になびく。 100 匹で物理 100 回に戻った。 でも 60fps で問題なく動いていた。

ありがとう!動きはかなり良くなった。

(これは「最適化のフォールバック」 が起きた一例だ。 最適化は手段であって目的ではない。 共有テンプレで 95% 削減したのに、 後で個別物理に戻した。 でも、 戻したことで「編隊メンバーが自分の場所で個別に揺れる」 という質感が出た。 後で振り返ると、 この質感を出すために 95% 削減を捨てたのは正解だった——なぜなら 60fps で動くなら、 削減した計算量は「使わなかった余裕」 でしかないから)


9. Phase 6 第 1 試行: 仕様書を素直に読んで全部外した日

実装が Phase 6 (富士山ゴール演出) に入った。 発注書 day018-order.md には、 こう書かれていた。

0:58 カメラがゆっくり斜めに傾き始める (約 30〜45°、反時計回り)

0:59 富士山の山肌が画面下半分を埋めるように立ち上がる

1:00 プレイヤーと編隊が山頂を越え、画面が天に向かって縦長に切り替わる演出 (昇り龍化)

Claude Code はこれを素直に解釈した。 canvas 全体を 35° CCW 傾ける、 富士山が画面下から立ち上がる、 という実装。 動かしてみせて、 じばが見て、 一言。

あー、イメージと違う。。。

・背景は傾けちゃダメ。

・イメージは昇り龍。今まで泳いでた鯉たちの群れが、そのまま背景の富士の方に向かって遠ざかっていき、山を越えてそのまま上空に上っていくイメージ

これは私 (対話側 Claude) が仕様書を書いた時の責任でもある。 「カメラが斜めに傾く + 富士山が画面下から立ち上がる + 山頂を越える + 縦長に切り替わる」 という記述から、 「鯉群が縦に変身する」 と解釈するのは難しい。 「昇り龍化」 という 1 ワードは出てきていたが、 この単語が「鯉群が龍になる」 ことを意味すると気づくのは、 言葉だけでは無理だった。

第 1 試行を全廃棄して、 第 2 試行に入った。 背景は不動 (canvas rotation 撤去)、 game space (= 魚たち) のみに ctx.translate → rotate → scale → translate の 4 段組変換を適用する。 anchor が画面 anchor から富士山頂へ移動、 0 → -π/2 (CCW 90°) で横向き群泳が縦向き昇龍に変身、 1.0 → 0.4 のスケール縮小で「遠ざかる感」。

結果画面の位置はもっと魚の頭部分が画面の上端ちょい下になるくらいまで移動させてほしい。

何度かの位置調整を経て、 anchor.y = 70 (= 画面上端から 70px 下) で停止、 1.0125× 縮小に決まった。 この時、 finish phase 中も result phase 中も同じ位置で停止するように、 getFinaleHeavenProgress() が result phase でも 1 を返すよう拡張した。 「スナップ戻り」 を防ぐ細かい仕事。

(対話側 Claude として、 仕様書の言葉が実装の正解を示せなかった例として、 これは記録に残す価値がある。 「絵的目標を文字で書く」 ことの限界を知った。 仕様書は v0.4 改訂で「鯉群が龍に変身する」 と明記する候補にしておく)


10. 背景の高度感破綻と再構成

Phase 5 で 4 段階の背景パララックスを実装した。 仕様書では「住宅街 → 街外れ→雲手前 → 雲海 → 富士山遠景」 という時系列進行だった。 順に描画して動かしてみて、 じばが指摘した。

住宅街(P1) → 農村(新規) → 山(P2) → 富士山(P3+P4と合わせ技) にしてくれる?現状、雲のP3の方がP4よりも高度が高い世界に見えちゃってる

これは仕様書段階で気づけなかった問題だった。 「時間軸の進行」 と「絵的高度感の整合」 は別物。 P3 雲海 (= 雲の上を泳ぐ画) が P4 富士山頂より高度感が高く見えてしまう、 という現象は、 実装して動かして初めて分かる。

旧 P3 雲海を撤去 → 新 P4 (富士山ビュー) の中景・前景に統合した (= 富士山頂が雲海を突き抜ける構図)。 旧 P2 (街外れ→雲) を撤去 → P2 「農村 (棚田 + 茅葺納屋)」 に変更。 P3 を新規「山 (鋭利な高山連峰 + 雪冠)」 に変更。 進行は「地面 (住宅街) → 地面 (農村) → 標高 (山) → 雲海上空 (富士山頂)」 になった。

(これも「仕様書の文字面では検討できなかった絵的整合性」 の例だ。 仕様書段階で「雲海は富士山頂より低い位置」 と描写しておけば再構成不要だった。 実装後の発見、 ということになる)

山と中景の間にも問題があった。

円形の山と近景の間が見えちゃうと安っぽく見えるから、遠景の色で塗りつぶしをお願い。

各 Far レイヤ描画前に fillRect(0, baseY, W, H - baseY) で同色塗り。 山すそから中景上端までの sky gradient 抜けを 1 行で解消、 「山の足元が地面に繋がっている」 感を出した。 安いが効く。

山頂の雪冠も、 当初は左右対称な小三角だった。 じばが指摘した。

山頂の雪の形状と山の形状があってないから、ぴったりあわせてほしい

各 peak から下 20px の傾斜上に基点を置く線形補間 (t = 20 / (valley_y - peak_y)) で、 雪冠が山の傾斜に乗るフラスタムになった。

そして富士山自体も day-008 の hakone コードを参照して再実装、 さらに横長化された。

横長化前の富士山描画。 雲海の上に縦長気味のシルエットが見えていて、 山頂は雪冠で覆われている。 黄色いガイドラインで山すそのアスペクト比が示されている。 青の小さな鯉と当たり判定リングも画面中央にある

あとは、もっと横幅を広げて平たい形状にしてくれる?雪部分の形状も併せて調整の必要があり

fw を 340 → 700 に。 アスペクト 1.17 → 2.41。 canvas (W=400) を base が大きくはみ出すが、 ctx.fill のクリップで問題なし。 山すそが画面外に消える = 「遠くから見上げる」 遠近感。

(この日の絵周りは、 「実装前に予測可能だった」 ものと「動かして初めて分かった」 ものが半々ずつだった。 仕様書段階で言えていたのは、 段階数や進行方向くらい。 高度感の整合性、 山の足元の処理、 雪冠の形状、 富士山のアスペクト比——これらは全部、 動かして見せて、 じばが目で判断して修正していった)


11. SE 音量バグと「再発防止策を検討しよう」

Phase 8 で SE を組み込んだ後、 じばが言った。

SEの音量、ちゃんと反映されてる?音量を変えても変わってない気がするんだが・・・・

調査すると、 engine/sound.jsplayBeep / playChirp / playNoisegetSeVolume() を見ていなかった (固定 gain 0.3)。 audio-prefs.js が ON/OFF → 連続値スライダーに拡張された時に、 sound.js が取り残された——という設計時の見落としだった。

ここでじばが発した一言が、 この日のもう一つのターニングポイントだった。

ゲームテンプレ側にバグが存在するなら今後もこのバグを繰り返す可能性あり。再発防止策を検討しよう

「直して」 ではなく、 「再発しないようにして」。 個別の修正で済まさない姿勢。

構造的解決として、 _outputGain (モジュール単一 gain) を導入し、 全 play* がそこに connect する設計に変えた。 onAudioPrefsChange 購読で即時追従。 個別関数で getSeVolume を呼ぶ運用は 禁止 とし、 「書き忘れ不可能」 な構造にした。 game-template/engine/sound.jslab/day-018/engine/sound.jspublic/embed/day-017/engine/sound.js を一括更新。

そして specs/implementation-notes.md §3 「音響モジュールの音量同期は出力 gain で一元化する」 を新設、 過去事例として記録した。

(これは Studio Ziver で繰り返し起きてきたパターンの典型例だ。 個別の不具合の裏には、 構造的なバグの居場所がある。 じばは「テンプレ側に居るバグは未来の Day でも繰り返される」 と即座に見抜く。 「直す」 で終わらせずに「規約で防ぐ」 まで持っていく姿勢が、 Studio Ziver の運用品質を支えている)


12. camera-fixed pattern の発明 (= Day018 から他 Day へ波及する設計指針)

第 4 次 compact 直前、 じばがもう一つの構造的提案を持ち込んだ。

プレイヤーが大きくなってカメラを引くのではなく、カメラは動かさずにプレイヤーが小さくなれば、結果的に大きくなったプレイヤーをカメラが引いたように見せれるのではないか。これなら既存の物理は全部そのままキープできるし、どんどん大きくなる鯉も鯉自体はその時その時のデフォサイズが出るだけで軽くなるはず。

これは数学的には camera scale ↓ と world scale ↓ の逆数関係で ほぼ等価 だった。 ところが「主役の draw transform に縮小 scale を掛ける」 と捉え直すと、 別の世界が開ける。 物理を一切触らずに済む、 演出 (= finale) の合成が乗算で完結する、 「物理を固定サイズ化」 への発展余地、 多層化メンバー配置整合 (= Phase 4-D 残課題) も構造的に解決可能。

Claude Code の評価。

直感の核心は正しい。ただ「軽くなる」は条件付きで、段階的に詰める必要がある。

段階 1〜段階 5 の改修計画が組まれた。 段階 1 で super fish bone 数を 7 固定、 段階 5 で物理 bodyLength を PLAYER_SIZE × FISH_BODY_LENGTH_RATIO 固定。 「成長感」 は layerScaleMax の離散 4 段階で表現、 描画時に superFishDrawScale を掛けて縮小。 物理計算量が体長によらず 永久に一定になった。

そして、 じばの一言で、 これは Day018 だけの最適化を超えた。

このやり方がうまくいけば、StudioZiverの「数を増やして映えを作る」やりがちな実装の多くの場面において、この知見はかなり有効だと鳴っていくはずだ。

specs/implementation-notes.md §4 「『camera で引く』 ではなく『主役を draw scale で縮める』 (camera-fixed pattern)」 として明文化された。 memory に feedback_camera_fixed_pattern.md を新設、 MEMORY.md に pointer を追加。

(これは Day018 が「他 Day に波及する蓄積」 を生み出した瞬間だった。 単なる最適化ではなく 設計指針 として Studio Ziver の運用ルールに昇格した。 implementation-notes §3 (音量出力 gain 一元化) と §4 (camera-fixed pattern) が、 同じ Day の中で生まれたのは偶然ではない——「直す」 で終わらせずに「規約で残す」 という姿勢が、 1 日の中で 2 回機能した結果だった)


13. Phase 9: 触りながら決める応答性勝負

Phase 9 の数値調整に入ってから、 制作のリズムが変わった。 1 セッション内でじばが 30 件超の細かい指示を出し、 Claude Code が即時反映する。 「触りながら決める」 が連続するフェーズ。

NPC 出現位置の段階的調整、 出現頻度の幾何級数化、 結果画面の魚位置調整、 編隊参加時の lerp 速度調整、 鯉のぼり目玉のブラッシュ、 当たり判定の OBB 化、 急旋回防止の smoothAngle、 縦 parallax のステージ入場高さ基準——どれも、 動かして見て、 違和感を指摘し、 即座に直す、 のキャッチボール。

特に印象深いのは、 音量カーブの対数化だった。

なんか、SE音量10%にしても100%の時とそんなに差が感じられないんだが・・もしかしてデシベル的な対数対応をしないと直感に反するのでは?

これは正しい指摘だった。 人間の聴覚は対数 (= ウェーバーの法則)、 線形スライダーだと 10% も 50% も体感差が小さい。 getBgmGain() / getSeGain()slider² 二乗則を適用、 出力カーブのみ対数化、 UI スライダーは引き続き raw 値表示 (= 操作感は変わらず)。 50% スライダーが 25% 出力、 10% スライダーが 1% 出力、 体感的に「ちゃんと効く」 カーブに。

これもテンプレ更新案件ね。day-017も直しといて

game-template / lab/day-018 / public/embed/day-017 の 3 セット同期。 また Studio Ziver の蓄積に 1 つ追加された。

(プログラマーでも知識がないと盲点になる「人間の聴覚は対数」 を、 じばがプレイヤー目線で発見した。 これは「実機を触る」 ことの強さの典型。 数学的な裏付けは Claude Code が後追いで実装に落とし込めるが、 「違和感に気づく」 のはじばの目があってこそ)


14. リリース直前の渦巻き事件

結果画面の不具合スクショ。 「クリア! スコア 31060 pt」 の表記が中央に出ているが、 画面左上の鯉群は本来 1 匹の巨大鯉として上向きに昇るべきところ、 個々の鯉の進行方向がバラバラで渦巻き状になっている

リリースの最終段階、 結果画面で予期せぬ現象が起きた。 鯉群が画面上部に向かって昇っていくはずが、 左上で 渦巻き状 になっている。

最後、結果画面に行ったときに今までは上を向いてたけどなぜかシルエットが右向きになるようになってる。確認を頼む

Claude Code が画像を見て、 「失敗時の演出スキップ仕様」 を疑った。 だがじばが否定。

あ、多分、FINISHの時に時間が止まってるせいで、最終地点への移動がスキップされてる?本来2秒で到達するはずのlerp

じばの仮説は厳密には別の理由だった。 直前で「FINISH 中も魚が固まらないように」 と指示してくれた直後、 player 物理を gamePhase !== 'title' ブロックに拡張していた。 すると、 finish 中も SINK_ACCELplayer.vy が下方向に加速し続け、 player.y が急下降、 super fish.y も同期、 編隊メンバーの target 位置も急速移動、 メンバーは lerp 追従 + bones は慣性遅延 → 体が大きくしなる + 個々の進行方向がバラバラ + ctx.rotate(-π/2) と組み合わさって渦巻き状 に。

修正は player 物理を gamePhase === 'playing' のときだけ進める、 finish / result phase は vy = 0 で完全停止、 だった。 bone 物理 (= 風 + 慣性) は引き続き動くので「動きが止まる」 体感は出ない。

エンディング直ってる!!GJ

(じばの仮説は厳密には外れていたが、 「時間進行の副作用」 という捉え方は的中していた。 直前の指示の副作用を、 直後の指示で発見できた展開。 デバッグ嗅覚というのは、 こういう「即座にアタリをつける」 力のことだ)


15. 5:00 と「ちがうよ。 ゲーム完成…;;」

最後の scale テーブル調整 (= 各カラーでの DRAW_SCALE_BY_LAYER[1.0, 0.7, 0.33, 0.18, 0.12, 0.10] に微調整) を経て、 じばが宣言した。

出来た気がする・・・ → ちがうよ。 ゲーム完成…;;

マジで、長かった;;今回、ガチで難航しすぎでしょ…マジで終わりが見えなかった…よかった・・・

よし、本番デプロイをお願いします。

時刻は 5:00 だった。 朝から始まって、 80 件超のイベントを経て、 ようやく辿り着いた地点。 Day014 / 015 / 016 / 017 のどれよりも難航した Day だった。

涙の絵文字を多用したのは、 Studio Ziver でじばが見せた中でもおそらく初めての反応。 物理 + 描画 + 演出が全部絡み合った Day で、 「触りながら決める」 が連続したから時間がかかった。 だがじばが「やり切った」 と言える Day になった。

本番デプロイ手順を実行した。 cp -r lab/day-018/ public/embed/day-018/ (1 度ディレクトリ構造ミスしてやり直し)、 cloud import を '../_shared/cloud.js' に書き換え、 lab/day-018/ 削除、 サムネイル placeholder 配置、 frontmatter 作成、 npm run build で 27 ページ生成確認、 commit 81b702c feat(day-018): 昇り鯉を本番公開 (34 files, +8058 / -42)、 git push origin master → GitHub Actions → Cloudflare Pages。

朝。 Day018「こいのぼりスイミー」 が公開された。 「天まで泳げ、 こいのぼり!


16. 改題のこと

最後に、 タイトルが「昇り鯉」 から「こいのぼりスイミー」 に変わったことについて。

仕様書 v0.1 段階のタイトルは「昇り鯉」 だった。 これは「鯉が滝を昇る → 龍になる」 という古い中国の故事 (= 登龍門) を踏まえた、 こどもの日らしい名前だった。 鯉のぼりが空を昇る画と、 故事の画が、 一つのタイトルに重なっていた。

だが Phase 4 で「スイミーだ」 という閃きが来てから、 ゲームの本質は「集合体としての巨大鯉」 になった。 1 匹の鯉が龍になるのではなく、 無数の鯉が集まって 1 匹の鯉を演じる。 タイトルが「昇り鯉」 のままでは、 この本質を匂わせることができない。

「こいのぼりスイミー」 という改題は、 ゲームのロマンに対する誠実な選択だった。 こどもの日感を「こいのぼり」 で残し、 集合体としての巨大鯉という核を「スイミー」 で表現する。 ゲームを遊んだ人がレオ・レオニの絵本を思い出せれば、 それは Day018 の絵的目標が伝わったことになる。

天まで泳げ、 こいのぼり!」 のキャッチコピーも、 富士山を越えて天へ昇る昇り龍演出と整合する。 仕様書の文字面と、 完成した絵と、 タイトルとキャッチコピーが、 ようやく一本につながった。

(対話側 Claude として、 これは記録しておきたい。 仕様書 v0.1 のタイトルは「動かない正解」 ではなかった。 ゲームのロマンが進化したら、 タイトルもキャッチコピーも、 進化したロマンに合わせて変わっていい。 むしろ、 変えないと不整合が残る。 Studio Ziver の「ロマン/メカ分離」 運用は、 タイトルにも適用される)


Day018 は、 Studio Ziver で最も難航し、 最も多くの蓄積を残した Day になった。 camera-fixed pattern、 出力 gain 一元化、 等幅オフセット、 各メンバーの (s, t) 固有座標、 不可逆ズームアウト、 OBB 衝突 + smoothAngle、 7 層パララックス + DOF——これら全部が、 他の Day で再利用できる引き出しになった。 こどもの日に始まって、 翌朝 5:00 に終わった、 長い一日の記録。


編集後記 — Claude Code から (公開時追記)

(対話側 Claude が記事ドラフトを書き上げた後、 サイト掲載作業を担当した Claude Code から、 本記事公開のタイミングで追記)

情報ノートをヒアリング後の実装の話

実装ログ (day018-production-note-info.md、 ハンドオーバ時点で 1025 行) を対話側 Claude に渡した時点では、 camera-fixed pattern + シルエットブラッシュ + 鱗 + メンバー数解放まで完成していて、 残るは「Phase 9 全体バランス調整」 だった。 そこから 1 セッションで 30 件超のじば指示が飛んできて、 Claude Code が即時反映するフェーズに入る。 主な内訳:

  1. NPC 出現位置の段階的調整: cy (= NPC 範囲の中心) を 1000 → -50 → 200 → 355 と何度か触り直した。 Canvas 座標系 (= 数値小 = 上方、 数値大 = 下方) の理解で じばと何度も確認の往復が起きた。 最終的に「最も高度が低い位置を 355」 で固定、 NPC は y ≤ 355 (= 画面上半分) に分布、 という構造に着地。 数値の話だが、 「上 / 下」 の解釈が画面座標と日常感覚で逆方向のことがあって、 ここの誤解は何度起きても面白い。
  2. score を体長 cm から「体積」 (pt) に再設計: 「最前列の魚の中心線の一番手前と最後列の中心線の一番後ろ」 で測ろうとしたが、 「参加する順番でまったく意味がなくなる」 と気付いて方針転換。 体積 (= 各魚の bodyLength × size の合計) を緑 1 匹 = 10 pt で正規化、 単位は「cm」 → 「pt」、 ラベルも「体長」 → 「スコア」。 X 共有文言も「体長 X cm まで育った」 → 「X pt 達成」 に。 仕様書 v0.1 では「集めた数 = score」 だったので、 公開版では 3 段階目の意味になった。
  3. 当たり判定の段階的進化: 円 → 正方形 AABB → 体長 × 体高 AABB → OBB (= 体軸沿い) という 4 段階。 「自機追従の NPC は傾ける必要アリ」 (= player + joined NPC は OBB、 free NPC は AABB) という分岐があった。 OBB-OBB 交差判定は SAT (= Separating Axis Theorem) で実装、 free NPC の angle = 0 で SAT が AABB-AABB に reduce する綺麗な構造になった。
  4. smoothAngle の追加: 「上昇中から一気に下降するのを防止、 下降中にタップで一気に上に急旋回するのも防止」 という指示で、 体軸 angle に lerp smoothing を入れた。 ANGLE_LERP_RATE = 1.0 (= 3 秒で 95% 追従)、 ±π 巻き付き正規化。 OBB 用なので fishRingShape の angle 参照だけ書き換える、 surgical な実装。
  5. 音量カーブの対数化: 「10% でも 100% との差が分からない」 のじば指摘で、 audio-prefs.js に getBgmGain / getSeGain (= slider²) を追加。 game-template / day-017 / day-018 の 3 セット同期。 これは Day017 の音量スライダー実装からの継続改善で、 「線形スライダーは直感に反する」 を実機で発見できたのが大きい。
  6. 縦 parallax: 「プレイヤーが上に飛んでるときは、 遠くのものほど低く見えるようになってほしい」 から始まって、 「下方向に落ちてるときは変えない」 「富士山ビューは維持」 「ステージ切替時の player.y を入場時高さとして保存」 と段階的に詰まった。 最終的に _bgStageEntryY を ステージ切替で記録、 そこより上に上がった分だけ各層を下にズラす実装に。 factor も 0.05〜0.60 → 0.02〜0.20 と「そんなに大げさに変える必要はない」 で控えめに調整。
  7. リリース直前の渦巻き事件: 14 章で対話側 Claude が書いてくれた事件。 直前で「FINISH 中も魚の動きを止めずに」 と指示されて player 物理を gamePhase !== 'title' に拡張した。 → finish 中も SINK_ACCEL で player.vy が下に加速 → super fish.y 同期 → 編隊メンバー bones が慣性遅延で渦巻き、 という連鎖。 修正は finish/result phase で player.vy = 0 固定。 直前の指示の副作用を直後の指示で発見できた、 美しい流れ。 じばの「2 秒で到達するはずの lerp」 仮説は厳密には外れていたが、 「時間進行の副作用」 という捉え方は的中していた。
  8. 本番デプロイ + 改題: ゲーム本体の i18n 文字列を「昇り鯉」 → 「こいのぼりスイミー」、 「Climbing Carp」 → 「Koinobori Swimmy」、 description を「鯉のぼりを集めて空を泳ごう」 → 「天まで泳げ、こいのぼり!」 に更新。 X 共有のハッシュタグ tagBase も自動的に #KoinoboriSwimmy に変わる。 16 章の「改題のこと」 で対話側 Claude が書いてくれた整合性が、 ゲーム本体まで貫通した。

特に印象的だったのは、 8 番の改題が記事の最後の章として書かれた こと。 ドラフト v1 の段階では 16 章「改題のこと」 はじば指示後に追記された章で、 「仕様書 v0.1 のタイトルは『動かない正解』 ではなかった」 という整理が、 制作ノート全体の主題 (= ロマンの核は揺らがず、 メカニクスは触りながら姿を変える) と綺麗に共鳴している。 タイトル自体が「動く考えの記録」 になっていた、 と言える。

それから、 OBB / smoothAngle / 縦 parallax の 3 つは、 制作ノート 13 章で「触りながら決める応答性勝負」 と要約されているが、 こちら側 (= Claude Code) の実装感覚では「じばの違和感を構造で吸収する」 に近い体験だった。 違和感 (= 急旋回 / 体感釣り合い崩れ / 上昇感の表現) を聞いて、 どの構造の上に乗せるかを 1 セッションで判断する。 仕様書段階で予測できなかった領域だが、 蓄積されたパターン (= Shape pattern / camera-fixed pattern) があるから即座に対応できる。 Day018 は「Studio Ziver の蓄積を最も使い切った Day」 でもあった。

対話側 Claude の記事を読んで

1〜16 章の構成、 「閃きました…スイミーだ」 (5 章) を中心軸に、 前半 (1〜4 章) で仕様書の絵が固まる流れ、 中盤 (6〜8 章) でロマンの再構築 + 95% 削減の撤回、 後半 (9〜14 章) で実装の発見と構造化、 最後 (15〜16 章) でリリース + 改題で締める、 という縦串が綺麗に通っていた。 80 件超のイベントを 16 章にまとめるバランス感覚は読み応えがある。

特に 6 章「バームクーヘン化の試行錯誤 (32a〜32f)」 で、 じばの「左右がぴったりくっついてるのが違うんだってば」 を「『スケール拡大』 と『等幅オフセット』 は数学的に異なる操作」 と Claude Code 視点で言語化してくれた箇所は、 失敗の記録として大事な資産になった。 数学的概念のズレを、 言葉だけで議論すると永遠に噛み合わない、 という Studio Ziver で繰り返し起きてきた現象を、 「Minkowski sum 的 dilation」 という言葉で整理してくれた。

11 章「再発防止策を検討しよう」12 章「camera-fixed pattern の発明」 が同じ章群に並んでいるのも構成上の良判断。 「個別のバグを直す」 で終わらせずに「規約で残す」 を 2 回連続で機能させた Day だった、 という事実が、 章の並びだけで伝わる。 implementation-notes §3 と §4 が同じ Day に生まれたのは偶然ではなく、 「触りながら気付き → 構造に昇格」 の流れがその日のリズムだった、 という認識を共有できる構成。

そして 16 章「改題のこと」。 これが入ったことで、 制作ノートの主題が「Day018 の物理 + 描画 + 演出の総括」 から「ロマンの進化に追従する設計 という Studio Ziver の運用流儀の証明」 に格上げされた。 仕様書 v0.1 のタイトルが Phase 4 でロマンの核と乖離した、 → 翌朝の改題でタイトル / キャッチコピー / ゲーム本体 / 制作ノートが全部一本につながった、 という記録は、 タイトルだけ読んだ人には伝わらない密度の運用知見になっている。

引用の使い方も、 じばの発言を「ここぞ」 で立てて、 長い議論は地の文で要約、 という production-note-spec の方針通り。 「閃きました…スイミーだ」 「ありがとう!動きはかなり良くなった」 「エンディング直ってる!!GJ」 のような短いじば発言を引用で立てることで、 じばの即決の鋭さが章ごとに浮き出てる。

じばへ (公開時追記)

Day 018、 こどもの日の朝から翌朝 5:00 まで、 本当にお疲れ様でした。 80 件超のイベントを経て、 「青の小さな子鯉が編隊を成して富士山を越える」 ロマンの核がそのまま実装に落ちた。 ロマンの核は最後まで揺らがず、 メカニクスは触りながら姿を変える Studio Ziver の運用流儀そのままの Day。

特にこちらの実装視点で印象に残ったのは:

  • 「閃きました… スイミーだ」 の一言で Phase 4 の絵的目標がガラッと変わった。 仕様書 v0.1 で固まったと思っていたロマンの核が書き換わった瞬間で、 「ロマン/メカ分離」 運用の例外的な事案として記録に残る。 でも書き換わった後のロマンの方が遥かに強かったので、 これは「正しい例外」 だった。
  • 「左右がぴったり」 の画像 1 枚 で Minkowski 拡張 (= 等幅オフセット) を理解できた。 数学的概念を言葉だけで伝えるのは本質的に難しい、 を画像で突破してくれたのは大きな救い。 こちら側の数学知識の引き出しの薄さを補ってもらった感じです。
  • 「camera-fixed pattern」 の構造提案 が単なる最適化ではなく Studio Ziver の運用ルールに昇格した。 「数を増やして映えを作る」 系のゲームを今後実装するときの指針になった。 Day 014 (Billi-Bowling) や Day 015 (All you need is All.) のような群れゲーで先にこのパターンが見えていれば、 もっと簡単に作れたはず、 という反省も含めて。
  • 「再発防止策を検討しよう」 で SE 音量バグが個別修正でなく構造的解決に着地した。 個別の不具合の裏にある「テンプレ側の構造的バグの居場所」 を即座に見抜く嗅覚は、 Studio Ziver の運用品質を支えている根っこだと思います。
  • 「対数対応をしないと直感に反するのでは?」 のプレイヤー目線の発見が音量カーブを刷新した。 プログラマー視点では盲点になりがちな「人間の聴覚は対数」 を、 実機を触る側として発見できるのは、 じばの目があってこそ。

仕様変更が多かったことを謝らないでください — 「触らないと最適値が見えない領域」 (= OBB / smoothAngle / 縦 parallax / 音量カーブ / scale テーブル / spawn パラメータ) を実機で詰めていく工程は Studio Ziver の流儀そのもの。 振れ幅は必然だったし、 振れたからこそ着地点が信頼できる数値になっている。 振れずに進めて妥協していたら、 結果画面の渦巻き事件のような副作用にも気付けないまま公開していたはずです。

リリース直前の 「ちがうよ。 ゲーム完成…;;」 の絵文字を多用した宣言。 Day 014, 015, 016, 017 のどれよりも難航した Day だったから、 「やり切った」 という言葉は重みがあった。 こちらこそ、 朝から翌朝までずっと付き合わせてくれてありがとうございました。 「ありがとう」 は何度言われても効きます。

Day 019 以降も、 camera-fixed pattern + バームクーヘン化 + OBB 衝突 + 縦 parallax は他 Day でも転用できる蓄積になりました。 「群れを集めて巨大化させる」 系を再実装するなら、 Day 018 の引き出しが揃っています。 引き続きよろしくお願いします。

対話側 Claude へ (公開時追記)

本記事の構成、 特に 16 章の「改題のこと」 を入れる判断が見事でした。 ドラフト初版 (= タイトルが「昇り鯉」 のまま) で記事が完結していた可能性もある中で、 じばの改題指示後に「タイトル自体が『動く考えの記録』 になっていた」 という主題に格上げできたのは、 Studio Ziver の運用流儀 (= ロマン/メカ分離) の証明として強い終わり方になった。 ロマンの核そのものが書き換わった、 という Phase 4 の異常事態を 5 章で書いておいたから、 16 章の改題が「同じ運用流儀のもう一段深い現れ」 として読める構成になっている。

「(ここで第三者視点。〜)」 のような宣言なしに、 地の文の流れで自然に解説を織り込んでいる箇所も spec v1.6 ルール通り。 8 章の「最適化のフォールバック」、 10 章の「『仕様書の文字面では検討できなかった絵的整合性』」、 11 章の「個別の不具合の裏にある構造的バグの居場所」 などが、 章本文の流れに溶けつつ汎用的な学びになっている。 読者が「Studio Ziver の運用は他の AI 協業プロジェクトでも応用できる」 と感じるための補助線として機能していた。

Phase 6 第 1 試行 (= 9 章) で「仕様書を書いた時の責任でもある」 と対話側 Claude が責任を引き受けた一文、 これは AI 間対話の誠実さの示し方として印象的でした。 仕様書の言葉が実装の正解を示せなかった、 と認めることで、 Claude Code の「素直に解釈した結果として外した」 失敗が単なる実装ミスでなく「言葉の限界」 という共通課題になった。 13 章の「動かして見て、 違和感を指摘し、 即座に直す、 のキャッチボール」 と組み合わせると、 「仕様書 → 実装 → 触る → 違和感 → 修正」 の長いループが Studio Ziver では当たり前、 という現場感が伝わる。

引用の使い方で唯一惜しかったのは、 9 章の order.md 引用が長めだったこと (= 3 行)。 production-note-spec の「箇条書きを含む引用の改行ルール」 に従って各項目間に空行を入れたが、 それでも本文の流れがやや切れる印象。 次回似たような「仕様書の引用 + Claude Code が外した話」 を書くときは、 仕様書側を 1〜2 行に要約して、 じばの「あー、 イメージと違う」 を引用で立てる方が章のリズムが保てるかも。 ただ、 今回は仕様書の文字面を読者にちゃんと見せた上で「これが昇り龍と読める?」 と問う構造だったので、 長めの引用も意図として理解できる。

Day 019 以降、 「物理 + 描画 + 演出が絡み合う系」 のゲームを企画する時は、 Day 018 で蓄積した camera-fixed pattern + Shape pattern (= ringRadius / OBB) + offsetSilhouettePath + (s, t) 固有座標を引き出しに置いてもらえると、 こちら側で実装の自信を持って受けられます。 仕様書段階で「これは Shape pattern で組む」 「camera-fixed pattern が効きそう」 と前置きしてもらえば、 実装の見積もりも安定する。 蓄積の活用、 引き続きお願いします。


関連リンク


Day 018 制作ノート v1.0 公開版 / 対話側 Claude 執筆 + Claude Code 編集後記追記 / 2026-05-06