$npx -y skills add Yakoub-ai/phaser4-gamedev --skill phaser-buildThis skill should be used when the user asks to "build my game", "run my Phaser game", "start dev server", "deploy my game", "fix build errors", "configure Vite for Phaser", "game won't build", "TypeScript errors in Phaser", "publish to itch.io", or needs to compile, run, trouble
| 1 | # Phaser 4 Build and Deployment |
| 2 | |
| 3 | ## Development Server |
| 4 | |
| 5 | Start the dev server with hot reload: |
| 6 | |
| 7 | ```bash |
| 8 | npm run dev |
| 9 | ``` |
| 10 | |
| 11 | Opens at `http://localhost:5173` (Vite default). Changes auto-reload in the browser. |
| 12 | |
| 13 | ## Production Build |
| 14 | |
| 15 | ```bash |
| 16 | npm run build # Compiles TypeScript + bundles with Vite → dist/ |
| 17 | npm run preview # Serve the dist/ folder locally to test production build |
| 18 | ``` |
| 19 | |
| 20 | Output in `dist/` — static files ready for any web host. |
| 21 | |
| 22 | ## Diagnose the Project |
| 23 | |
| 24 | Run the validation script before building: |
| 25 | |
| 26 | ```bash |
| 27 | bash scripts/validate-project.sh |
| 28 | ``` |
| 29 | |
| 30 | The script checks for common issues automatically. |
| 31 | |
| 32 | ## TypeScript Type Checking |
| 33 | |
| 34 | ```bash |
| 35 | npx tsc --noEmit |
| 36 | ``` |
| 37 | |
| 38 | Fix all type errors before shipping. Common Phaser 4 TypeScript issues: |
| 39 | |
| 40 | **Missing Phaser types:** |
| 41 | ```json |
| 42 | // tsconfig.json — REQUIRED for Phaser 4 types to work |
| 43 | { |
| 44 | "compilerOptions": { |
| 45 | "typeRoots": ["./node_modules/phaser/types"], |
| 46 | "types": ["Phaser"] |
| 47 | } |
| 48 | } |
| 49 | ``` |
| 50 | |
| 51 | **`this.input.keyboard` nullable:** |
| 52 | ```typescript |
| 53 | // Wrong: |
| 54 | const cursors = this.input.keyboard.createCursorKeys(); |
| 55 | // Correct: |
| 56 | const cursors = this.input.keyboard!.createCursorKeys(); |
| 57 | ``` |
| 58 | |
| 59 | **`sprite.body` nullable:** |
| 60 | ```typescript |
| 61 | // Wrong: |
| 62 | sprite.body.velocity.x |
| 63 | // Correct: |
| 64 | (sprite.body as Phaser.Physics.Arcade.Body).velocity.x |
| 65 | // Or: |
| 66 | sprite.body?.velocity.x |
| 67 | ``` |
| 68 | |
| 69 | **`this.scene.get()` returns base Scene type:** |
| 70 | ```typescript |
| 71 | // Cast to specific scene class: |
| 72 | const game = this.scene.get('GameScene') as GameScene; |
| 73 | ``` |
| 74 | |
| 75 | ## Common Build Errors |
| 76 | |
| 77 | ### "Cannot find module 'phaser'" |
| 78 | |
| 79 | ```bash |
| 80 | npm install phaser@beta # NOT npm install phaser (that's Phaser 3) |
| 81 | ``` |
| 82 | |
| 83 | ### Asset 404 Errors (game loads but assets missing) |
| 84 | |
| 85 | In Vite, assets must be in the `public/` directory. They are served as-is at the root. |
| 86 | |
| 87 | ``` |
| 88 | ✅ public/assets/images/sky.png → loads as 'assets/images/sky.png' |
| 89 | ❌ src/assets/images/sky.png → won't work with this.load.image() |
| 90 | ``` |
| 91 | |
| 92 | Never import assets via ES imports for Phaser. Just reference the path string: |
| 93 | ```typescript |
| 94 | this.load.image('sky', 'assets/images/sky.png'); // ✅ |
| 95 | ``` |
| 96 | |
| 97 | ### "Phaser.Geom.Point is not a constructor" |
| 98 | |
| 99 | v3 → v4 breaking change. Replace with `Vector2`: |
| 100 | ```typescript |
| 101 | // Old (v3): |
| 102 | const pt = new Phaser.Geom.Point(x, y); |
| 103 | // New (v4): |
| 104 | const pt = new Phaser.Math.Vector2(x, y); |
| 105 | ``` |
| 106 | |
| 107 | ### "Math.PI2 is undefined" |
| 108 | |
| 109 | v3 → v4 breaking change: |
| 110 | ```typescript |
| 111 | // Old (v3): |
| 112 | const angle = Math.PI2; // was π (wrong!) in v3 |
| 113 | // New (v4): |
| 114 | const angle = Math.TAU; // π×2 |
| 115 | const half = Math.PI_OVER_2; // π/2 |
| 116 | ``` |
| 117 | |
| 118 | ### Black Screen on Launch |
| 119 | |
| 120 | 1. Check browser console for errors (F12) |
| 121 | 2. Check for 404s in Network tab (missing assets) |
| 122 | 3. Verify scene is in GameConfig's `scene: []` array |
| 123 | 4. Verify HTML has `<div id="game-container">` if using `parent: 'game-container'` |
| 124 | 5. Try removing `parent` config to append to document.body directly |
| 125 | |
| 126 | ### WebGL Context Lost |
| 127 | |
| 128 | ```typescript |
| 129 | // Try Canvas renderer as fallback |
| 130 | const config = { |
| 131 | type: Phaser.CANVAS, // instead of Phaser.AUTO or Phaser.WEBGL |
| 132 | // ... |
| 133 | }; |
| 134 | ``` |
| 135 | |
| 136 | Or add WebGL context loss recovery listener: |
| 137 | ```typescript |
| 138 | this.game.renderer.on('contextlost', () => { |
| 139 | console.warn('WebGL context lost — attempting recovery'); |
| 140 | }); |
| 141 | ``` |
| 142 | |
| 143 | ## Vite Configuration |
| 144 | |
| 145 | ```typescript |
| 146 | // vite.config.ts |
| 147 | import { defineConfig } from 'vite'; |
| 148 | |
| 149 | export default defineConfig({ |
| 150 | base: './', // IMPORTANT for itch.io and subdirectory deployment |
| 151 | build: { |
| 152 | outDir: 'dist', |
| 153 | assetsDir: 'assets', |
| 154 | minify: 'terser', |
| 155 | rollupOptions: { |
| 156 | output: { |
| 157 | manualChunks: { |
| 158 | phaser: ['phaser'], // Bundle Phaser separately for caching |
| 159 | }, |
| 160 | }, |
| 161 | }, |
| 162 | }, |
| 163 | server: { |
| 164 | port: 5173, |
| 165 | }, |
| 166 | }); |
| 167 | ``` |
| 168 | |
| 169 | **`base: './'` is critical** for itch.io, GitHub Pages, and any subdirectory deployment. Without it, assets load from `/` (root) which breaks on subdirectory hosts. |
| 170 | |
| 171 | ## Deployment Targets |
| 172 | |
| 173 | ### itch.io |
| 174 | |
| 175 | 1. `npm run build` |
| 176 | 2. Zip the `dist/` folder contents (not the folder itself — zip what's inside) |
| 177 | 3. Upload the zip to itch.io → "Upload files" → HTML game |
| 178 | 4. Set "This file will be played in the browser" |
| 179 | 5. Check "SharedArrayBuffer support" if needed |
| 180 | |
| 181 | ### GitHub Pages |
| 182 | |
| 183 | ```yaml |
| 184 | # .github/workflows/deploy.yml |
| 185 | name: Deploy to GitHub Pages |
| 186 | on: |
| 187 | push: |
| 188 | branches: [main] |
| 189 | jobs: |
| 190 | deploy: |
| 191 | runs-on: ubuntu-latest |
| 192 | steps: |
| 193 | - uses: actions/checkout@v3 |
| 194 | - uses: actions/setup-node@v3 |
| 195 | with: { node-version: '18' } |
| 196 | - run: npm ci |
| 197 | - run: npm run build |
| 198 | - uses: peaceiris/actions-gh-pages@v3 |
| 199 | with: |
| 200 | github_token: ${{ secrets.GITHUB_TOKEN }} |
| 201 | publish_dir: ./dist |
| 202 | ``` |
| 203 | |
| 204 | Set `base: '/repo-name/'` in vite.config.ts for |