INDIE INDEX

Claude Code に、ゲームの重い処理をプロファイラで探させる頼み方【AIでゲーム開発】

公開 2026-09-25更新 2026-09-25Claude Code

Claude Code に Node.js のプロファイラでゲームの計算を調べさせると、星どうしの当たりを確かめる処理が、記録に入っていた時間 1750.74 ミリ秒のうち 1731.71 ミリ秒(98.9%)を占めていました。直す前と直したあとの計算の写しを自分でプロファイラ付きで走らせると、300 フレーム分の計算は 1860.55 ミリ秒から 432.79 ミリ秒になりました。星がまばらな条件では直す前と後の動きが最後まで一致し、星が 3000 個の条件では1フレーム目から星の位置がずれました。

このページの目次
  1. Claude Code に頼んだ文
  2. Claude Code にプロファイラで調べさせた文
  3. Claude Code が挙げた上位5つを、残ったファイルで確かめる
  4. 自己時間と合計時間の違い
  5. 自分でプロファイラ付きで走らせる
  6. 直したあとも同じ動きかを確かめる
  7. ゲームそのものが動くかを確かめる
  8. プロファイルのファイルを開いて読むときの決まり
  9. 情報源

Claude Code に頼んだ文

作業フォルダを1つ決め、Claude Code に次の文を1回だけ渡して、調べる元になる小さなゲームを作らせました。画面の下の自機を左右の矢印キーで動かし、上から落ちてくる星をよけるゲームです。星は1秒ごとに 50 個ずつ増え、最大 3000 個まで増えます。

この試しでは、重い処理のあるゲームにするため、星どうしの当たりを「すべての星の組み合わせを1組ずつ確かめる作り」にするよう、頼んだ文の中で求めています。星どうしの当たりの計算は、描画とは別のファイル logic.js にまとめるよう頼みました。

Claude Codeに星よけゲームを頼んだ文

作業フォルダは C:\games\my-game\ だけです。このフォルダの外は読まない・書かないでください。

ブラウザで動く小さなゲームを作ってください。追加のパッケージは入れないでください。
ゲームは game.htm で、画像のファイルは使わず四角と丸と色だけで描きます。画面の下の自機(四角)を左右の矢印キーで動かし、画面の上から落ちてくるたくさんの星(小さな丸)をよけます。星は最初 50 個で、1秒ごとに 50 個ずつ増え、最大 3000 個まで増えます。星どうしがぶつかると、はね返るようにしてください。自機が星に当たるとゲームオーバーで、よけ続けた秒数を画面に出します。
星どうしの当たりは、すべての星の組み合わせを1組ずつ確かめる作りにしてください。
星の動き・星どうしの当たり・自機との当たりの計算は、描画とは別のファイル logic.js にまとめ、game.htm はそれを読み込んで使ってください。Node.js からも logic.js を読み込めるようにしてください。
作り終えたら、どのファイルに何を書いたかを、ふつうの言葉で説明してください。

※ このページの枠の中の作業フォルダの道は、例の道(C:\games\ の下)に置き換えて載せています。ほかの文字はそのままです。

Claude Code は game.htm と logic.js の2つのファイルを作りました。logic.js を読むと、星どうしの当たりは、1つ目の星より後ろにいるすべての星と1組ずつ比べる二重の繰り返しになっていました。星が 3000 個のときに1フレームで比べる組は、3000×2999÷2=4498500 組です。計算を描画と別のファイルに分ける形は、Claude Code に、ゲームのテストを書かせてバグを減らす頼み方でも使っています。

Claude Code にプロファイラで調べさせた文

Node.js のプロファイラは、ほかの部分より多く CPU を使っているコードの部分を探すときに使います。続けて、同じ作業フォルダで、Node.js に最初から入っているプロファイラを使って、どの処理に時間がかかっているかを調べさせる文を1回だけ渡しました。直す前と直したあとの結果を並べて見せることも頼んでいます。

Claude Codeにプロファイラで重い処理を調べさせた文

作業フォルダは C:\games\my-game\ だけです。このフォルダの外は読まない・書かないでください。

このゲームは、星が増えると動きが重くなります。どの処理に時間がかかっているかを、プロファイラで調べてください。追加のパッケージは入れず、Node.js に最初から入っているプロファイラ(`--cpu-prof`)を使ってください。
調べるときは、logic.js を読み込んで、星が 3000 個のときの1フレーム分の計算を 300 回くり返すスクリプト bench.js を作り、それをプロファイラ付きで走らせてください。
出てきたプロファイルのファイルを読んで、時間のかかっている処理を上から5つ、それぞれの時間と全体に対する割合とともに、ふつうの言葉で説明してください。
そのうえで、いちばん時間のかかっている処理を、ゲームの動きを変えずに軽くしてください。直す前と直したあとで同じ bench.js をプロファイラ付きで走らせ、結果を並べて見せてください。
プロファイルのファイルは profiles という名前のフォルダに、直す前(before)と直したあと(after)で分けて残してください。

※ このページの枠の中の作業フォルダの道は、例の道(C:\games\ の下)に置き換えて載せています。ほかの文字はそのままです。

Claude Code は、bench.js・プロファイルのファイルを読むための analyze-profile.js・直す前と直したあとの2つのプロファイルのファイル(拡張子 .cpuprofile)を作り、logic.js の星どうしの当たりの処理を書き換えました。game.htm は変えていません。

Claude Code の説明では、直し方は次のとおりです。画面を格子に区切って星を振り分け、自分のマスと周りの8マスにいる星とだけ比べる形にしました(Claude Code が logic.js に書いた注釈では、1マスは 12 ピクセル四方です)。星が当たるのは2つの半径の合計(最大 12 ピクセル)より近いときだけなので、外した組はもともと当たらない組です。当たったときの式は1行も変えていません。星が密集しているときは、同じフレームの中で押し戻す順番がわずかに変わることがあります。

Claude Code は、直す前と直したあとで挙動が変わっていないかを確かめたとも書いていますが、この説明は Claude Code 自身の説明で、動いた証拠ではありません。このあとの節は、残ったファイルを自分で読み、自分で走らせて確かめた記録です。

Claude Code が挙げた上位5つを、残ったファイルで確かめる

Claude Code の返事にある数と、フォルダに残ったプロファイルのファイルから出る数を比べました。Claude Code が作った analyze-profile.js とは別に、プロファイルのファイルを読む短いスクリプトを自分で書き、どちらでも読みました。時間は、1つの見本を取ってから次の見本を取るまでの時間を、その見本で動いていた処理に足し上げて数えています(analyze-profile.js と同じ数え方です)。

直す前のプロファイルのファイルに記録されていた時間は、合わせて 1750.74 ミリ秒でした。自己時間の大きい順に5つを並べると、次のとおりです。

順 処理(ふつうの言葉で) logic.js の行 自己時間 1750.74 ミリ秒に対する割合
1 星どうしの当たりを確かめる処理 158 行目 1731.71 ミリ秒 98.9%
2 自機と星の当たりを確かめる処理 211 行目 4.86 ミリ秒 0.3%
3 星を動かす処理 129 行目 3.76 ミリ秒 0.2%
4 1フレーム分をまとめて進める処理 251 行目 2.61 ミリ秒 0.1%
5 Node.js 本体の読み込み (logic.js の外) 1.59 ミリ秒 0.1%

1位から4位の時間と割合は、Claude Code の返事と同じ数でした。5位について、Claude Code は Node.js 自体の読み込みやごみ集めなどをまとめて「1.5〜1.6ms(各0.1%)」と書いていて、ファイルでは 1.46〜1.59 ミリ秒の4つの行でした。

直したあとのプロファイルのファイルでは、Claude Code の返事の数と、ファイルから出る数が違いました。返事の中の星どうしの当たりの処理の数は「396.01ms・90.6%」です。フォルダに残っていたファイルを読むと、記録されていた時間は合わせて 437.77 ミリ秒で、星どうしの当たりの処理の自己時間は 384.46 ミリ秒(437.77 ミリ秒に対して 87.8%)でした。analyze-profile.js で読んでも同じ 384.46 ミリ秒(87.8%)で、396.01 ミリ秒という数はどちらの読み方からも出ませんでした。

返事の中の「直す前 1743.94ms」「直した後 430.34ms」のような合計の時間は、bench.js が画面に出した数で、プロファイルのファイルには入っていません。これらの数は、この試しでは確かめていません。

自己時間と合計時間の違い

Chrome DevTools の Performance パネルの表では、Self Time(自己時間)はその処理そのものに直接かかった時間で、Total Time(合計時間)はその処理と、その処理から呼ばれた処理にかかった時間を合わせたものです。Bottom-Up のタブは、どの処理が直接いちばん時間を使ったかを合計して見せ、Call Tree のタブは、いちばん上の処理から、呼び出しの関係のとおりに入れ子にして見せます。

同じ直す前のプロファイルのファイルで、合計時間も数えました。

処理(ふつうの言葉で) 自己時間 合計時間
1フレーム分をまとめて進める処理 2.61 ミリ秒(0.1%) 1743.36 ミリ秒(99.6%)
星どうしの当たりを確かめる処理 1731.71 ミリ秒(98.9%) 1732.13 ミリ秒(98.9%)

割合は、どちらも記録されていた時間 1750.74 ミリ秒に対するものです。1フレーム分をまとめて進める処理は、自己時間は 2.61 ミリ秒でしたが、星を動かす処理や当たりの処理をこの処理から呼んでいるので、合計時間は 1743.36 ミリ秒でした。このファイルを合計時間の大きい順に並べると、呼び出しの元になる処理が上に来て、自己時間の大きい順に並べると、時間を直接使っている星どうしの当たりの処理が1位に来ました。

自分でプロファイラ付きで走らせる

直す前の logic.js(2回目の頼みの前に写しておいたもの)と、直したあとの logic.js を、それぞれ Claude Code が作った bench.js と一緒に別のフォルダへ写し、Node.js v24.18.0 でプロファイラ付きで走らせました。bench.js は、種を決めた乱数で星 3000 個の状態を作り、1フレーム分の計算を 300 回くり返すスクリプトです。直す前の写しで打ったコマンドと、bench.js が出した結果は次のとおりです。

$ node --cpu-prof --cpu-prof-dir=prof --cpu-prof-name=mine-before.cpuprofile bench.js
stars: 3000
frames: 300
elapsedMs: 1860.55
avgMsPerFrame: 6.202

プロファイラなしでも、それぞれ1回ずつ走らせました。

bench.js が出した 300 フレームの時間 1フレームあたり
直す前(プロファイラ付き) 1860.55 ミリ秒 6.202 ミリ秒
直したあと(プロファイラ付き) 432.79 ミリ秒 1.443 ミリ秒
直す前(プロファイラなし) 1750.10 ミリ秒 5.834 ミリ秒
直したあと(プロファイラなし) 429.94 ミリ秒 1.433 ミリ秒

自分で走らせて出たプロファイルのファイルを、同じ自分のスクリプトで読みました。

記録されていた時間 星どうしの当たりの処理の自己時間 同じ処理の合計時間
直す前 1868.36 ミリ秒 1832.94 ミリ秒(98.1%) 1853.98 ミリ秒(99.2%)
直したあと 440.4 ミリ秒 370.89 ミリ秒(84.2%) 382.31 ミリ秒(86.8%)

割合は、それぞれの行の「記録されていた時間」に対するものです。直す前も直したあとも、自己時間のいちばん大きい処理は星どうしの当たりの処理でした。

自分で走らせた直す前のファイルでは、2つの星が当たったときにはね返す式の処理が、別の行として 21.05 ミリ秒(1.1%)で出ました。Claude Code が残した直す前のファイルでは、この処理は別の行として出ていません。同じ bench.js と同じ logic.js でも、Claude Code が走らせたファイルと自分で走らせたファイルとでは、どの処理が別の行として出るかと時間が違いました。直したあとの自分のファイルでは、格子の中で比べる星を番号の順に並べ替える処理が 11.43 ミリ秒(2.6%)あり、直す前には無かった処理として出ました。

直したあとも同じ動きかを確かめる

Claude Code の説明では、ゲームの動きを変えずに軽くしました。これを確かめるため、直す前と直したあとの logic.js に、同じ種の乱数と同じ入力を渡して1フレームずつ進め、フレームごとに星の数、すべての星の位置と速さ、自機の位置、自機に星が当たったかを比べました。

条件 比べたフレーム 結果
ゲームを始めたときと同じ(星 50 個から、1秒ごとに 50 個ずつ増える)。自機を右・止まる・左と動かす 351 フレーム(両方ともここでゲームオーバー) 351 フレームのすべてで、星の数・すべての星の位置と速さ・自機の位置・当たったかが一致。どちらも 351 フレーム目にゲームオーバーになり、星は 300 個だった
bench.js と同じ(星 3000 個、自機は動かさない) 300 フレーム 星の数(3000 個)と自機の位置はすべてのフレームで一致。1フレーム目で 27 個の星の位置か速さが違い(位置の差は最大 5.45 ピクセル)、300 フレーム目には 3000 個すべてが違った。自機に星が当たったフレームは、直す前が 80、直したあとが 89 で、300 フレームのうち 9 フレームで違った

星がまばらな条件では、直す前と直したあとの動きは最後まで一致しました。星が 3000 個の条件では、1フレーム目から星の位置がずれ、自機に当たったかも一部のフレームで違いました。直したあとの 3000 個の星の位置と速さに、数でない値(無限大など)は1つもありませんでした。この比べ方で見たのは上の2つの条件だけで、ほかの種や、星が 50 個から 3000 個まで増えていく途中の条件は比べていません。

ゲームそのものが動くかを確かめる

直したあとの logic.js を読み込む game.htm を、画面を持たない Chrome で開き、矢印キーを送りました。ゲームの中の値は外から直接は読めない作りだったので、画面の上の生存時間と星の数の表示、ゲームオーバーの枠が出ているか、canvas の自機の行に描かれた自機の色(青、当たると赤)の位置を読みました。時刻は、開いた直後に読んだ時点からの差です。

したこと 記録に出たこと
開いて 0.3 秒待つ 星の数 50、自機は横 210〜269(画面の横幅 480 の中央)
右矢印キーを1秒押し続ける(100 ミリ秒おきに読む) 1059 ミリ秒の読み取りで横 419〜477、1167 ミリ秒からキーを離したあとの 1604 ミリ秒までの読み取りはすべて横 420〜479(画面の右端)
続けて左矢印キーを1秒押し続ける 1695 ミリ秒の横 420〜479 から、2673 ミリ秒の読み取りで横 106〜164 まで動いた
キーを押さずに待つ(200 ミリ秒おきに読む) 4581 ミリ秒の読み取りで、ゲームオーバーの枠が出て、よけ続けた時間が 4.6 秒と出た。自機の色は赤で、位置は横 74〜132

キーを離した直後の 2892 ミリ秒の読み取りでは、自機は横 74〜132 にいて、そこからゲームオーバーまで同じ位置でした。星の数の表示は、329 ミリ秒の読み取りで 50、1059 ミリ秒で 100、2020 ミリ秒で 150、3108 ミリ秒で 200、4163 ミリ秒で 250 に変わりました(読み取りは 100〜200 ミリ秒おきで、変わった瞬間そのものではありません)。ゲームオーバーの枠が出たあと、さらに2秒のあいだ 200 ミリ秒おきに 10 回読むと、生存時間は 4.6 秒、星の数は 250 のままでした。この試しのあいだ、コンソールに出たエラー・警告・例外は0件でした。

星よけゲームを開いた直後の画面。上に星の数50、下の中央に青い自機の四角がある

右矢印キーを1秒押し続けたあとの画面。星の数が100になり、青い自機の四角が画面の右端にある

星に当たったあとの画面。中央にゲームオーバーの枠とよけ続けた時間4.6秒が出て、自機の四角が赤くなっている

この試しは星が 250 個になったところでゲームオーバーになり、星が 3000 個まで増えた画面、星どうしがはね返る様子、ブラウザでの動きの速さ、直す前の logic.js を読み込んだ game.htm の動きは確かめていません。自機と星が当たるかどうかの基本の考え方は、AI に移動と当たり判定を作らせる頼み方と、動かないときの直し方にあります。

プロファイルのファイルを開いて読むときの決まり

Node.js をプロファイラ付きで起動すると、起動のときに V8 の CPU プロファイラが動き、終わる前にプロファイルがファイルに書き出されます。上の節のコマンドでは、置き場所(prof のフォルダ)とファイル名を指定しています。置き場所を指定しないと、ファイルは今いるフォルダに置かれます。ファイル名を指定しないと、ファイル名は日付・時刻・プロセスの番号などを並べた名前になり、拡張子は .cpuprofile です。見本を取る間隔もマイクロ秒で指定でき、指定しないときは 1000 マイクロ秒です。プロファイラ付きで起動する一連の指定は、Node.js v22.4.0 と v20.16.0 で安定版の扱いになりました。

Chrome DevTools の Performance パネルは、.cpuprofile のファイルを読み込めます。Performance パネルの Bottom-Up と Call Tree のタブの表には、Self Time と Total Time の列があります。Call Tree のタブでは、列を押すとその列で並べ替えられます。Node.js を DevTools とつなぐ指定を付けて起動し、DevTools の Performance パネルの記録のボタンを2回押して、動いている間を記録することもできます。この試しでは、DevTools の画面でファイルを開くところは試していません。

Claude Code は、作業のあとで走らせて結果を読める確かめ(テスト、ビルドの終了コード、出力を見比べるスクリプトなど)があると、作業・確かめ・結果の読み取りをくり返します。Claude Code に「成功した」と言わせる代わりに、走らせたコマンドとその結果のような証拠を見せるよう頼むこともできます。この試しで直す前と直したあとの結果を並べて見せるよう頼んだのも、この形です。

情報源

Claude Code のほかのページ

このページに出た言葉