筆者はZwiftという仮想世界に入り浸っています。Zwiftというのは、自転車(とランナー)が、共通の3D世界の中で走る有料サービス。月額2400円と高額ですが、友人やまったく知らない人たちと同じ道を走れる楽しさは格別なものです。
ただ、走れるのは運営会社が作ったコースだけ。新しいコースは年に1回あるかどうかで、また同じ道かよ、と思うことがたまにあります。知らない街を走ってみたい……と永六輔みたいな気持ちになります。
ならば、常に新しい道を走れるようなプログラムはできないか。最近急激に性能を上げているAIプログラマーならできるのでは? そう考えてやってみました。
できたのがこちらのプログラムです。タイトルは「無限に広がる3D地形探索」。AIが勝手に名付けました。
これは1個のHTMLファイルで、ブラウザだけで動作しています。実際に室内バイク(自転車)で漕いでいるペダリングを反映させたスピードで3D地形の上を進むようにできています。
プログラミングには自分の手は一切入れず(というか、まったくできないので)、AIがコードを書いています。
AIプログラミングではこれまで、シンセサイザーやビジュアライザーなどを作って、それなりに実用的に使えるものもできるようになりましたが、3Dの領域は未経験。
いや、コーディングそのものもまったくやっていないのですけど。

▲音声に合わせてシャボン玉が噴出するビジュアライザー
今回やる気になったきっかけはGPT 4.5の登場です。せっかく毎月200ドル(3万円超)を払っているので、元を取らなくてはと、新モデルの実力試しのため、前からやろうと考えていたアイデアをぶつけてみました。
リアルな3Dの樹木や地形が自動生成され、その地形の中をASDWキーで自由に進んでいけるプログラムを書いて
このプロンプトをChatGPT 4.5に投げたのですが、最初はUnityで作れと言われ、ブラウザで出させたところ、画面が表示されないという結果に。

そこで同じプロンプトをリリースされたばかりのClaude 3.7 Sonnetに渡したら、こちらは一発で動くプログラムを出してきました。優秀すぎ。

Claudeは、Spaceを押すとジャンプする機能まで付けてくれました。気配り最高。マウス操作で視点も変えられます。これは行けるとばかりに改良を加えていきます。
樹木、雲のリアルさを上げ、最初に生成された領域以外にも自動的に拡張生成できるようにし、さらに、cキーを押すと、連続で走り続けるモードにトグルできるようになりました。
ここまでくれば、Zwiftでやっていたような、自分がその世界に入り込んで走っている気分になります。
しかし、機能を追加してコードが長くなってくると、Claudeは一度で生成しきれなくなり、アラートを出して止まってしまいます。
Continueの指示を出さないと完成できなくなり、最後には10回くらい続きを書かせて、「本日の生成はもうできません。XX時にまたきてね」と言われる始末。
実際のペダリングと連動できるように、ANT+という無線通信プロトコルに対応したケイデンスセンサーと接続し、その情報を取得できるように無理強いしたのが原因でしょうか。
ChatGPTに聞いたところ、
Claudeは、コンテキストの保持や一度に扱えるトークン数が多いことを特徴としている半面、1回の応答で出力できるコード量には厳しい制限をかけています。
これは、Anthropic(Claudeの開発元)がモデルの安全性や品質管理を重視しており、特に複雑な処理や長大なコードについては、1回のレスポンスでは部分的な提示に留めるようチューニングされているためです。
結果として、長いコードの生成や修正を依頼した際には「途中で途切れる」という挙動が頻繁に発生します。
ということで、長くなりすぎると、一度での処理はできなくなるようです。こうなると、再びChatGPTに戻るしかありません。
Claudeで分割出力されたものをテキストエディタでまとめて、それを元にコードを書き直させたのですが、これは省略しすぎて樹木がなくなってしまったりと、なかなかうまくいきません。
しかし、ChatGPTとやりとりするうちに、実際に自転車を漕ぐスピードを画面内に反映させるアイデアが浮かびました。

漕ぐサイクルを、例えば足がおりきったときのタイミングに合わせて、エンターキーを数回押すことで、ケイデンスを取得するというのは?
スピードはそのケイデンスにあわせて自動推定。ギアは1から9までを選択可能にする
という指示でできたPedalSimulatorプログラムをClaudeで作った3D地形探索プログラムに組み込むことで、動作しました。

なお、この部分はo3-mini-highを使っています。確実に完成させたかったので……。
その後の改良(速度や雲・樹木・丘陵の最適化)は、ChatGPTで続けています。
執筆時点でのプロジェクトは、こちらで共有していますので、使いたい方はHTMLをコピーして起動してみてください。ただし、メモリ喰らいのようなので、ご注意を。
https://chatgpt.com/share/67c2fa1b-88f4-8011-bf0b-85a50faf5119
次にやるとすれば、ペダルが一番下に来たときにEnterキーを自動で発信するデバイスの制作でしょうか。
これも、ChatGPTに聞いてみました。
ペダルに磁石を仕込んで、下に置いたデバイスからEnterキーを自動で送信できるようにするにはどうしたらいい?

これもなんかできそうです。
ChatGPT 4.5に聞いたところ、必要な部品、ステップバイステップの作り方まで教えてくれました。


わかりやすい。これは楽しみが増えました。
買い物は日本でも使えるようになったOperatorに頼めばいいかな?
試してみたところ、No Internetというエラー表示。

復活したら再度試してみます。次はAI IoTだ!
追記:はてブのコメントで、Web Bluetooth APIを使えばいいのではというアドバイスがあったので、ChatGPTに追加で聞いてみました。
Web Bluetooth API使えば、Fitness Bikeクラスのセンサーデータをブラウザから取得できるそうだけど、これを組み込んでみて
これに対する回答は、
以下は、Web Bluetooth API を用いて Fitness Bike センサー(ここではサンプルとして「cycling_power」サービスを利用)からデータを取得するコードを組み込んだ例です。
画面上部の操作パネルに「Fitness Bike接続」ボタンを追加し、ボタン押下で Bluetooth デバイスの接続を試み、センサーデータを受信するとペダルシミュレーターの仮想速度に反映する(簡易な例)ようにしています。
以下のコードは、既存の 3D 地形探索アプリケーションに Web Bluetooth のサンプル処理を追加した完全な例です。
(※実際のセンサーデータのフォーマットはデバイスに依存するため、ここでは最初の 2 バイトを cadence(rpm)として読み取り、仮想速度を更新するダミー処理としています。)
というもの。実際に所有するスマートトレーナーのTacx Flux-2(ロードバイクと接続してスピード、ケイデンス、パワーなどのセンサーデータを取得するデバイス)が接続できました。

個別のセンサーフォーマットがまだわからない(勉強しなければ)ためにとりあえずはここまでですが、こうしたデバイスを持っている人なら、さらなる改良が可能なようです。

高度を変えられるフライスルーモードも実装してあります。

追記:Tacx Flux-2対応もできました。
ChromeのConsoleのデータをChatGPTに送ってデバッグした結果、ちゃんと動くようになりました。
実際にTacx Flux-2で漕いでいるスピードが20.4km/hと表示され、自動生成された3D地形の中を進んでいます。これで完成と言っていいでしょう。

ポッドキャスト番組のbackspace.fmで西川善司さんと話しているときにこのプログラムを紹介したところ、いたく感動してくれました。そういえば、AIが勝手に実装してくれたLoD(Level of Detail)は善司さんから聞いた話ですし、ゲームグラフィックスの教科書も書かれています。
プログラミングはできなくても、そこに出てくるキーワードや実例をみていれば、ChatGPTやCluadeとやりとりするときの参考になるはず。改めて読み返してみたいと思います。