本文へスキップ

Myaku のご紹介 ​

Web ゲームの開発者なら誰でも知っている瞬間があります。ゲームを遊んでいると、カクッとする。ほんの一瞬止まって、拍が飛んで、また滑らかに戻る。DevTools を開いて記録を始め、1分ほど遊んでみても、もう起きない。あるいは起きたとしても、目の前には1万本のバーが並ぶフレームチャート。どれが原因だったのか、途方に暮れる。

ほとんどのヒッチは、説明されないまま終わります。「ブラウザのせい」や遅いマシンのせいにされ、プレイヤーはそれと付き合い続けます。

Myaku(脈)は、それに対する私たちの答えです。ページではなく、ゲームのために作られたフレームプロファイラーです。

ts
import "myaku/auto";

エントリファイルの先頭にこの1行を書くだけで、ゲームの隅に小さなフレームグラフが現れます。赤いスパイクがヒッチです。ホバーするとグラフが止まり、スパイクをクリックすると、Myaku が何が起きたかを教えてくれます。

フレーム 1,204 は 79 ms かかりました(予算 9.1 ms)。うち 80 ms はスクリプト:src/enemies.ts:88 の spawnWave。 これはゲームループの中で実行されました。Performance パネルでこの関数をプロファイルするか、処理を複数のフレームに分散させてください。

フレームチャートではなく、判定を ​

Myaku はプロファイルを読み解くことを求めません。遅いフレームのひとつひとつに判定を出します。原因、その確信度、そして試すべきこと。原因は、実際にゲームをカクつかせるものばかりです。

  • あなたのスクリプト。ブラウザが報告してくれれば、関数名とファイルまで特定します。
  • ガベージコレクション:コードが何もしていないのに、ヒープが数メガバイト減っています。
  • GPU へのアップロード:プレイ中に作られたテクスチャやバッファを、バイト単位で数えます。
  • シェーダーのコンパイル:エフェクトを初めて使ったときに起きます。
  • レイアウト:canvas の上に重ねた DOM の UI が、毎フレーム再計算されています。
  • ブラウザ自身:隠れたタブや、覆われたウィンドウがスロットリングされています。

そして何も説明がつかないときは、当て推量をせず、低い確信度でそう伝えます。

常にオン ​

開始しないといけないプロファイラーは、ヒッチを見逃すプロファイラーです。Myaku は直近10秒のフレームを常に保持しています。カクつきを感じたときには、もう記録されていて、オーバーレイに表示されています。

これはプロファイラーが軽くないと成り立ちません。Myaku は固定サイズの型付き配列にフレームを記録するので、フレームごとのメモリ確保がなく、自分が探しているガベージコレクションを自分で引き起こすこともありません。自身のコストも測って報告します。私たちのテスト用ゲームでは、1フレームあたり約 0.05 ms でした。

どのエンジンでも ​

Myaku はゲームを外側から見守ります。requestAnimationFrame、canvas のコンテキスト、そしてブラウザが報告するもの。なので Phaser、PixiJS、three.js、KAPLAY、Excalibur、自分で書いたループ、そして debuff で、ゲームに手を入れることなく動きます。

Phaser の Runner サンプルで試しました。ある関数を1フレームだけ 80 ms 忙しくさせたところ、Myaku はその関数を名指ししました。1フレームで 2048×2048 のテクスチャを4枚作ったところ、GPU に 64 MB アップロードされたと「high」の確信度で報告しました。ブラウザのウィンドウをほかのウィンドウの後ろに隠したところ、秒間2フレームをゲームのせいにするのではなく、ブラウザがスロットリングしていると伝えてきました。

エンジンがループを握っている場合、遅いコールバックはエンジンのステップ関数になるので、原因としてはエンジンのファイルが挙がります。スパンを使えば、その中を覗けます。

ts
profiler.span("physics", () => world.step(dt));

これで判定は「Spans: physics 22 ms, render 6.0 ms」のようになり、レポートには各システムの1フレームあたりの平均コストが表示されます。

ツールとエージェントのために ​

Myaku が知っていることは、すべてただの JSON です。profiler.report() は、フレーム時間のパーセンタイル(平均はカクつきを隠すので p50、p95、p99)、1分あたりのヒッチ回数、原因、説明つきの最悪のヒッチ、そしてスパンを返します。window.__MYAKU__ として公開されているので、スクリプトでのプレイスルーのあとに Playwright から読めます。

debuff のプロジェクトでは、debuff dev が Myaku を自動で起動し、ゲームの update と render をスパンにします。コーディングエージェントは MCP サーバーの game_profile ツールからこれを使え、explain-stutter プロンプトが判定からコードまでエージェントを案内します。

もっと大きなアイデアの一部 ​

Myaku は、ロジックテストのフレームワークである Keiko に続く、debuff プロジェクトから生まれた2つ目の独立したツールです。どちらも同じルールに従っています。Web ゲームのスタックにある本当の問題をひとつ、きちんと解決する。どのエンジンでも動く。debuff に依存せず、それでいて debuff とは深く統合する。

Myaku をはじめる →