Welcome, agents.
src/is the JavaScript source code. Edit files here, not generated output. Searchsrc/rather than the whole repo, because searching the repo also hitsbuild/,docs/, andnode_modules, which are full of generated duplicates.build/contains generated bundles (phaser.js,phaser.min.js,custom/). Do not hand-edit them. Regenerate with Grunt.dist/is for temporary generated bundles and is untracked.typescript/holds the TypeScript declaration files.phaser.d.ts,p2.d.ts,pixi.d.ts,pixi.comments.d.ts,box2d.d.ts, andphaser_box2d.d.tsare hand-maintained.phaser.comments.d.tsandpixi.comments.d.tsare generated at release for authors.filters/holds shader filter scripts.resources/docstrap-master/templateis the JSDoc HTML template used by thedocstask (tasks/jsdoc-conf.json).resources/jsdoc Export JSON/templateis the JSDoc JSON export template used by thejsdocJSON task (tasks/jsdocexportjson-conf.json).tasks/holds Grunt task configuration and helpers (tasks/options/,tasks/manifests/,tasks/jsdoc-plugins/).scripts/holds the shell scripts used bynpm testand build verification.docs/holds generated JSDoc HTML. Do not hand-edit.src/pixi/is a fork of Pixi v2 with its own manifests andIntro.js/Outro.js. It has diverged from upstream, so do not rely on current Pixi docs for it.src/stubs/holds the replacements used when an optional module is excluded from a custom build (see the*.stub.jsonmanifests intasks/manifests/).
npm cinpm run gruntruns the default task, which isbuild.- The
buildtask compiles all Phaser variants into the temporarydist/folder. - The
disttask compiles all variants and copies them intobuild/. - Custom builds:
npm run grunt -- custom --exclude=p2,tilemaps,retrofont. Run without--excludeto list the optional modules. - Other custom build flags:
--filename,--sourcemap true,--split true,--uglify true,--verbose true. - Doc tasks:
docs(JSDoc HTML) andtsdocs(TypeScript docs).
npm testrunstest-src(ESLint onsrc/) and thentest-ts(TypeScript definition checks).npm run test-srcrunseslint src.npm run test-tsrunsscripts/test-ts.sh, which compiles the.d.tsfiles withtsc --noImplicitAny.npm run test-buildrunsscripts/test-build.sh, which checks syntax ofbuild/*.jsandbuild/custom/*.jswithnode --check.- There are no unit tests. Verify runtime behavior by loading a build in a browser.
- Do not claim runtime behavior (rendering, physics, input) is verified unless you ran it in a browser. State what you did not verify.
- CI (
.github/workflows/nodejs.yml) only runsnpm ci && npm test. It does not validatebuild/or runtime behavior. - While iterating, run
npx eslint <file>. Runnpm testonce at the end, since it also compiles the type definitions. - Do not run the
disttask just to verify a change. It overwrites tracked files inbuild/. Usenpm run build-testinstead.
Prefer these signals over fixed sleeps, and keep an overall timeout as a backstop. The examples assume the page exposes the game as window.game. Register listeners before the event can fire (e.g. in the page's own bootstrap), since signals do not replay.
-
Wait for a state to finish creating, then for the next rendered frame, before a screenshot:
await page.evaluate(() => new Promise((resolve) => { const rendered = () => game.onPostRender.addOnce(resolve); if (game.state.current === 'Menu' && game.state.created) { rendered(); return; } const onCreated = (key) => { if (key === 'Menu') { game.state.onStateCreated.remove(onCreated); rendered(); } }; game.state.onStateCreated.add(onCreated); }));
-
Capture the canvas without
preserveDrawingBufferby reading it insideonPostRender:const png = await page.evaluate(() => new Promise((resolve) => game.onPostRender.addOnce(() => resolve(game.canvas.toDataURL('image/png')))));
-
onPostRenderis not dispatched whengame.lockRenderis true or the renderer isPhaser.HEADLESS. -
Detect WebGL context loss with
game.onContextLostandgame.onContextRestored.
Follow .eslintrc.json and .editorconfig. Key rules:
- ECMAScript 5 syntax only (
parserOptions.ecmaVersion: 5). Do not uselet,const, arrow functions, classes, template strings, or modules insrc/. - Allman brace style: opening braces go on their own line, for functions, classes, and blocks alike.
- 4-space indentation, LF line endings, UTF-8, final newline, no trailing whitespace.
- No trailing commas.
- Always use braces with
if,for, andwhile(curlyrule). - Use
===and!==(eqeqeq). - Prefer
forloops overforEach. - Array literal brackets have inner spacing:
[ a, b ]. - Object and block spacing follows the existing code. Match the surrounding file.
- Keep the
compat/compatlint rule in mind. Browser features need polyfills listed in.eslintrc.jsonor guards. camelcaseis a warning. Existing code uses some snake_case from external APIs. Do not add new violations.- Multiline comments must use
/* */. - Do not reformat or lint-fix vendored code.
.eslintignoreexcludessrc/animation/creature,src/physics/p2,src/physics/ninja,src/plugins, and theIntro.js/Outro.jswrappers.
- Each module is wrapped by the
Intro.jsandOutro.jsUMD wrappers and assembled by Grunt. Do not add a top-levelPhaserglobal elsewhere. - Use the existing namespace and prototype patterns (
Phaser.Foo = function (...) {},Phaser.Foo.prototype = ...). Match the file you are editing. - Keep public API changes in sync with the TypeScript definitions in
typescript/phaser.d.tsandtypescript/pixi.d.ts. - Keep JSDoc comments on public members. They feed the generated docs and
phaser.comments.d.ts. Imitate the tag style (@property,@method,@memberof, etc.) of the current file or a neighbor. - New files in
src/must be added to the matching JSON intasks/manifests/(for examplegameobjects.jsonorpixi-main.json). Otherwise they are not bundled, and nothing warns you. - For optional modules (
color,create,debug,dom,scale,sound,tilesprite,tweens), check whether the matching stub insrc/stubs/needs the same change. - Hot paths (render loops,
update, the sprite batches) are allocation-sensitive. Avoid creating arrays, objects, or closures per frame, and avoidforEachorbindthere. Phaserobjects extendPIXIobjects. When changing shared display or renderer code insrc/pixi/, check both the Canvas and WebGL paths.- Do not "fix" odd-looking code in the
src/pixi/renderers without a browser reproduction. Some of it is intentional, such as the batch size thresholds. - Add a
CHANGELOG.mdentry for user-visible changes. Add## Unreleasedfor in-development changes if it's absent. - Do not change the version in
package.jsonorbower.jsonunless asked. Runnpm run check-versionto compare version strings acrosssrc/Phaser.js,build/phaser.js,package.json,CHANGELOG.md, andREADME.md.
- Read the relevant file in
src/and its neighbors before editing. - Before choosing any browser API, check the lowest declared browser support in
package.json(browserslist: currently IE 9 and Android 4.4) and note our polyfills in.eslintrc.json. Use only features available there, or add a polyfill or guard. - Make the smallest change that solves the problem. Avoid unrelated reformatting.
- Run
npx eslint src/path.js(one file) ornpm run test-src(all) and fix any lint errors you introduced. - If you changed public API or types, edit
phaser.d.tsorpixi.d.tsto match the JavaScript source. TypeScript syntax must stay within version 1.4.1. Runnpm run test-ts. - If you need a runnable bundle, run
npm run build-testand usedist/phaser-test.js. - Do not edit
docs/,build/, ordist/by hand. - Do not delete or rewrite
tasks/manifests/ortasks/options/without understanding the build order they define. - Before finishing, check that
git statusshows no changes underbuild/ordocs/. A stray build or docs run is easy to commit by accident. - Do not commit, push, or tag unless asked. Releases are handled by maintainers.
- Editing generated files in
build/,docs/, ordist/. - Introducing ES6+ syntax into
src/. - Adding dependencies to
package.jsonwithout a clear need. - Changing
overridesinpackage.jsonwithout checking the reason. - Using newer TypeScript syntax in
typescript/*.d.ts. Stay within 1.4.1: noreadonly,unknown, orimport type.