本文へスキップ

Keiko のご紹介 ​

ゲームのテストが難しいのは、ゲームが特別だからではありません。時間の上で動いているからです。ブラウザはゲームをリアルタイムで、そのマシンが出せるフレームレートで動かし、入力は好きなときにやってきます。同じテストを2回走らせれば、少しだけ違うゲームが2つできあがります。

だからほとんどの Web ゲームは、誰かが遊んでみる以外にはまったくテストされていません。ジャンプがちょっと低くなった、高速のダッシュで壁をすり抜ける、といったタイミングに潜むバグは、プレイヤーが見つけることになります。

Keiko(稽古)は、それに対する私たちの答えです。ブラウザなしで本物のゲームを Node 上で動かし、時間をテストの支配下に置くテストランナーです。

ts
import { expect, play, test } from "keiko";

test("the player reaches top speed within a quarter second", async () => {
  const game = await play();
  game.press("ArrowRight");
  expect(game.until((s) => s.player.vx >= 140)).toBeAtMost(15);
});
bash
npm install -D keiko
npx keiko

時間はテストのもの ​

Keiko はゲームの index.html をヘッドレスなページに読み込み、そのスクリプトを実行します。時間を伝えるものはすべて仮想です。requestAnimationFrame、setTimeout と setInterval、performance.now()、Date.now()。Math.random() にはシードが入ります。フレームが進むのは、テストがそれを求めたときだけです。

これでゲームは入力の決定的な関数になり、テストは厳密になります。10秒のプレイが一瞬で終わり、毎回同じ結果になります。

ゲームが本当に知りたいこと ​

ほとんどのテストランナーが与えてくれるのは expect(value).toBe(…) です。ゲームにはスナップショット以上のものが必要なので、Keiko にはプレイの展開を見守る方法が加わっています。

  • until は、何かにどれだけ時間がかかるかを測ります。最高速に達するまで、着地するまで。
  • during は、何かが一度も起きないことを確かめます。画面の外に出る、体力がマイナスになる。
  • trace は値を時間に沿って記録します。ジャンプの高さや速度のカーブに。
  • test.sweep は、出荷するかもしれないすべてのパラメータの値でテストを走らせます。
  • test.deterministic はスクリプトを異なる乱数シードで2回遊び、全フレームの差分を取ります。

何かが失敗すると、Keiko はその瞬間のゲームを見せてくれます。

text
fail tests/movement.test.ts › stops in speed ÷ acceleration [player.speed=300] 40 ms
  ExpectationError: expected 60 to be 0
  at tests/movement.test.ts:33:21
  game tick 42 (0.70s) · scene play
  state {"player":{"x":309,"vx":60},"pops":0,"particles":0}

どのエンジンでも ​

Keiko はエンジンの API を使いません。あらゆるWeb ゲームがすでに使っているプラットフォームを通じて動きます。フレーム、タイマー、DOM イベント、Canvas 2D と WebGL です。Keiko の中では、後者2つはどんな呼び出しも受け付けて何も描きません。Phaser、PixiJS、KAPLAY、Excalibur、three.js、そして手書きのループで動作を確認しました。どれも、テストから状態を読めるようにする1行が必要なだけです。

ts
if (import.meta.env.DEV) window.__KEIKO__ = { state: () => ({ player: { x: player.x, y: player.y }, score }) };

エンジン別レシピに、それぞれ動くゲームとテストがあります。

debuff で作られ、みんなのために ​

Keiko は 2D ブラウザゲームのための私たちのツールキット debuff の中で生まれ、debuff には深く統合されています。npx debuff test、コーディングエージェント向けの run_tests ツール、そしてすべての新規プロジェクトに入っているサンプルテスト。でも Keiko は debuff に依存しておらず、独立したツールとしてドキュメントも用意されています。Web ゲームを作っているなら、あなたのためのツールです。

コーディングエージェントとの相性は特に抜群です。操作すべきブラウザがなく、フィードバックは数ミリ秒で返り、失敗はスタックトレースではなくゲームの様子を説明します。エージェントはテストを書き、それが失敗するのを見て、ゲームを直し、修正を証明できます。

できないこと ​

Keiko は描画もサウンドの再生もしないので、見た目や音が正しいかどうかは教えてくれません。そのためには、本物のブラウザでのスクリーンショットテストをいくつか残しておきましょう。ゲームがすることの何百もの事柄には、Keiko を使ってください。

ドキュメントを読むか、さっそく始めましょう。