休日である。
せっかくなので、以前から作っている自作アプリをClaudeと一緒にいじっていた。
筆者はいわゆる「バイブコーディング」寄りの人間である。
コードを一行一行自分で書くというより、
「こういう感じにしたい」
「なんかここ変じゃない?」
「既存部分は壊さないでいい感じにして」
みたいな、だいぶふわっとした注文をAIに投げる。
返ってきたものを動かす。
壊れる。
文句を言う。
直させる。
また何か思いつく。
そんな感じで休日の個人開発をしていたところ、突然Claudeがこうなった。
API Error: 529 Overloaded.
This is a server-side issue, usually temporary — try again in a moment.
Claudeが落ちた。
俺の休日開発も止まった。
……というのも癪なので、前からちょっと気になっていたものを試してみることにした。
OpenCodeから使える無料モデル、
0xAlphaFree。
今回はベンチマークを回すわけでも、「無料AI最強!」をやりたいわけでもない。
知りたいのはもっと実用的な話だ。
普段Claude相手にゆるふわなバイブコーディングをしている人間が、Claude障害中だけ別の無料モデルへ避難しても開発を続けられるのか?
せっかくなので、実際に開発中のプロジェクトをそのまま渡してみることにした。
そもそも何を作っていたのか
今回0xAlphaFreeに渡したのは、個人的に開発しているWallpaper Engine向けの「宮舞モカ デスクトップアシスタント」。
名前だけ聞くと大層だが、やりたいことは割と単純である。
「PCで作業している横で、デスクトップ上に宮舞モカが住んでいたら楽しいよね」
というもの。
現時点ではこんな感じ。
【ここに現在のデスクトップのスクリーンショット】
※Windows 11 + Wallpaper Engine上で実際に動作している画面。スクショ用にデスクトップアイコンとタスクバーは非表示にしている。
右側にいるのがキャラクター。
左側にはスマホ風のNow Playing表示があり、現在PCで再生している音楽を表示している。
中央上部には時計。
左下には会話システムの状態表示。
右下の「+」からは付箋を追加できる。
一見すると「キャラクター付きの動く壁紙」なのだが、最終的に作りたいのはもう少し変なものである。
「壁紙のキャラ」ではなく「デスクトップに住んでる人」にしたい
目標としているのは、単にキャラクターを表示して瞬きさせるだけではない。
デスクトップ上を歩き回る。
勝手に喋る。
音楽に反応する。
何かを見つける。
そこまで歩いていく。
こちらが特に操作していなくても、勝手に何かしている。
そうやって、
「キャラクターがデスクトップの中で生活している」
ように見せたい。
チャットボットというより、横で勝手に喋っている人
会話部分はAIと連携している。
ただし、こちらから毎回話しかけるチャットボットにしたいわけではない。
作業している横で、
「もうこんな時間なんだ」
とか、
「今日暑いね」
とか、
今流れている曲について何か言ったりとか。
ラジオくらいの距離感で、作業中に勝手に喋っていてほしい。
現在も会話内容に合わせた口パクなどは行えるようになっている。
Now Playingの情報もアプリ側から取得できるので、将来的には音楽を含めた現在の状況をキャラクター側が認識できるようにしたい。
付箋も「ただのUI」にはしたくない
スクショ右下の「+」からは、デスクトップ上に付箋を追加できる。
これも単なるメモ帳で終わらせるつもりはない。
最終的には付箋そのものを、モカからも認識できる**「デスクトップ上の物体」**として扱いたい。
例えば、
ユーザーが付箋を書く
↓
モカが付箋に気付く
↓
付箋のところまで歩いていく
↓
立ち止まる
↓
付箋を見る
↓
内容を読む
↓
何かコメントする
みたいなことをさせたい。
つまり最終的には、AIが文章を生成して喋るだけではなく、
「何かに気付く → そこへ移動する → 見る → 考える → 喋る」
くらいまで含めて、一人のキャラクターとして動かしたい。
そんなものをちまちま作っている。
で、右側のモカを「この見た目のまま」動かしたい
今回の開発テーマは、スクショ右側のキャラクター表示。
ここが重要なのだが、
この見た目をなるべくそのまま維持して動かしたい。
現在のプロジェクトには、完成済みの2D立ち絵を表示する方式とは別に、VRMモデルを使った3D表示も実装している。
3Dは非常に便利である。
頭を動かす。
瞬きする。
腕を振る。
脚を動かす。
歩く。
視線を向ける。
こういった動作は、3Dモデルなら比較的素直に実装できる。
ところが問題がある。
宮舞モカの元になるビジュアルは2Dイラストである。
2Dキャラクターを3Dモデルへ起こすと、どうしても顔の輪郭、髪型、目の見え方などが変わる。
色々調整してみたものの、どうにも、
「宮舞モカ本人がそこにいる」
というより、
「宮舞モカっぽい3Dモデルがそこにいる」
という印象が消えなかった。
動きの自由度は高い。
でも今回のプロジェクトで一番欲しいものは、自由に360度回転できることではない。
スクショ右側にいる、この2Dイラストのキャラクターがそのまま動き出すこと。
だったら、そもそも3Dにする必要がないのでは?
というところに戻ってきた。
3Dを元絵に近づけるのではなく、元絵をそのまま動かす
そこで今回考えたのが、独自の2Dパペット方式。
Live2Dのような高度な変形システムをいきなり導入するのではなく、元のイラストをIllustratorなどで、
頭
├─ 顔
├─ 前髪
├─ 後髪
├─ 左目
├─ 右目
└─ 口
胴体
├─ 左上腕
│ └─ 左前腕
│ └─ 左手
├─ 右上腕
│ └─ 右前腕
│ └─ 右手
├─ 左脚
└─ 右脚
のようにパーツ分割する。
そして、それぞれに回転中心を設定してプログラムから少しだけ動かす。
例えばidle中なら、
- 身体が呼吸に合わせて数ピクセル上下する
- 頭がほんの少し動く
- ランダムに瞬きする
- 髪が身体から少し遅れて揺れる
歩くときなら、
- 腕と脚を少し動かす
- 身体をわずかに上下させる
- 進行方向へ少し傾く
- 頭と髪が遅れて追従する
喋るときなら、
- 既存の口パク情報で口を動かす
- 瞬きする
- ときどき少し首を傾ける
くらい。
目指しているのは、
「高度な2Dアニメーション」ではない。
むしろ、
「元の2Dイラストが、元の2Dイラストのまま少しだけ生きている」
くらいでいい。
顔をぐにぐに変形させる必要もない。
今回のアプリで重要なのは技術的に豪華であることではなく、
元絵の宮舞モカ本人がデスクトップ上にいるように感じられること
だからである。
ただし、AIに全部作り直されると困る
ここで問題になるのが、すでにプロジェクトがそれなりに育っていることである。
キャラクター表示だけなら、
「VRM消して2Dにして!」
でもいい。
しかし実際には、
- キャラクター位置管理
- 歩行
- idle
- 口パク
- AI会話
- 音楽との連動
- 付箋
- 今後追加するイベントシステム
などが絡んでいる。
ここでAIに雑に、
「VRMやめたいから2Dにして」
とだけ言って、既存コードを盛大に作り直されたら困る。
そこで0xAlphaFreeには、かなり長い指示を渡した。
要約すると、
まず既存実装を調査すること。
VRM関連コードはいきなり削除しないこと。
キャラクターの見た目とモーションだけ2Dへ交換し、AI・付箋・イベント・会話など既存システムは極力そのまま使うこと。
VRM固有処理とキャラクターの行動ロジックが密結合しているなら分離すること。
まず実装計画を作ること。
計画が承認されるまでは実装しないこと。
という内容である。
今回は「無料モデルにTODOアプリをゼロから作らせてみた」という話ではない。
すでに存在するプロジェクトを理解して、既存部分を壊さず改修計画を立てられるのか。
こっちを試すことになった。
無料モデル、まず既存コードを漁り始める
指示を渡すと、0xAlphaFreeはPowerShellを使ってプロジェクトを調査し始めた。
例えばこんなことをしている。
Test-Path -LiteralPath "...\places.json"
Get-Content -LiteralPath "...\state.json"
結果、
False
{"updated_at": ..., "mode": "idle", ...}
などと返ってきている。
最初は、
「おっ、無料モデルなのにいきなりコードを書き散らかさず、ちゃんと調査してるじゃん」
と思った。
……が。
よく考えたら俺がプロンプトにかなり念入りに、
「まず既存実装を調査しろ」
と書いていた。
そりゃ調査する。
重要なのは、このあとである。
調査結果は思ったよりちゃんとしていた
しばらく待つと、既存実装をかなり具体的に調べた結果を返してきた。
まず、現在のキャラクター表示がすでに複数系統あることを整理。
完成済み画像を表情や口の開き方に応じて丸ごと差し替える旧2D方式。
現在試しているVRM方式。
そして読み込み失敗時のプレースホルダ。
ここまでは単なる現状整理。
その次に、重要なものを見つけてきた。
すでに「差し替えポイント」が存在していた
VRM版では、
window.mokaCharacter
というAPIが外部へ公開されていた。
そこには、
setMotionState()
moveToRatio()
lookAtRatio()
setLipsync()
stopLipsync()
isReady()
といった操作がまとまっている。
そしてアプリ本体側は、VRM内部のthree.jsなどを直接触っているわけではなく、基本的にこのAPIを通して操作していた。
0xAlphaFreeはここを見て、
「だったら2Dパペット側も同じAPIを実装すればいい」
と判断した。
これはかなり都合がいい。
上位のAIや行動システムから見れば、
右へ移動して
↓
そこを見て
↓
喋って
という命令を出すだけ。
その先でVRMが動いているのか、2Dイラストが動いているのかは知らなくていい。
つまり既存システムを大きく触らず、
「実際にキャラクターを描画している部分」だけ交換できる可能性が高い。
今回の目的にかなり合っている。
付箋にも、すでに将来用のフックがあった
さらに付箋システムも調査。
すると付箋データの中に、
mokaAwareness
というフィールドがすでに存在していた。
まだ使われていないが、名前からして完全に、
「モカがこの付箋を認識済みかどうか」
を入れるための場所である。
さらに付箋システムには subscribe も存在する。
つまり将来的には、
新しい付箋が作られる
↓
subscribeで検知
↓
mokaAwarenessを確認
↓
まだ見ていなければ付箋まで移動
↓
付箋を見る
↓
AIへ内容を渡す
↓
コメントする
という接続ができる。
新しい付箋管理システムを勝手に生やすのではなく、
既存コードの中にすでにある接続点を探して再利用する
という判断をしてきた。
この辺から、
「あれ、この無料モデル、思ったより普通に既存プロジェクト読めるな?」
となってきた。
提案:「VRMを置き換える」のではなく「第三のRendererを追加する」
最終的に0xAlphaFreeが出してきた基本方針がこれ。
window.mokaCharacter
△
┌────────────────┼────────────────┐
│ │ │
旧2D立ち絵 VRM 2D Puppet
(既存) (既存) (新規)
VRMを削除しない。
旧2D表示も残す。
その上で、
既定 → 旧2D立ち絵
?vrm=1 → VRM
?char=puppet → 新2Dパペット
として、3方式を並行して動かす。
新しい2Dパペットが盛大に壊れても既存版には影響しない。
元の要求通りである。
さらに、
CharacterMovement
と、
PuppetAnimation
を分離する設計も提案してきた。
要するに、
「画面の右へ移動すること」と「歩いているように腕や脚を動かすこと」は別物
として扱う。
これは将来的に付箋やデスクトップ上のオブジェクトまで自律的に歩いていくことを考えると、かなり重要になる。
2DパペットはCanvasで描く
描画方式については、
- DOMで各パーツを重ねる
- PixiJSなどを使う
- Canvas 2Dを使う
という候補を比較したうえで、Canvas 2Dを選んできた。
ファイル構成も、
puppet/
├─ manifest.json
├─ motions.json
├─ rig.js
├─ animation.js
├─ movement.js
├─ puppet.js
├─ debug.js
└─ test.html
のように分割。
manifest.json には、
この画像は頭
親は胴体
回転中心はここ
重なり順はここ
といったリグ情報を持たせる。
motions.json には、
idle
walk
talk
などのモーションを書く。
こうしておけばIllustrator側で素材を変更するたびにJavaScriptを書き換えなくて済む。
さらに開発用Debug UIも用意し、
- パーツの表示・非表示
- pivot
- position
- rotation
- scale
- z-order
- animation
- animation speed
- キャラクター位置
などを画面上から触れるようにする計画になった。
だいぶそれっぽい。
ただし、細かく読むと怪しいところもある
ここで、
「0xAlphaFreeすげえ! Claudeいらん!」
とはならなかった。
初版の設計を細かく読むと、いくつか怪しいところがある。
例えば座標系。
ある場所ではpivotを画像ローカル座標として説明しているのに、別の場所ではIllustratorのアートボード座標をそのまま使うような説明になっていた。
このまま実装すると、パーツを書き出した瞬間に座標がズレる可能性がある。
z-orderにも若干矛盾があった。
さらに、
「Canvas 2DならVRMより桁違いに軽くなる」
など、まだ実測していないことを妙に自信満々で言っているところもある。
AI、こういうところある。
そして「歩き方」がかなり怪しい
もう一つ気になったのが歩行。
今回使うのは基本的に正面向きの2Dイラストである。
横向きのキャラクター画像があるわけではない。
その状態で腕と脚を振っても、正面から見れば「歩く」というよりその場で足踏みしているように見える。
その足踏みしているイラストを画面上で横へ移動させる。
結果、
紙人形が足踏みしながら横滑りしていく。
これはまずい。
そもそも今回の目的は人体として正しい歩行アニメーションではない。
スクショ右側のモカが、その見た目を崩さず「なんかトコトコ移動してる」ように見えればいい。
その意味でも、最初の設計は少し動かしすぎな気がした。
じゃあ、自分で自分の設計をレビューさせてみよう
そこで0xAlphaFreeに、
「今作った計画を自分で批判的にレビューして、実装時に破綻しそうなところを探して修正して」
と頼んでみた。
特に、
- 座標系
- z-order
- Canvas描画負荷
- Illustratorからの書き出し
- 正面向き2Dキャラの歩行
あたりを重点的に見直させた。
すると、意外とちゃんと直してきた。
初版のv1.0からv1.1へ更新され、最終的には9項目の修正が記録された。
例えば、
- 座標系をアートボード基準へ統一
- PNG書き出し時に原点がズレない方式へ変更
- 正面歩行の「横滑り問題」を仕様として明文化
- 瞬きを「瞼を上から被せる」方式から開眼・閉眼画像のswapへ変更
- Canvasへのdrop-shadowを廃止
-
moveToRatioの座標定義を明文化 - 不要な左右flip機能をPhase 1から削除
- z-orderを左右非対称前提へ修正
- Illustratorからの書き出し方法を見直し
など。
自分で作った設計の穴を、指摘されればある程度自分で潰せる。
これは結構面白い結果だった。
そして最大の問題に気付く
さらに実際の立ち絵を確認した結果、もっと根本的な問題を見つけてきた。
スクショ右側のモカをよく見ると分かる。
両脚が交差している。
そして、
両手も身体の前で組まれている。
この完成済みイラストをそのまま、
上腕
前腕
手
太もも
すね
足
と切り分けるのはかなり無理がある。
交差して隠れている部分は、そもそも絵の中に存在しない。
無理やり切り出せたとしても、関節を数度回しただけで隠れていた部分が露出し、シルエットが崩壊する。
つまり、
「今ある立ち絵をIllustratorで切り分ければ、そのままパペットにできる」
という前提自体が間違っていた。
そこでv1.1では方針変更。
「直立・腕下ろし・脚揃え」のパペット用ベース絵を新しく用意する。
顔、髪、衣装、キャラクターデザインについては元絵を忠実に参照する。
ただし身体については、最初から関節を動かすことを前提に描き起こす。
さらに、
- 閉じ目
- 口の開き3段階
- スカートの裏側
- 頭を動かしたときに見える首元
- 腕や脚を動かしたときに露出する部分
など、完成済みの一枚絵では描かれていないところも必要になる。
これは結構大きな設計変更だった。
そして個人的には、今回一番評価したところでもある。
「どうコードを書くか」以前に、「そもそもその素材では成立しない」と気付いて設計を戻した。
少なくとも最初に思いついた方法へそのまま突っ走るだけではなかった。
現在の計画
最終的にPhase 1では、
- 2Dモカが正常に表示される
- idleで呼吸・瞬き・微動する
- 左右へ移動できる
- walkモーションが動く
- talkへ切り替えられる
- 既存AIの口パク情報をそのまま使える
-
mokaCharacterAPIから外部制御できる - Debug UIでリグを調整できる
ところまで作る計画になった。
VRM版と旧2D版はまだ削除しない。
2D Puppetは第三の選択肢として追加するだけ。
失敗したら戻せる。
素材が完成する前でも、既存立ち絵を一枚のbodyとして表示し、腕や脚は仮の図形を使ってリグとアニメーション部分だけ先に開発できるようにする。
ここまでが、0xAlphaFreeが作った実装計画である。
で、0xAlphaFreeは使えそうなのか
ここまで書いておいてなんだが、
まだコードは一行も実装させていない。
今回やらせたのは、
既存コードを読む
↓
構造を理解する
↓
移行方法を考える
↓
実装計画を書く
↓
自分の計画をレビューする
↓
修正版をMarkdownにまとめる
まで。
なので、
「0xAlphaFreeはClaude並みにコーディングできる!」
などと言う段階では全くない。
現時点での印象を雑にまとめるなら、
| 項目 | 現時点の印象 |
|---|---|
| 既存コードの調査 | かなりできる |
| 要求の読み取り | 良好 |
| 既存設計の再利用 | 良好 |
| アーキテクチャ設計 | 思ったより良い |
| 細部の正確性 | 人間のレビューは欲しい |
| 未検証事項への自信 | ちょっとありすぎ |
| 自己レビュー | 意外と効く |
| 実装能力 | まだ不明 |
少なくとも、
「Claudeが落ちた。今日はもう個人開発終了!」
とする必要はなさそうだ。
「Claudeの代用品」じゃなくても十分役に立つかもしれない
今回使ってみて感じたのは、無料モデルに最初からClaudeと全く同じものを期待する必要はないのかもしれない、ということ。
「Claudeがいない間に、どこまで仕事を前へ進めておいてもらえるか」
くらいで考えると結構面白い。
例えば、
Claudeで方針を考える
↓
無料モデルにコードベースを調査させる
↓
設計案を書かせる
↓
無料モデル自身に批判的レビューさせる
↓
Claude復旧
↓
「おかえり。これレビューして」
でもいい。
能力差が多少あったとしても、その間に調査と設計が終わっていれば十分仕事は進んでいる。
そして何より、今回はタダである。
休日の個人開発としては大事なポイントだ。
もちろん今回はまだ設計段階。
本当の地獄はこれからである。
設計書を書くAIと、既存コードを壊さず実際に実装できるAIは別物だ。
次はこの計画を元にPhase 1を実際に作らせてみたい。
無料モデルだけで、スクショ右側のモカが「この見た目のまま」動き始めるのか。
意味不明なバグを生み出して休日が溶けるのか。
それともClaudeが復旧した瞬間、
「おかえり。ちょっとこいつが書いたコード見てくれ」
と全投げすることになるのか。
本記事はchatgptに書いてもらいました。claudeが落ちて暇なので。
