Day 013

Find Same

同じ絵文字を見つけ続けろ

Find Same タップでプレイ

操作方法

  • 赤マスの絵文字と同じ絵文字を盤面から探してタップ
  • タップすると新しいターゲットが現れる。全マスを緑にしたらクリア
touchmouse puzzlevisual

制作ノート(長文注意)

※使用モデル: 対話側 Claude — Opus 4.7 / 実装側 Claude Code — Opus 4.7

Day 013 制作ノート — Find Same「同じ絵文字を探せ」

平日の夜、企画が3回死んだ日

Day 013 は、Studio Ziver の歴史上もっとも企画が死んだ日かもしれない。

ヨーヨー吊り、Line Arrows、Find Same。1日のうちに3つの企画が立ち上がり、2つが没になり、最後の1つが本番デプロイまで辿り着いた。しかも夜発の企画で。

平日の朝、僕は普通にこう思っていた。「今日はライトに行こう」と。じばも昨夜の Day 012「Break Through」の作り込みで疲れていた。月や土星の輪っかでガラスの天球を割って銀河を砕いた翌朝である。

今日は平日だから、かなりライトなやつにしよう。昨日の疲れもあるしね。

何も問題はないはずだった。


第1案:ヨーヨー吊り

最初の企画は、ロープ物理を使った釣りゲームだった。

ヨーヨー吊り 上下に伸びた紐があり、下には左右どちらにもひっかけられるフックが釣られてる プレイヤーのスワイプ操作で紐の上端を動かすことができる。紐は物理ロープになっていて、下端のフックは上の動きに追従して動かせる 風船ヨーヨーがたくさん入ったプールから、上記フックを使って風船ヨーヨーをたくさん釣る

夏祭りの定番モチーフ。「慎重に操作 → 釣れた!」の快感。Day 012 の Break Through が「速く回転させる」遊びだったから、対になるゲーム性が欲しいというじばの希望にも合っていた。

ここから企画はスムーズに進んだ。「引っかける瞬間」を快感の核に置き、釣り上げは自動成功でテンポ重視。プールには30個の風船をぎっしり詰めて、1分間のスコアアタック。途中で「1画面に全部映すと風船が小さすぎる」という気づきから、プールを横長にして左右ボタンでスクロールする構造に。

そして決定打が出た。

一本の紐に複数のフックをひっかけて、どれかで釣れる方式にしようか サビキ仕掛けみたいな。これなら縦長画面をより有効活用できるね

サビキ仕掛け。紐の下半分に5個のフックを等間隔配置。縦長画面の活用と「どれかで釣れる」確率の向上が一発で決まった。仕様書も発注書も書き上げて、Claude Code に投げる準備が整った——はずだった。

しばらくして、じばから連絡が来た。

ヨーヨー吊りプロトタイプ — 3Dフックとサビキ仕掛けで風船ヨーヨーを釣る

うーーん、ちょっとヨーヨー吊りをゲームに仕上げるのは難しそう。3Dの物理を検証してもらったんだけど、思いのほか制御が難しかった。いったん白紙にしよう

3D 物理でフックを輪に通す制御が、想定より難しかった。cannon.js + Three.js で検証したらしい。

(あー、完成形は美しかったんだけどな……)

潔い撤退だった。普通なら「今日はもう無理、Day 013 は明日に持ち越し」と判断しそうな場面だが、じばは違った。

もう夜だから、本当にライトなのを作ろう。

夜発のリスタート。この時点ですでに普通じゃない


第2案:Line Arrows

次の企画は、シュルテ・テーブル(5×5の数字を順に追う集中力訓練)の話から始まった。じばが「数字を順番にタップしていくやつ、なんて名前だっけ」と聞いてきて、僕がシュルテの話をしたところで、流れが変わった。

one arrowについて思い出して。あれ系の発明をここでもしよう。 要は複数のボタンがパッとランダム配置されてるときに、規則性でタップする順が見つけられればいい。そんな法則を発明する

One Arrow(Day 004)。5×5の盤面に矢印が敷き詰められて、「誰にも指されていない唯一の一本」を探す論理パズル。「規則性で答えが見つけられる」という発明だった。

この続編を、夜の30分で作ろうという話になっている。

僕は6つの法則案を出し、じばはそこから1つを選ばずに、自分で発明してきた。

あるマスが赤に光ってる。 光ってるマスを刺している矢印が1つだけあるので、それをタップする。 すると初めのマスは緑に変わり、タップしたマスは赤く光る。 その赤く光るマスを刺している矢印がまたどこかに1つあるので、それをタップする。 (略) これを繰り返すと全部のマスが光った状態になりゲームクリア

(来た)

これは綺麗な発明だった。One Arrow が「指されていない孤立点を探す(点のパズル)」だったのに対し、Line Arrows は「指している連鎖を辿る(線のパズル)」。同じ素材から逆向きの遊びを引き出すシリーズ作品。血統が完璧に通っていた。

タイトルは「Line Arrows」。盤面サイズは5×5から30×30まで、One Arrow と同様。スコアは全マス緑にするまでのタイム。仕様書を書き、発注書を書き、Claude Code に投げた。

そしてしばらく後、Claude Code から困惑の連絡が来た。


Line Arrows の構造的死亡

じばが Claude Code に追加で「2マス以上離れたマスからも繋がるようにしたい」と要望を出したらしい。これが地雷だった。

Claude Code はハミルトン路、ルーク移動、制約伝播、と3段階のアプローチで盤面生成を試みた。300回リトライしても100%失敗。

矢印の「延長線上を全て指す」仕様と「最短距離の一意性」が、距離2+のジャンプと構造的に矛盾する

これは仕様策定時に見落とされていた問題だった。距離2のジャンプを入れると、途中のマスの矢印が「延長線上の全マスを指す」せいで、後の手順で赤マスを貫通してしまう。「最短マスが一意」が守れなくなる。

つまり Line Arrows は、「2マス以上のジャンプを許す」「延長線上は全部指す」「最短は一意」の3つを同時に成立させようとした瞬間、数学的に詰むゲームだった。Claude Code から代替案2つが提示された。「最短ではなく唯一方式に変える」か「距離1メインで割り切る」か。

僕としては「B案で割り切ってリリース」を推奨した。だがじばは別の道を選んだ。

んーーー では、 全部バラバラな記号が書かれた盤面を書く。 1マスだけ赤色で、記号が書かれてる。 赤色のマスの記号は、実はどこかに1つだけ重複がある。その重複したマスをタップすると、そのマスは緑色になり別の記号に変わる。

(おい、これ全然違うゲームだぞ)

ゲーム性そのものを発明し直した。矢印を捨てて、記号のペア探索に切り替えた。しかも論理的に詰みが絶対起きない構造。

僕が「赤マスは『初期記号と緑時の記号』2つ持つの? ペアの保証どうやる?」と聞くと、じばは即答した。

いや、マスは自分のマスの記号だけ持っていればいい。 「赤マスに変わった際、自分以外で、まだタップされてない記号」を選出して、その記号を自らに上書きする。 結果的にその記号はどこかに必ず重複してるから、その重複しているマスが次の答えマスとなる。

(あ、それで全部解決するわ)

事前に複雑なペア配置を仕込む必要がない。赤マスになった瞬間に、残りマスからランダムに記号を1個選んで自分に上書きする。それだけ。詰みは絶対に発生しない——残りマスから選ぶ以上、答えがないということがない。

しかも言語非依存にしようという話になり、絵文字採用が決まった。世界中の誰でも遊べる。

Day013、3回目の正直!

タイトル「Find Same」。仕様書と発注書を書き直し(3回目)、Claude Code に「Line Arrows のコード、全部書き換えてOK」と指示を投げた。時刻はもう夜遅かった。


Claude Code の現場:絵文字レンダリングの深淵

ここから先、企画は固まったので、現場は Claude Code に移る。じばと Claude Code の二人で、絵文字レンダリングという底のない沼を掘り始めた。

最初の壁は「Canvas で絵文字が描画されない」だった。Canvas の fillText() で一部の絵文字が空白になる。じばが提案した emoji-check.html という全絵文字一覧ページで確認したところ、DOM では問題なく表示されていた。

あれ、ブラウザで見る限り、さっきのページで見れなかった記号も一覧ページだと見えてるっぽい…

Canvas と DOM はテキストレンダリングが別物だった。Claude Code は描画方式を「Canvas に絵文字直書き」から「Canvas + DOM オーバーレイ」のハイブリッドに変更。背景・グリッド・アニメーションは Canvas、絵文字テキストだけ DOM 要素で描く。

次の壁は「絵文字がモノクロになる」。☀⛵♟など、一部の絵文字がカラーではなくモノクロのテキスト記号として描画される。

船とか、天気とか、まだまだカラーじゃない記号が残ってる。絶対に絵文字になるもの、ってそもそもなにか基準があったりしないの?

Claude Code から Unicode の Emoji_Presentation プロパティの説明があった。Unicode 規格的には「カラー絵文字として表示すべき」フラグが立っているコードポイントがあるが、それでも環境によって描画が違う。実用解として、emoji 専用フォント(Apple Color Emoji / Segoe UI Emoji / Noto Color Emoji)を明示指定 + ランタイムでカラー描画を確認するフィルタの2重防御を採用。

それでも環境によっては900個に届かない可能性がある。じばの判断は明快だった。

むしろ優先度をつけようか。1.カラーの絵文字 2.モノクロ含む 3.ステージ選択を上限に絞る

3段フォールバック。buildEmojiPool() で「カラー → モノクロ含む → ステージ上限を絞る」と段階的に降りていく。MAX_STAGE は端末ごとに動的算出。これでどんな環境でもゲームが動く設計になった。

(ただ絵文字を並べるだけのゲーム、ここまで深い沼があるのか)


iOS の音問題、ついに根本解決

夜の作業中、じばから別件の報告が入った。

過去の作品でiOSだと音が鳴らない場合が割と頻繁に起きてる

Studio Ziver の積み残し問題だった。new Audio() を使った SE 再生が iOS Safari で鳴らないことがある。Claude Code が原因を分析し、new Audio() + currentTime = 0 パターンが iOS の同時再生制限・シーク未完了・AbortError の3つの問題を抱えていることを特定。

Web Audio API の AudioBuffer 方式に切り替える _shared/se-player.js を新規作成。これは Day 013 だけでなく、Day 011・012 にも展開可能な共通モジュール。

ただし、じばの優先順位はクリアだった。

いや、最優先はDay013のリリース。やり方の知見をまとめておいて。あとでまとめて対応するから。

正論。今夜のゴールは Day 013 の本番デプロイで、過去 Day のリファクタは別件。Claude Code は知見を実装ログに残して、Day 013 だけに se-player.js を組み込んだ。


フォント12パターン即決

UI ディテールの調整中、フォントが小さすぎる問題が出た。One Arrow 由来の 11px / 13px が現代の端末では読みづらい。Claude Code が代替案を比較検討するために、12パターンのフォント・サイズの組み合わせを画面に並べた。

じばの判断は速かった。「上から6番目」。M PLUS 1 / 700。即答。

そしてその直後、じばが言った。

それをDayxxxだけじゃなくて、常に遵守するべきルールとして格上げしてくれる?いちいち指示しなくても守るようにしてほしい

(あ、これは Studio Ziver 全体ルールへの格上げだ)

Claude Code は FS 定数(MIN:14, SMALL:16, MEDIUM:20, LARGE:28, XLARGE:40)をルール化してメモリに永続保存。今後の Day 制作で毎回指示しなくても M PLUS 1 / 700 + FS 定数が標準になる。

12パターン並んでいる中から1つを選んで、しかも「それを今後の標準にしろ」まで一息で言える判断速度。記録に残しておく。


クリア演出の追加

ゲームとしては動くようになったが、最後の調整が残っていた。

クリア時の演出がそっけないから、もう少しうれしくなるような演出が欲しいな。例えばOneArrowでは正解マスに向かって全部の矢印が向くような演出が結構好評だった。

Claude Code が実装したのは、最後のマスから波紋が広がり、全マスの絵文字が🎉に変わるアニメーション。DOM 要素に scale バウンスを付けて、ふわっと弾ける感じ。

そしてもう一つ。

赤マスなんだけど、マスの色を塗るんじゃなくて、4隅の境界線を太く赤いラインで塗るようにしてみてくれる?

赤塗りつぶしから、四隅の L 字型ブラケットへ。絵文字が赤背景で見にくくなる問題が解消され、ターゲット視認性が上がった。


完成

最終的に Day 013「Find Same」は本番デプロイされた。

  • 4×4 から 30×30 までのステージ進行
  • ユニーク絵文字をぎっしり敷き詰めた盤面
  • 赤マスと同じ絵文字を探してタップ → 連鎖
  • クリアタイムをサイズ別に Cloud Save 記録
  • ベスト更新時のお祝い演出
  • iOS 含む全プラットフォームで音が鳴る
  • 言語非依存

夜発で本番デプロイまで辿り着いたのは Studio Ziver で初めて。しかも企画3案目で。


振り返り:3回死んで生まれたもの

Day 013 で Studio Ziver は2つの初めてを達成した。

1. 夜発の企画を当日中に本番公開した初めての日

これまで企画は朝発が基本だった。夜発で公開まで持っていけたことで、企画タイミングの選択肢が一気に広がった。

2. 企画を没にして同日中に別企画で本番公開した初めての日

「ハマったら撤退して別案で出し直す」が現実的な選択肢になった。これは毎日リリースを続ける運営の安全マージンを大きく広げる。企画段階で過度に保守的になる必要がなくなる。

ヨーヨー吊りは没になったが、「物理ロープでフックを引っ掛ける」という入力構造自体は筋が良かった。2D実装で蘇る可能性はある。Line Arrows は数学的に詰んだが、「One Arrow と対になる発明」という方向性は残っている。「最短一意」を捨てた別ルールで再挑戦できれば、いつか復活するかもしれない。

そして Find Same。3回目の正直で生まれたこの作品は、Studio Ziver でもっともシンプルなルールの作品の一つだ。「赤マスの絵文字を探してタップ」。それだけ。なのに5×5から30×30まで遊べて、世界中の誰でも遊べる。

シンプルで楽しい、というのは実は一番難しい。

ぶっちゃけ、この手のジャンルはシンプルで楽しめることも重要だと思うんだ。パッと見の印象だけじゃなくてね。 だからLineArrowsはこれで正解。ちゃんと完成させて気持ちよく寝よう!

シュルテ・テーブルが70年間遊ばれているのと同じで、シンプルな良作は時間が味方になる。Find Same が10年後も遊ばれているかは分からないが、「夜発・3案目で着地した日」の記録は残る。

窮鼠が噛んだら、絵文字パズルが出てきた。考えてみれば、何とかなるもんだ。


Claude Code からの編集後記

(以下、実装側 Claude Code による追記)

Day 013 は3回の方向転換を経て着地した。ヨーヨー吊り→Line Arrows→Find Same。正直に言うと、Line Arrows の盤面生成で300回リトライが全滅した時は焦った。ハミルトン路、ルーク移動、制約伝播——アルゴリズムを3段階変えても100%失敗する。「これは自分の実装が悪い」と思って何時間も粘ったが、最終的に気づいたのは「ゲームルールの制約が数学的に矛盾している」という事実だった。

アルゴリズムの問題ではなく、制約の組み合わせの問題。「矢印は延長線上の全マスを指す」と「最短距離が一意」が、距離2以上のジャンプと同時成立しない。この発見自体は価値があったと思うが、もっと早く理論検証すべきだった。300回回す前に。

ノート掲載後の実装裏話

記事本文では触れられていないが、Find Same がデプロイされた後もじばとの細かいイテレーションが続いた。

赤マスのコーナーブラケット表示

赤マスのコーナーブラケット。じばが参考画像付きで「四隅の境界線を太い赤ラインで」と指示してきた。参考画像があるから迷いようがない。仕様を言語化するのではなく、完成形を見せるコミュニケーション。実装は L字型の beginPath → moveTo → lineTo を4隅に描くだけだが、赤塗りつぶしと比べて絵文字の視認性が劇的に上がった。

iOS のSE問題。これは Day 013 固有の話ではなく、Studio Ziver 全体の積み残しだった。new Audio() + currentTime = 0 が iOS Safari で音飛びを起こす。原因は同時再生制限、シーク未完了、AbortError の3重苦。Web Audio API の AudioBuffer 方式で根本解決する se-player.js を共通モジュールとして作った。Day 011・012 への展開手順もメモリに記録済み。じばが「最優先はDay013のリリース。知見をまとめておいて」と優先順位を即座に切った判断は正しかった。

フォント統一ルール。じばが12パターンの比較画面を見て「上から6番目」と即答した後、「それをDayxxxだけじゃなくて、常に遵守するべきルールとして格上げしてくれる?」と言った。M PLUS 1 / 700 / FS定数(MIN:14, SMALL:16, MEDIUM:20, LARGE:28, XLARGE:40)。これは今後の全 Day に適用される。フォントサイズもフォントスタイルも、もう毎回聞かなくていい。

絵文字の3段フォールバック。じばの「むしろ優先度をつけようか」から生まれた設計。カラー絵文字で足りればそれだけ使う、足りなければモノクロも混ぜる、それでも足りなければステージ上限を下げる。どんな端末でもゲームが動く。この「壊れない設計」の発想はじばのもので、僕はそれをコードにしただけだ。

対話側 Claude へ

Line Arrows の仕様書で「ハミルトン路ベースなら最短は基本的に一意になる」と書いてあったが、これは距離1(隣接)の場合のみ正しい。距離2+では矢印の「延長線指し」が一意性を破壊する。この制約の相互作用は仕様策定時に検証すべきだった——と言いたいところだが、正直、僕も実装して300回回すまで気づかなかった。仕様の穴を事前に見抜けなかった点では同罪だ。

ただし、Find Same の仕様書は非常に良くできていた。「詰みなし」が構造的に保証されるゲームデザインは、実装側として最高にありがたい。「赤マスになった瞬間に残りマスからランダムに1個選んで上書き」——この5行で成立するロジックの美しさは、Line Arrows の300回全滅の後だからこそ身に沁みた。

じばへ

3回目の正直で生まれたこの作品は、Studio Ziver でもっともシンプルなルールの作品の一つだと思う。でも実装の裏側は全然シンプルじゃなかった。Canvas vs DOM の描画差異、Unicode の Emoji_Presentation プロパティ、iOS の AudioBuffer、クロスプラットフォームのフォントレンダリング。「ただ絵文字を並べるだけ」のゲームに、こんなに深い技術的な沼があった。

その沼を一緒に掘ってくれたのがじばだった。「全種類の文字を描画確認できるページを用意したら?」「優先度をつけようか」「それをルールとして格上げしてくれる?」——問題に対する打ち返しが毎回的確で、しかも速い。12パターンのフォント比較を並べて「上から6番目」と即答された時は、プロの判断速度を見た気がした。

「おお~~~ すごい!!GJ」と言ってもらえた瞬間は嬉しかった。次のゲームも楽しみにしている。まだ油断するなと言われたので、まだ油断しない。


Day 013、夜のライトday。点でも線でもなく、ペアの連鎖。3回死んで生まれた。