本文へスキップ

スパンとエンジン ​

Myaku はゲームループを外側から見ています。フレームコールバック、canvas コンテキスト、そしてブラウザが報告する内容です。ループの中で物理、AI、描画の順に動いていることまでは知りません。それを教えるのがスパンです。

ts
import { myaku } from "myaku";

const profiler = myaku();

function update(dt: number) {
  profiler.span("physics", () => world.step(dt));
  profiler.span("ai", () => enemies.think(dt));
}

コールバックをまたぐ処理には begin を使います。

ts
const end = profiler.begin("pathfinding");
await findPath(start, goal);
end();

スパンは各フレーム(frame.spans)、判定("Spans: physics 22 ms, ai 6.0 ms")、レポート(フレームあたりの平均ミリ秒)に表示されます。Myaku が保持するスパン名は最大 16 個です。

エンジンのスパンは自動で ​

Myaku はエンジン自身のループに update と render のスパンを最初から追加するので、遅いフレームでゲームロジックと描画のどちらが時間を食ったかがわかります。

エンジン方法スパン
PixiJS 8自動。Pixi の devtools フック経由update(ティッカーのリスナー)、render
three.js自動。three の devtools フック経由render
Phaser 3、または script タグで読み込んだ Phaser自動。グローバルの Phaser 経由update、update:<scene key>、render
Excalibur自動。Excalibur の devtools グローバル経由update、render
KAPLAYデフォルトのグローバルなら自動。global: false なら adapt(profiler, k)update、render
Phaser 4(ES モジュール)、またはそのほかadapt(profiler, game)Phaser 3 と同じ
debuffdebuff devupdate、render

Phaser 4 の ES モジュールビルドにはグローバルがないので、ゲームを渡します。

ts
import { adapt, myaku } from "myaku";

const game = new Phaser.Game(config);
adapt(myaku(), game);

スパンは入れ子にできます。update:level は update の一部です。エンジンのスパンは myaku({ engines: false }) でオフにできます。

さらに深く見たいときは、その中に自分のスパンを追加してください。

エンジン別ガイド:Phaser · PixiJS · three.js

Phaser で自分のスパンを使う ​

ループは Phaser が持っているので、シーンの update をラップします。

ts
class Level extends Phaser.Scene {
  update(time: number, delta: number) {
    profiler.span("level", () => this.tick(delta));
  }
}

PixiJS で自分のスパンを使う ​

ティッカーのコールバックを 1 つずつラップします。

ts
app.ticker.add((ticker) => profiler.span("game", () => game.update(ticker.deltaMS)));

three.js で自分のスパンを使う ​

ts
renderer.setAnimationLoop(() => {
  profiler.span("update", () => update());
  profiler.span("render", () => renderer.render(scene, camera));
});