目次
スマホの中に「うちの子」が住んでいて、ふと開くと画面の中で暮らしている。この夏、そんな犬アプリを作っていました。結論から書くと、このアプリはかなり先まで作り込んだうえで、いま凍結しています。技術的に行き詰まったからではありません。途中の壁はいくつも越えられたのに、最後に残った「この画面を見ていたくなるか」という問いだけは、コードが動くだけでは答えられなかったからです。
どんな犬アプリを作りたかったか
中心にあったのは、「いつでもどこでも、大好きな犬と一緒に過ごせる感覚」でした。犬の写真を投稿するSNSでも、プレイヤーが犬を操作するゲームでもありません。スマホの中に「うちの子」がいて、ぼーっとしたり、座ったり、眠ったり、ときどき歩いたりする。朝と夜では過ごし方も少し違う。タップするとドット絵から本物の写真へつながる。そんな、犬が勝手にそこで暮らしていて、ふと眺めたくなる場所を作ろうとしていました。
ただ、最初から「うちの子を眺める」だけのアプリを考えていたわけではありません。もうひとつ大きな軸にしていたのが、現実ですれ違った人が登録している犬との、偶然の出会いでした。
タイムラインではなく、すれ違いで犬と出会う
XやInstagramを開くと、自分とは直接関係のない投稿まで次々と流れてきます。誰かをフォローしたり、おすすめ欄を眺め続けたりすれば、いくらでも新しい情報が出てくる。犬アプリでは、その逆にしたいと考えていました。
自分の犬を登録すると、スマホの中の広場に「うちの子」が暮らし始める。そして現実の生活の中で、アプリを使っている別の人と一定範囲ですれ違うと、その人が登録している犬の情報を非同期で受け取る。その場で通知を出して交流するのではなく、あとでアプリを開いたときに、知らない犬が広場に増えている。「この犬、いつ来たんだろう」と思ってタップすると、その子の本物の写真や動画を見ることができて、そこから「かわいい」「なでなで」といった軽いリアクションを送れる想定でした。
大量の投稿を流すつもりもありませんでした。一度にやってくる犬は数頭程度で、自由なDMやコメントも前提にしない。一匹一匹を「今日すれ違った犬」として感じられるくらいの距離感にしたかったからです。技術的には犬のプロフィールデータを交換しているだけでも、画面ではそれを「知らない犬が自分の広場へ遊びに来た」という出来事として見せる。設計資料では、この考え方を「冷たいデータ交換を“出会い”に翻訳する」と整理していました。
位置情報も、相手の正確な場所を知るために使いたかったわけではありません。どこですれ違ったのかを地図に残すのではなく、「今日どこかでこの犬の飼い主と近くを通った」という程度にぼかす。犬を入口にした小さな偶然だけを残す構想でした。
まずは「うちの子」だけでも成立させる
ただ、この構想をそのまま作り始めると、ひとつ問題があります。すれ違いは他のユーザーがいて初めて成立するので、利用者がほとんどいない初期状態では誰とも出会えません。
そこで開発の途中から、まずは他のユーザーが一人もいなくても成立する体験を先に作る方針へ変えました。横向きの小さな箱庭で「うちの子」が生活のリズムを持って過ごし、タップすると本物の写真が出てくる。それだけでも、ふとアプリを開きたくなる状態を先に作る。すれ違いを捨てたわけではなく、その土台が成立したあとに重ねる機能へ移した形です。実際、後期の設計でも「すれ違い」は上乗せ層として残っていて、表示する犬は数頭まで、DMや自由コメントは使わず、定型リアクション中心という考え方は維持しています。
そして、この「まず一匹だけでも見ていたくなるものを作る」という判断が、結果的には犬アプリを凍結する理由にもつながっていきました。
作り方は、何度も変えた
最初の構想はかなり野心的で、うちの子の実写真からその子らしいドット絵を作り、正面・後ろ・左右の四方向と歩行アニメーションまでAIで自動生成するつもりでした。ところが生成ツールを実際に試すと、四方向で犬の見た目が安定しない。写真に写り込んだ人の手まで生成結果に入り込む。今回試した方法では、そっくり度と四方向の一貫性を安定して両立できませんでした。
ここで諦める代わりに、設計を変えました。写真から毎回生成するのをやめて、品質を確認済みの犬種テンプレートから選ぶ方式へ。そっくりなドット絵を追いかける代わりに、ドット絵はスマホの中での存在感を、本物の写真は本人らしさを担当する、という役割分担です。
世界の作り方も一度大きく削っています。当初は見下ろし型で四方向に動き回るゲーム寄りの構成でしたが、四方向ぶんの素材を用意する負荷と、犬を自然に見せる難しさを考えて、横向き素材のidle・お座り・眠り・歩きと、朝昼夕夜で変わる行動比率に絞り直しました。この時期に重視していたのは移動量ではなく生活のリズムで、まず1匹でも「犬がそこに暮らしている」と感じられることを先に成立させる。その土台ができてから、自由移動や複数の犬へ再び広げていきました。
思った以上に作れた
実装はFlutterとFlameで、6月の前半に設計と検証を進め、後半に集中して形にしていきました。素材は初期に複数のAI生成ツールを検証し、後半はAutoSpriteも活用しながら、品質を確認できたものだけを採用。柴犬を主役に、チワワ・ダックスフンド・ミニピン・プードルまで揃いました。行動リズム、自由移動、プロフィール、タップで開く写真カード、GoogleとLINEのログイン。どれもPixel 9の実機で動いています。
途中の技術的な壁は、調べれば越えられました。たとえば写真の保存は実機で失敗が続いたのですが、原因を追いかけるとPostgresの権限エラーに行き着き、RLSの問題ではなくauthenticatedロールへのGRANT不足だと判明。DB権限を直すと、写真を選んで保存し、アプリを完全に終了して再起動しても写真が復元されるところまで通りました。LINEログインも最初の方式ではSupabase側の検証仕様と噛み合わず成立しなかったので、LINEのネイティブSDKからEdge Functionを経由してセッションを作る方式へ変更して、実機でアプリ本体まで到達しています。詰まっても、原因を特定して方式を変えれば前へ進める。この時点までは、ずっとそうでした。
複数の犬まで来て、違和感が大きくなった
最後に取り組んでいたのが、広場に複数の犬を置くことでした。NPCの犬たちが同じ画面で全部の行動をして、奥行きに応じて前後が入れ替わる。表示してすぐ違和感が出たわけではなく、ここでも調整を重ねています。ダックスフンドのアニメーションのちらつきを直し、主役の柴だけ大きくてぼやける問題を調整し、配置を散らし、行動の切り替えにフェードを入れ、芝生の背景を敷いて、広場としての仕上げを続けました。

これが凍結時点の実画面です。機能としては成立しています。そしてこの広場は、最終的には現実ですれ違った人たちの犬が少しずつ集まってくる場所になるはずでした。だから問題は、単に5匹の犬をうまく配置できているかではありません。この場所そのものを、知らない犬が増えたときに思わず開きたくなる世界にできるか。その前提に、僕自身がまだ納得できていませんでした。
この画面を前にして大きくなっていったのは、「頭の中で想像していたものと違う」という感覚でした。思い描いていたのは、犬たちが自然にそこで暮らしていて、眺めているだけで楽しく癒される世界です。実際の画面はそこに届いているように感じられず、クオリティが低く見えて、「これを誰が使うんだろう」という問いが浮かんでしまう。複数の犬そのものが嫌だったわけではなく、全体の雰囲気と完成度が、欲しかった体験になっていませんでした。
技術の壁と、体験の壁は別だった
振り返ると、それまでの問題にはすべて対処のしようがありました。写真からの生成が難しければ方式を変える。四方向が重ければ生活リズム中心に絞る。保存が失敗すれば原因を調べて権限を直す。ログインが通らなければ認証の経路を変える。複数の犬に表示の問題が出ればサイズや素材や背景を調整する。症状があり、原因があり、打ち手がある問題です。
でも「この世界を見ていたいか」「犬が自然に暮らしていると感じるか」という最後の問いには、機能をひとつ追加すれば解決するような明確な答えがありませんでした。Claude Codeに実装を任せる部分が多かったので、動くものができる速度は本当に速かった。ただ、速く作れるのは「動くもの」までで、それが「欲しかった体験」になっているかの判断は、変わらずこちらに残っていました。作れなかったから差が見えたのではなく、かなり作れたからこそ、頭の中の完成形との差を実物で判断できたのだと思います。
凍結する判断
答えのない問いを抱えたまま機能を足し続けても、あの差は埋まりそうにありませんでした。致命的なバグで止まったわけでも、特定の機能が実装できなかったからでもありません。それでも、欲しかった体験になっていないと分かっている画面に積み増しを続けるより、ここでいったん止める。そう決めて、犬アプリは凍結にしました。
現在
コードと素材はそのまま残っていて、現在は凍結状態です。プロジェクトの概要はProjectsページにもまとめてあります。