
Phaser
Load Phaser games efficiently with texture atlases, atlas-based animations, and pooled physics groups.
Install
npx skills add https://github.com/opusgamelabs/game-creator --skill phaserWhat is this skill?
- Prefer texture atlases (JSON Hash) over per-image loads to cut draw calls
- Documents TexturePacker and free-tex-packer export workflow
- Atlas frame animations via generateFrameNames with prefix/start/end/zeroPad
- Physics Groups with maxSize for spawn/recycle coin-style entities
- TypeScript examples for preload, anims.create, getFirstDead pooling
Adoption & trust: 622 installs on skills.sh; 185 GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Game Enginegithub/awesome-copilot
Godot Gdscript Patternswshobson/agents
Unity Ecs Patternswshobson/agents
Game Developerjeffallan/claude-skills
Game Developmentsickn33/antigravity-awesome-skills
Unity Developerrmyndharis/antigravity-skills
Journey fit
Common Questions / FAQ
Is Phaser safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Phaser
# Assets & Performance ## Texture Atlases Always pack sprites into atlases instead of loading individual images: ```typescript // Bad: individual images (one draw call each) this.load.image('player', 'assets/player.png'); this.load.image('enemy', 'assets/enemy.png'); this.load.image('coin', 'assets/coin.png'); // Good: single atlas (one draw call for all) this.load.atlas('sprites', 'assets/atlases/sprites.png', 'assets/atlases/sprites.json'); ``` Create atlases with TexturePacker or free-tex-packer. Export as **JSON Hash** format. ```typescript // Using atlas frames this.add.image(100, 100, 'sprites', 'player-idle'); this.add.sprite(200, 200, 'sprites', 'enemy-walk-01'); ``` ## Atlas Animations ```typescript // In Preloader or Boot scene this.anims.create({ key: 'player-walk', frames: this.anims.generateFrameNames('sprites', { prefix: 'player-walk-', start: 1, end: 8, zeroPad: 2, }), frameRate: 12, repeat: -1, }); ``` ## Object Pooling Use Groups for anything created/destroyed frequently: ```typescript const coins = this.physics.add.group({ classType: Coin, maxSize: 20, runChildUpdate: true, }); // Spawn function spawnCoin(x: number, y: number) { const coin = coins.getFirstDead(false) as Coin | null; if (coin) { coin.activate(x, y); } } // Return to pool function collectCoin(coin: Coin) { coin.setActive(false); coin.setVisible(false); coin.body!.enable = false; } ``` ## Update Loop Optimization ```typescript // Bad: iterating all children update() { this.enemies.getChildren().forEach(enemy => { (enemy as Enemy).update(); }); } // Good: only update active children update() { this.enemies.getChildren() .filter(e => e.active) .forEach(enemy => (enemy as Enemy).update()); } // Best: use runChildUpdate on the group and let Phaser handle it // (automatically skips inactive children) ``` ## Camera Culling For large worlds, objects off-screen still render by default. Phaser automatically culls objects outside camera bounds for most game objects, but ensure it's working: ```typescript // Set world bounds larger than camera this.physics.world.setBounds(0, 0, 3200, 600); this.cameras.main.setBounds(0, 0, 3200, 600); this.cameras.main.startFollow(this.player, true, 0.1, 0.1); ``` ## Audio Best Practices - Load `.ogg` with `.mp3` fallback: `this.load.audio('sfx', ['sfx.ogg', 'sfx.mp3'])` - Use `this.sound.play('sfx', { volume: 0.5 })` for one-shots - Use `this.sound.add('bgm', { loop: true })` for music - Audio won't play until user interacts with the page (browser policy). Phaser handles this with its audio unlock system. ## BitmapText for Performance `Phaser.GameObjects.Text` creates a canvas texture per instance. For frequently updated text (score, timers), use BitmapText: ```typescript // In preload this.load.bitmapFont('pixelfont', 'assets/fonts/pixel.png', 'assets/fonts/pixel.xml'); // In create const score = this.add.bitmapText(16, 16, 'pixelfont', 'Score: 0', 24); ``` ## Mobile Optimization (Primary Target) Mobile is the primary deployment target. Design for mobile first, then verify desktop. - Target 30fps if needed: `fps: { target: 30, forceSetTimeOut: true }` in game config - Reduce particle counts by 50-75% - Use simpler physics bodies (circles over polygons) - Minimize texture swaps — pack everything into fewer atlases - Use `Phaser.Scale.FIT` with `autoCenter` for responsive sizing - **Touch target sizes**: All interactive elements (buttons, game objects the player taps) must be at least **44x44px** on screen. Smaller targets frustrate mobile players. - Test on real devices, not just browser DevTools throttling ## Memory Management - Remove event listeners in `shutdown()`: ```typescript this.events.on('shutdown', () => { this.game.events.off('custom-event', this.handler, this); this.registry.events.off('changedata-score', this.onScore, this); });