Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when building a 2D web game with Phaser (3.x/4.x) or PixiJS 8 in TypeScript - framework vs renderer, Phaser scenes/game objects/arcade physics/groups as pools/scale manager/loader, scene shutdown cleanup, PixiJS 8 async init, Assets bundles, ticker units and destroy, and keeping rules in plain TS modules.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Phaser is a game framework: scenes, game objects, input, physics, audio, tweens, a loader and a scale manager. PixiJS is a fast 2D renderer: display objects, textures and a ticker — scenes, physics, input mapping and audio are yours to add. Pick by what the repository already uses; never put both in one game.
Core principle: The engine draws and dispatches; rules live in plain TypeScript modules with no engine import, so Vitest can run them (web-game-performance-and-testing).
// main.ts
new Phaser.Game({
type: Phaser.AUTO,
parent: "game",
backgroundColor: "#101018",
scale: { mode: Phaser.Scale.FIT, autoCenter: Phaser.Scale.CENTER_BOTH, width: 1280, height: 720 },
physics: { default: "arcade", arcade: { gravity: { x: 0, y: 900 }, debug: false } },
scene: [BootScene, PreloadScene, GameScene, HudScene],
});
// GameScene.ts — the scene wires engine objects to plain rules
export class GameScene extends Phaser.Scene {
private player!: Player;
private bullets!: Phaser.Physics.Arcade.Group;
private rules!: CombatRules; // plain TS, no Phaser import
constructor() { super("Game"); }
create(data: { seed: number }): void {
this.rules = new CombatRules(definitions.combat, mulberry32(data.seed ?? Date.now()));
this.player = new Player(this, 200, 500);
this.bullets = this.physics.add.group({ classType: Bullet, maxSize: 64, runChildUpdate: true });
this.physics.add.overlap(this.bullets, this.enemies, (b, e) => this.onHit(b as Bullet, e as Enemy));
this.scene.launch("Hud"); // HUD as a parallel scene listening to events
this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => this.cleanup());
}
update(_time: number, deltaMs: number): void {
this.rules.tick(deltaMs / 1000); // Phaser's delta is milliseconds
this.player.applyIntent(this.input.keyboard!, deltaMs / 1000);
}
private fire(x: number, y: number): void {
const b = this.bullets.get(x, y) as Bullet | null; // reuse from the pool; null when maxSize reached
b?.launch(600);
}
private cleanup(): void {
this.game.events.off("settings-changed", this.applySettings, this);
}
}
scene.launch) talking through events, not object references.Phaser.GameObjects.Sprite / Phaser.Physics.Arcade.Sprite, added with scene.add.existing(this) and scene.physics.add.existing(this).maxSize, get(), and on release setActive(false).setVisible(false) plus disabling the body (group.killAndHide(obj), body.enable = false). Never new + destroy per shot.arcade.fps, default 60); move bodies with velocity/acceleration, not by setting x/y each frame. Matter physics for real shapes and constraints, at higher cost.this.game.events, the registry, or DOM/window must be removed on SHUTDOWN; listeners on the scene's own emitter die with it. Restarting a scene that leaked listeners doubles every handler.this.load.atlas(key, png, json)), audio with format alternatives (this.load.audio("hit", ["hit.ogg", "hit.m4a"])), a pack file for large asset lists.this.input.keyboard!.addKeys({ jump: "SPACE", left: "A", right: "D" })); pointer and touch through the same action layer; gamepads with input: { gamepad: true } in the config.const app = new Application();
await app.init({ resizeTo: window, background: "#101018", antialias: false }); // async in v8
document.getElementById("game")!.appendChild(app.canvas); // `canvas`, not `view`
await Assets.init({ manifest: "assets/manifest.json" });
const level = await Assets.loadBundle("level-1");
const world = new Container();
app.stage.addChild(world);
const hero = new Sprite(level.hero);
world.addChild(hero);
app.ticker.add((ticker) => {
const dt = ticker.deltaMS / 1000; // seconds; ticker.deltaTime is a frame-scaled factor (~1 at 60 FPS)
sim.step(dt);
hero.position.set(sim.hero.x, sim.hero.y);
});
app.init, app.canvas, the ticker callback receiving the Ticker, the chainable Graphics API (new Graphics().rect(0, 0, 10, 10).fill(0xff0000)), ParticleContainer holding lightweight Particles.Assets with bundles per level; unload a level's bundle when leaving it (Assets.unloadBundle).destroy({ children: true }) removes a subtree; pass texture: true only for textures nothing else shares.ParticleContainer for thousands of particles; cullable = true on off-screen-heavy scenes.strict; no any, no as casts to silence the compiler — type game object factories and event payloads.mulberry32(seed)), passed into rules; the seed comes from the URL in debug builds so tests and screenshots are reproducible.Text objects regenerate a texture on every change.pixelArt: true (Phaser) or antialias: false plus nearest scaling (Pixi), integer zoom, and positions rounded at render time.window.innerWidth inside rules.delta as seconds.game.events.Scene.update that Vitest cannot import without a canvas.app.view, synchronous new Application({...})) pasted into a v8 project.import Phaser or import { Sprite } from "pixi.js" in a file under the rules/logic folder.this.add.text updated every frame for a score counter.events.on on a global emitter and no matching off.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
日本語の概要は準備中です。原文の説明を表示しています。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
日本語の概要は準備中です。原文の説明を表示しています。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
日本語の概要は準備中です。原文の説明を表示しています。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
日本語の概要は準備中です。原文の説明を表示しています。
Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation
日本語の概要は準備中です。原文の説明を表示しています。