ゲームを公開する
Keiko は手助けなしでもどんなゲームでもプレイできます。仮想時計を進め、本物の入力イベントを送るだけです。ゲームを読み、調整値にアクセスするには、開発ビルドで window.__KEIKO__ を追加します。フックはすべて任意です。
if (import.meta.env.DEV) {
window.__KEIKO__ = {
state: () => ({ player: { x: player.x, y: player.y }, score }),
scene: () => currentScene,
params: () => ({ player: { speed: tuning.speed, gravity: tuning.gravity } }),
setParam: (group, key, value) => {
if (group === "player") tuning[key] = value;
},
command: (name, ...args) => {
if (name === "warp") return loadLevel(args[0]);
},
};
}型が欲しければ、そのファイルに import type {} from "keiko"; を追加します。ビルドからは消えます。
ステート
state() はテストが game.state として読む値を返します。小さく、JSON にしやすく保ってください。数値、文字列、真偽値、配列、プレーンなオブジェクトです。プレイヤーには違いがわからない値は丸めておく(Math.round(x))と、浮動小数点の誤差でテストが壊れません。
state: () => ({
player: { x: Math.round(player.x), y: Math.round(player.y), onGround: player.onGround },
enemies: enemies.map((e) => ({ kind: e.kind, hp: e.hp })),
score,
}),シーン
scene() はアクティブなシーンや画面の名前を返し、game.scene として読めます。ready や「ゲームオーバーになった」といったアサーションに便利です。
const game = await play({ ready: (g) => g.scene === "level-1" });パラメータ
パラメータはあなたが調整する数値です。速度、重力、タイミングなど。公開しておくと、テストから設定したり(game.set、play({ params }))、スイープしたり(test.sweep)できます。
params: () => ({ player: { ...tuning } }),
setParam: (group, key, value) => {
if (group !== "player" || !(key in tuning)) throw new Error(`Unknown param ${group}.${key}`);
tuning[key] = value;
},未知のパラメータで例外を投げておけば、テスト内のタイプミスに気づけます。
コマンド
コマンドを使うと、テストは先回りできます。レベルにワープする、アイテムを渡す、状況をお膳立てする。テスト専用のショートカットは、ゲームの通常のコードパスではなくここにまとめましょう。
command: (name, ...args) => {
switch (name) {
case "warp": return loadLevel(String(args[0]));
case "give": return inventory.add(String(args[0]));
default: throw new Error(`Unknown command ${name}`);
}
},独自の固定ステップを持つエンジン
デフォルトでは、テストの 1 ステップは仮想時計の 1 フレームで、あなたの requestAnimationFrame ループが実行されます。エンジンに直接呼べる決定的な固定ステップの update があるなら、それを公開すると、ステップは直接そこへ送られます。
step: (n) => {
for (let i = 0; i < n; i++) world.update(1 / 60);
},
stepSeconds: 1 / 60,タイマーはステップごとに引き続き進みます。
入力
入力はデフォルトで DOM イベントとして届きます。ゲームが別の方法で入力を読む場合(仮想コントローラー、ネットワーク経由など)は、直接受け取れます。
press: (code) => controller.down(code),
release: (code) => controller.up(code),
pointerDown: (x, y) => cursor.press(x, y),
pointerMove: (x, y) => cursor.move(x, y),
pointerUp: () => cursor.release(),debuff のゲーム
debuff のゲームに __KEIKO__ は要りません。Keiko は debuff の開発ツールを通してゲームを動かすので、ステートはシーンの inspect()、パラメータとコマンドは debuff のものになります。debuff のレシピを見てください。