このほど、富士山麓河口湖にあるシェア別荘「SANU 2nd Home 河口湖 2nd」で開催されたAIハッカソンに参加してきました。
大学受験は国立大学の中で数学の配点が最も低いところを選び、それでも100点中20点しか取れなかったという、完全文系なわたくしがハッカソン?
AIハッカソンってどういうもの? そういう方には、ちょうど良い解説動画があるので、そちらをご参照ください。
ハッカソンとはマラソンのように長時間使ってプログラムを一気に書き上げて競うコンテストのこと。AIハッカソンはそこでAIを使うというわけ。
最初にお誘いを受けたときには取材側ということだったのですが、直前に参加者側に振り分けられ、「AIを活用したゲームを作れ」という課題に一泊二日で取り組んだのです。
最近でこそヴァイブコーディングを使っていろいろやっている記事を書いてますが、やってるのは自分の趣味を満足させるようなものばかりで、人様にプレイしてもらうようなものではございません。
そんな過酷な状況に置かれた筆者が、これまで作ってきたエージェンティックAIをベースに 、プログラムを作っていった経緯をここでまとめてみたいと思います。
なお、今回のハッカソン「Project DENT」は、宇宙に凹み(Dent)をつけるようなすげーものを作れよ、というスティーブ・ジョブズの言葉にインスパイアされたという、主催者である清水亮さんの発案。
彼の多彩な人脈から、本来ならばハッカソンの審査員に回るような方々がチームを構成する一方で、ゴールデン街のバーテンダーのみなさま、普通のOLといった多様性を重視しすぎたような集まりとなっています。
筆者がアサインされたのは、ゲームAIの権威である三宅陽一郎さん、Final Fantasy VIIの映像制作を担当した橋本和幸さんという、レジェンドチーム(高齢者チームということ?)。これなら僕は何もやらなくてもいいかな、くらいに思っていました。
他のチームにも、LLM無職を自称するナル先生(GOROman)と「どこでもいっしょ」開発者でありトロ父と呼ばれているビサイドの南治一徳さんによる「AIもいっしょ」チーム、「魔改造の夜」のSニーチームの方々、大阪万博で落合館を開発していたみなさん、そして技研ベースのレギュラーメンバーなど強者揃い。
そこに、月曜日・火曜日を費やして集まり、競い合ったというわけです。
河口湖AIハッカソンの事前準備
今回のハッカソンは、ゲームを開発するという目的は明かされていましたが、その詳細は謎のまま。ただ、レギュレーションは緩くて、持ち込むマシンに制限はなく、必要なガジェット、デバイスの持ち込みも可能。
筆者は楽器でも持ち込もうかと悩みましたが、結局Macを2台とAndroid端末、iPhoneそれぞれ1台という、まあごく普通のセットとなりました。
ただ、開発環境としては、2台のMac(128GBのメモリを搭載したM4 Max MacBook Proと、最低構成のMacBook Neo)のどちらにも、LLMやビジュアライザーなどを組み込んだ自作エージェンティックAIをインストールしてあり、それをベースにClaude Codeで拡張することはできるようにしてあります。
例えば、8GBのMacBook Neoに構築してあるエージェンティックAI「mazzaineo」にはFastAPI + vanilla Sで組んだサーバ、Ollama/mlx-lm/Apple FMといったローカルLLMバックエンド、HDemucsによる音源分離、SparkJSでレンダリング する3Dガウシアンスプラットのビジュアライザー。そこにMCPサーバを立てて、Claude Codeから全機能を呼び出せるように整えてあります。
対話しながら創作を進めるための環境は出来上がっていました。
ただ、主催者からハッカソンのテーマやレギュレーションが発表されるまで、それが使えるかどうかはわかりません。「Antigravityだけ使え」と言われる可能性だってあるわけで、その場合には全くのゼロからスタートしなければなりません。
最初のテーマ:90分でAIゲームを3つ作れ
最初に出されたテーマは、自然をテーマにしたAIゲームを作ること。90分の持ち時間でチームで最低3つ。多ければその分、加点されるという仕組みです。
筆者らのチーム「現実改竄機構」(橋本さんのChatGPTが提案して決定)は、3人それぞれ別個で作ることに自然と決まりました。橋本さんはヴァイブコーディング自体が初めてだそうで、環境のインストールからスタート。三宅さんは何やらロッジの外に出かけて何やらやっています。数分後には「できました」となんかすごいのを見せてくれます。
自律したAI生命体がぐにょぐにょ動いていて、それがノートPCのインカメラに映った草を食べるという奇想天外でありながらきちんとテーマに沿った内容。
「これ、俺は何もやらなくていいのでは」と思いながらも自分のプログラムに取り掛かります。ヴァイブコーディングでそれっぽいのを作ったことはあるけど、ちゃんと人がプレイできるものとなるとまた別ですからね。
幸いなことに、持参したMacBook Neoには、3DGS(Gaussian Splatting)を使ったビジュアライザーのプログラムが入っています。
3DGSを簡単に使うためのSparkJSというClaude Codeのスキルがインストールされているので、それをベースに作ればいいかと考え、その方向で進むことに。
ブラウザで動作し、その実行環境内でLLMなどのローカルAIを使う。その上で、人類の未来に変革を与えうる、自然をテーマに含むゲーム。これらが、自分にとっての制約条件となります。
MacBook Neo上に構築したエージェンティックAI「mazzaineo」の中でmkdir univコマンドを実行。宇宙という名前のディレクトリを作りました。
清水さんがぶち上げたProject DENTというのは、宇宙に凹み(Dent)を作ること。つまり、大きなテーマの枠としては宇宙ということにしておこう、というわけです。この時点で何を作るかはまだ考えていません。
そこでClaude Codeを実行。3DGSを使って、AI、自然を使うということで、言葉の部分はmazzaineoで使っているLLMをollamaで動かすことにして、そこにインタラクティブなゲーム性を持たせなければいけません。
自然をテーマにした3つのAIゲームその1:言葉で世界を塗り替える森
最初に思いついたテーマは「森」。AIが森になり、森が言葉で世界を塗り替えていく、というもの。
プレイヤーは原始的な生態系の観察者となり、ブラウザ内のローカルLLMが一匹ずつの生き物に固有の人格を与えます。生き物に触れると、生き物の方からプレイヤーに知恵を語りかけてきます。「AIを消費するのではなく、AIを介して自然と対話する」という体験そのものが、人とAI・人と自然の関係を再定義する思想的核になっています。
大まかなゲームの仕組みはこうなっています。
画面に4体の発光する生命体 (各1500個のスプラットの雲) が呼吸している

クリックすると、その生命体に内在する小さなLLMが詩のような言葉を語り始める

語られる一文字ごとに、その仮名/漢字の母音 (a/i/u/e/o) が音程に変換され、FM音源のベルの音色でメロディとして発声される
語の中に色彩語 (緑、苔、青、水、火、月など30語) が出現すると、生命体の色相が最短経路でその色に押し込まれる
複数の生命体が独立した位相で色相をドリフトさせ続け、視点はゆっくり森の周りを回転する
WebLLMの推論コストは生き物の数だけ並列推論することを許さないため、「無数の生き物が常時喋る」設計を諦め、「少数の生き物と深く対話する瞑想的テンポ」に絞りました。アクション性を捨てる代わりに、唯一無二の体験になるはず。
ollamaではなく、WebLLMで起動時に読み込むことをClaude Codeが勝手に選択してくれました。
LLMの応答は1~2文の極めて短いものに制限し、システムプロンプトで「個体名を持たない、感覚 (湿り、震え、匂い、温度、明滅) を語る、説明や前置きは禁止」と条件をつけました。MacBook Neoの8GBメモリで動作するLLMは言葉が不自由なので、そうした制限が生きてきます。
自然をテーマにした3つのAIゲームその2:12秒ごとに生まれては爆ぜる宇宙
ガウシアンスプラットでできた球体が息をするたび、AIが宇宙の名を授け、囁いた一語が次の宇宙の色になる、というコンセプト。ビッグバンと消滅を12秒のサイクルで繰り返す、というものです。
世界そのものが呼吸する1個のシステム。約6秒の吸気で、無数のスプラット粒子が流体場に従って収束し、ひとつの生態系が一瞬で結晶化する。続く6秒の呼気で、その生態系は花粉・霰・火の粉・プランクトンの光となって全方位に爆ぜる。LLMはこの呼吸ごとに「いま生まれた世界の名」を一語だけ授け、その語の母音が次の呼吸の旋律を、色彩語が次の世界のパレットを決定します。

アイデアとしては、「三体」の最終巻や「百億の昼と千億の夜」みたいな壮大な宇宙叙事詩を超短時間でプレイする、というものです。
操作なき採集ゲームといった感じで、3層構造でゲームが成立しています。
同調 (Sync):マイク入力でプレイヤー自身の呼吸の包絡線を取得し、世界の呼吸との位相同期度を計測する。同調率が高いほど画面の彩度・粒子密度・音響の解像度が上がる。「うまく息ができる」こと自体が報酬になる。
種付け (Seed):吸気のピーク (世界が結晶化する瞬間) に、プレイヤーはスペースキーを押して一語だけ囁く (キー入力)。LLMはその語と現在の世界状態から次の世界の名を返し、その語が次の宇宙の色・音・速度を決定する。
採集 (Archive):生まれた世界には固有の名前と座標 (色相×流体タイプ×音律) が付き、稀少なものは「息の図鑑」にlocalStorageで保存される。プレイヤーは過去の宇宙を再起動 (recall) することもできる。勝敗はなく、進行は図鑑の充実と1呼吸あたりの平均同期度で測る。
当初はマイク経由のASR (whisper-web等) も検討しましたが、音声認識の重さと体験の純粋さを天秤にかけ、最終的に「マイクは音量包絡のみ、種語はキー入力」という最軽量構成を選択。
粒子は1個の大きなSplatMesh (3万粒子) で構築し、その中を8個のSplatEdit SDFが流体場に従って動き回ることで、目まぐるしく変化する色彩を表現。GPUで全粒子を再計算することなく、SDFの位置と色を変えるだけでこの効果が得られます。
自然をテーマにした3つのAIゲームその3:架空の星に栄えた知的生命体の歴史
制限時間の90分内でもう1つ、ゲームを作りました。これも三体とか火の鳥未来編みたいな世界観。
プレイヤーは神でも歴史家でもなく、因果の入力者となります。ある架空の星に栄えた知的生命体の歴史を、プレイヤーが「因子」として投げ入れた一語が形作っていきます。LLMはその因子と文明の現状から1ページの古文書風叙述を綴り、5つの内部指標 (安定/知/調和/人口/環境) を更新。いずれかの指標が0に達すると文明は崩壊し、書き続けてきた全ページが灰となります。
ゲームシステムは次のとおり:
毎ターン、4枚の因子カード (火/文字/鉄/神話/疫病/移住/神/機械/忘却/詩/法/王 など計44種) から1枚を選ぶ

選んだ因子が5指標に確率的な影響 (各 [-7..+8] 程度) を与える
LLMが古文書風の1~2文を生成し、ページとして書き加えられる

•星 (2.2万スプラットの発光球) は5指標を色相・密度・脈動・輝きにマッピングして変化
いずれかの指標が0で崩壊 ── 星は四散し、ページは灰になる
最長で何ページ書き残せたかが記録 (localStorageに永続化)
LLMに全てを委ねると「面白いが運ゲー」、内部指標にルールベースの確率を併走させると「戦略性は出るが文脈が硬くなる」ということで、後者寄りを選択。各因子は5指標に対する基本影響テーブルを持ち、LLMはその範囲内で叙述を書く。プレイヤーは指標を見ながら戦略を練るが、物語の質感はAIに委ねます。
因子のカテゴリー (tech/culture/social/mystic/nature/calamity) を区別して、毎ターン異なるカテゴリーから引くことで選択肢に多様性を持たせています。さらに、いずれかの指標が25未満になると災厄カテゴリ (戦/疫病/飢/火山) の出現確率を下げ、崩壊のスパイラルを抑制。この辺は全てAIが考えています。
これもLLMにゲームシナリオを依存しているため、どのLLMを選択するかが重要となります。
最初に採用した Qwen2.5-0.5B-Instruct は、日本語の古文体ではしばしば文章として崩壊。Qwen2.5-3B-Instruct (約1.8GB、q4f16量子化) に切り替えたところ、文体の安定度・整合性が劇的に改善しました。3作品すべて同じモデルIDに統一したので、ブラウザのIndexedDBに1度だけ保存され、3作品で共有されました。
一語を投げ入れるだけで、AIがその語の重みを千年に翻訳する。崩壊すれば全てが灰になる、はかない年代記ができました。
3つのゲームに共通する仕様
3つの作品で共通するのは次の通りです。
ブラウザのみで完結 (サーバ不要)
LLMはWebLLM経由で完全ローカル実行 (プライバシーと思想の純度を保つ)
3D描画はSparkJSのガウシアンスプラットを主軸とし、生命的・流体的な質感を出す
音響はTone.jsで生成、外部音源を一切使わない
オブジェクトプーリングで毎フレームのGCを回避し、なめらかに動かす
ガウシアンスプラットの「柔らかく境界のない粒子的表現」は、明確な形を持たない原始生命・進化途中の生き物・霊的な森の気配を表現するのに最適でした。ポリゴンでは絶対に出せない "生命の揺らぎ" を表現できます。
3作品でのスプラット数の使い分けは、
森: 1500粒子 × 4体 = 6000粒子 (生命体ごとの個別性を強調)
息吹: 30000粒子 × 1個 + 8個のSplatEdit SDFが流体運動 (全体の動的変化を強調)
年代記: 22000粒子 × 1個 (惑星) + 内核SDF + ハローSDF (静的な威厳を強調)
LLMについては3作品はすべてでQwen2.5-3B-Instruct-q4f16_1-MLC を使用。同一originなので IndexedDB が共有され、最初に開いたページで1回だけDLされ、以降はどのページでも数秒で起動。これがあるからこそ、3つの作品をシームレスに行き来できます。
音響設計に関しては3作品とも Tone.js で完全合成。外部音源を不使用。共通する設計指針は:
常時鳴る低音ドローン/パッドサウンドが世界の呼吸を表現
出来事 (発話・種・ページ) はFM音源のベルサウンドやプラック(撥弦)で点として響く
リバーブとディレイを深くかけ、空間的な広がりを作る
崩壊や絶頂の瞬間にだけ「絶対無音」を挟む (年代記の崩壊シーンなど)
90分という限られた時間で形だけでも3作品を開発できたのは、これらの共通項があったからです、
反省点としては、単調すぎることと、リアルタイム性に欠けていること、最初のLLMローディングに1分近く時間を取られてしまうことなど。とりあえず、数だけは作ることができたのでよしとしました。
第2のミッションは、風船と買い物でゲームを作る
次なる課題は、非常に複雑です。各チームに風船が配られました。さらに、3000円を渡されて近所のスーパーに買い物に行き、それを加えた上でゲームを作る、というもの。
今回は数が勝負ではなく、チームで1つのゲームを完成させなければなりません。現実改竄機構ではな、まず風船をどう使うかで、議論が起きました。
風船を破裂させる、音を鳴らす、飛ばす、といった選択肢がある中、きちんとそうしたデータを取れるかどうかという現実的なところを考えると、画像認識して何かした方がいいという結論に。
そこで三宅さんが、複数の風船を画像認識して、それを一つの紐状の物体に見立てるプロトタイプを見せてくれました。この速さはさすがという感じです。
ではこれをどうするかということで、風船を紐で繋げて、龍にしてはどうかというアイデアが浮かびました。筆者の故郷である長崎の代表的な祭りである「おくんち」名物のじゃおどり(龍踊)がモチーフ。
龍踊では、先頭に金色の玉を持ち、それを龍が追いかけますが、それを風船で代用しようというものです。複数の風船が龍の関節となります。5回玉を食べると龍が昇天していく、というゲーム。


本物の龍踊を見たいという方は、ぜひ長崎くんちに行くか、東龍倶楽部という、東京を拠点にパフォーマンスをしているグループがあるので、そちらをご覧ください。筆者の母校である長崎東高等学校のOBが中心となって運営しています。
他のチームを含め、第2のミッションがどういうものだったかは、ガジェタッチによる収録動画でご覧ください。
最後の試練:AIゲームセンターに置ける複数プレイヤーゲーム
そして、このAIハッカソンもいよいよ大詰め。夕食後のまったりし後に、3つ目のミッションが発表されました。
最後のミッションは、AIゲーセンに置ける、複数プレイヤーが共同でできるAIインタラクティブゲーム。清水さんが立ち上げたクラウドファンディング「AIゲームセンター構想」のゲームセンターに置けるようなゲーム、ということです。実際にそこを訪れたプレイヤーが遊べるゲームを作る、というもの。
今回のミッションが発表されたのは酒も入ってしまった夜の10時過ぎ。すっかり疲れ切った状態ですが、これを翌日朝9時までに作り上げなければなりません。徹夜か? いや、体が持たないから一眠りしてからにするか……。一番若い三宅さんでも50代。橋本さんと筆者は共に60代という高齢チームにはきつい時間制限です。逆に1時間で、というのなら短期決戦できるのですが。
それでも始めました。今回は3人がそれぞれ独立してプログラムを組んでいきます。長時間、打ち合わせをしながら開発を続けるだけの余裕はないので、自分のペースで途中睡眠を挟みながらやっていきます。
宿泊したキャビンにはBBQができるところやキッチンも備えられているので、飲み食いしながらそれぞれ開発を進めていきます。橋本さんは持ち込んだSwitchコントローラーを使ったレースゲームを開発している様子。三宅さんは人工生命を使った何かをやっているようです。こちらでアドバイスするだけのものもないので、邪魔にならないように自分の開発をのんびりやっていきます。
筆者の持ち駒としては、最初に組んだ3つのプログラムと同じ。mazzaineoに組み込んでいたLLMとビジュアライザーを活かしたい。
ビジュアライザーでは、HDemucsで4パートのステム分離した音源に、4種のGaussian Splatクラウド(drums/bass/vocals/other)をリアクションさせ、SDFカーバーで雲を彫り、ボーカルのpitchでhueを回し、絵文字の歌詞を色付きsplat化するという仕組みでした。ボーカルのピッチで描画するというところは活かしたい、という発想。
これをベースに、カメラとマイクも入力として加えたいというアイデアです。ビジュアライザーが 、音源ファイルではなくその場にいる人間の声と顔に反応する。「視覚的な楽器」になるというもの。
まだ明確なゴールが決まらないまま、Claude Codeと対話しながら入力機能を追加していきました。
マイク入力: getUserMedia でストリームを取り、既存のstemSourcesに差し込む。ステム分割は複雑だから、声はvocalsに直結し、drums/bass/otherには薄くブロードキャスト
カメラ入力: MediaPipeのFaceLandmarkerをCDN経由で遅延ロード、478ランドマークから顔の幾何情報を抽出
Self-Portraitモード: 顔ランドマーク→8つのSDFカーバーに位置マッピングしてステム雲を顔型に彫り抜く(抽象レイヤー)+顔の内側をピクセルサンプリングしてSplatMeshとして毎フレーム再構築(具象レイヤー) という 試行錯誤のなかで、ランドマーク=Splatに一対一対応させるという方針に転換。
4000点の密サンプリングより、輪郭36点+目・口・眉36点+頬/額埋め30点の計110点だけをsplat化し、それぞれに対応する動画ピクセル1点から色を取る。これで毎フレーム軽く再構築でき、顔の構造そのものが音で幾何変形するようになりました。
顔が音に合わせて呼吸しながら泳ぐ、そういう自画像モードが完成しました。 自分の顔に、3DGSで顔のパーツがオーバーレイされて変形していくというもの。
でも、これでは対戦、協力プレイという条件を満たすことができません。
Voice Tug of War
そこで、単純に綱引きにしようと考えました。 お互いの顔splatを引き合う。顔綱引きです。
じゃあ何で対戦するかというと、最初は歌で引き合うつもりでした。しかし実際に組んでみると、歌声での綱引きは難易度が高すぎました。マイク入力の場合には左右のプレイヤーの違いを認識しなければならず、そのためのロジック実装は非常に難しいと感じたのです。
ここで設計方針を転換。シンプルに、
- 入力はキー連打にする(左=A/Q/Z、右=L/P/K/,)
- ただし顔の表情で威力が最大2.6倍に増幅される(目を見開く、口を歪める、ウインクする)
- 声・音はビジュアル反応に残す(音量で綱が波打つ、ピッチで色相が流れる)
綱引きの「綱」もsplatで作成。両者の顔中心を結ぶ80粒のGaussian Splatチェーンで、tug値(-1~+1)で色の境界(赤→青)が移動する。tug=0なら中央で半々、+0.8なら青がほぼ全域、すなわち「右の色が綱を呑み込みつつある」。ゲージだけでなく、音で綱全体が波打ち、優劣が一目でわかります。
表情ブーストの算出は、MediaPipeランドマークから幾何的に:
目の縦距離 / 顔高さ(見開き度)
唇間距離 / 顔高さ(口の開き度)
口角距離 / 顔幅(歪ませ度)
左右非対称度(ウインク)
これらの重み付き和が0~1のスコアになり、キー入力のimpulseを 1 + score × 1.6 倍する。結果、連打速度が同じでも叫ぶような顔をしている方が勝つゲームバランスが生まれました。

一発勝負を「長く遊べる」構造へ:ドラマスコア制
初期バージョンは「±0.85を2秒キープで勝ち」という単純な勝利条件でした。しかし短いプレイで一方的に勝つよりも、接戦を長く楽しんだ方が面白いはず。二人のプレイヤーがどちらも楽しめる、「勝利だけでない報酬」が欲しくなりました。
そこでドラマスコア制を導入:
毎フレーム、intensity^1.8 × closeness × layerBonus を累積
closenessは|tug|が0.5~0.85でピークになるカーブ、|tug|>0.95でブローアウトペナルティ(一方的な勝利は報われない)
60秒タイムアウトで強制集計
最終ランクはD~S、さらに特殊条件でS+とSSがある
報酬は音楽そのものにしました。高intensityを持続して蓄積した「ドラマタイム」が閾値を超えるごとに、新しい楽器レイヤーが解放されます。
6秒 :PAD(浮遊サスペンデッドコード)
14秒 :CLAP(2,4拍の三連ハンドクラップ)
24秒 :ARPEGGIO(Hungarian Minor・32分音符の16音/秒ランナー)
38秒:RIDE(9kHzハイパスのシマー + 5kHzベルトーン)
56秒:LEAD(sawオシレータ+5.5Hzビブラートのメロ)
アルペジオは特に凝りました。最初のスケールやテンポが気に入らなかったので、A Hungarian Minor(A, B, C, D#, E, F, G#)という、2つの増2度を持つ中央アジア/ジプシー調のスケールで、3小節96ステップの非反復パターン。レゾナントQ=6.0のローパスフィルターで金属的に鳴理、解放された瞬間、いきなりレーザーのような高速アルペジオが走り始めます。
音楽のレイヤーが重なり合って、より分厚いエレクトロサウンドになってきます。
さらにもう一段、両プレイヤーの協調レイヤーを設計しました。
赤(左)専用: TOM → SUB
青(右)専用: SHAKER → CHIMES
両者が自分のサイドレイヤーを解放すると、協調報酬として DUAL tier が発動 → COSMOS(LFO detune
driftする壮大な6声パッド)、さらに上で CHOIR(フォルマントフィルタによる「あー」という合唱)
DUAL tierに到達しないとSSランクは取れません。勝利だけを目指す一方的な展開では最高評価が得られず、双方が派手に盛り上がった長い戦いだけが真の勝者になるという構造ができました。
敗者は爆散し、勝者は金色に輝き、綱は磁力の波をうちます。
さらに、画面を派手にしていきます。Gaussian Splatだけだとどうしても映像的に地味になりつつあり、 ビート連動の顔変形: 音楽のkick/snare/chord beatに合わせて、目の位置が前方Zに飛び出して最大4.5倍に巨大化、口は上下に爆ぜて口角が左右に広がり、chordが鳴ると目がランダム方向に飛散。音と視覚が完全に同期するようになります。
ビート連動のDOMエフェクト:
衝撃波リング、マンガ的スピードライン、レイバースト、スクリーンシェイク、CSS filter経由の色相歪み、全画面フラッシュ
さらに「爆散感」を強めるため、回転しながらスパイラル軌道を描く多形状破片(三角・四角・菱形・星・円がそれぞれ-22~+22
rad/secで自転しつつ、発射点を中心に旋回しながら重力で落下)
火花は尾を引いてカーブする軌跡
といったものを追加しています。

勝利演出: 勝者決定の瞬間、敗者の顔ランドマークがランダム方向に飛散しながら透明になり、勝者は金色パルスで脈動、220粒の紙吹雪が放射状に噴き上がる。1.3秒後にこの瞬間を合成スクリーンショットとして保存します。

スクショ合成は少し工夫した。勝者の顔領域は本物の映像がくっきり見えるようにして、splatエフェクトは周辺だけに残す。勝者のsplatメッシュを一時非表示にして再レンダー、オフスクリーンキャンバスで放射状グラデによるdestination-inマスクを使って、勝者の素顔を中心に配置、フワッと周辺のsplat/紙吹雪/衝撃波に溶け込ませます。
プリンタ出力ができれば、プリクラのように印刷できます。AIゲームセンター向け。
LLM実況:AIが作品を「語る」
もうひと推し追加しました。ローカルLLMによる実況コメンタリー。
mazzaineoのサーバから、ポート8082で動いている Ternary Bonsai 8B(1.58-bit量子化モデル、mlx-lmで実行)に接続
/api/chat/simple エンドポイント経由で、ゲームイベント(開始・勝利)時に短いプロンプトを投げる
返ってきたテキストからthinkタグを除去し、最初の一文だけ抽出
ブラウザのSpeechSynthesisAPIで深い低音(pitch 0.65)、やや遅め(rate 0.92)の映画予告編ナレーター調で読み上げ
プロンプト例(勝利時):
The red player won a 2-player facial-expression tug-of-war after 42 seconds with rank S+ and drama score 68 (shared
layers 4 of 5, dual tier 1 of 2). Deliver a dramatic cinematic victory line, ONE sentence under 20 words.
Ternary Bonsai 8Bは1.58-bit量子化にも関わらず、こういう短文タスクには十分な文学性を発揮する。しかも8GB
MacBook Neo上で0.5秒前後でレスポンスが返る。
勝利の瞬間、オレンジ色の紙吹雪のなか、低い声で「Red stood defiant as the chaos bent to their will.」みたいな一文が流れる。ゲーム体験そのものが、一人のナレーターに見守られている物語になる。
……というはずだったのですが、翌朝9時のデモ時にはLLMが動作しなかったため、いったんオフにしました(執筆中には復活しました)。

デモモード:AIが二人分を自動プレイする
ハッカソン最終日の発表前、「デモのときに誰かが常にプレイしてないと見せられない」という問題が浮上しました。そこで最後にデモモードを実装。
開始画面にDEMOボタン(URL ?demo=1でも起動)
両サイドに独立したタップスケジューラ、基本間隔0.20秒(5tap/秒)
sin(t × 0.28)でレートを緩くオシレート → 11秒周期で優劣が自然に入れ替わる
合成表情スコアも動かすので、サイドレイヤー解放→DUAL→SSランク到達までを見せられる
勝利スナップ表示の6秒後に自動でPLAY AGAINをクリックしてループ
オートデモモードも作りさらには起動時のチュートリアル画面も作成。これを見て、ああこういうゲームだったのか、と理解(笑)

エージェンティックAIとゲームを開発
このペースで機能が雪だるま式に増えていけたのは、mazzaineoの下地と対話型の開発スタイルのおかげでした。
カメラ/マイク入力 → Self-Portrait → 2Pゲーム → 音楽生成 → LLM実況 → 自動デモ 、というそれぞれのステップは、前のステップの部品を使い回しています。コードベースは確実に重層化していきますが、対話しながら設計を固め、動くものをすぐ試し、そして「もっとこうしたい」を即座に反映させるサイクルが回り続けました。
一人でずっとやっていたら、たぶんTug of Warまで辿り着きませんでした。Self-Portraitで満足して終わっていたはずです。
「エージェンティックAIをベースに何か作る」というとき、AIを単なるツールではなく、自分のクリエイティブな相棒として使うのが、いちばん生産性が高いのだと思います。構想を口にした瞬間に試せる、という環境があると、発想の方が加速します。そうしたものを蓄積していくのが本来のプログラミングかどうかはよくわかりませんが、自分の場合にはうまくいった気がします。
それにしても、自分が作ったゲームをいろんな人にプレイしてもらい、フィードバックしてもらうだけでなく、楽しんでもらえたのは極上の体験でした。「もう一度やらせてもらっていいですか?」と言われた時の喜び。
常設AIゲームセンターができた際にはぜひ置いてもらえるように、さらにブラッシュアップしていきたいと考えています。
あ、結果的に使ったのはMacBook Neoだけでした。8GBのメモリがあれば動作するので、最近は5、6万円で中古が出回っているM1 MacBook Airでも動くはず。
AIゲームコーナーは、11月7日に開催が決まっている「AIフェスティバル 2026 Powered by THIRDWAVE」にも出展するそうです。ここで置いてもらえるとうれしいなあ。









