- Skill ID
- chongdashu/phaserjs-tinyswords/phaser-gamedev
- Publisher
- chongdashu
- Repository
- phaserjs-tinyswords
- Installs
- 0
- Files
- 5
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
chongdashu/phaserjs-tinyswords/phaser-gamedevInstalls these files- SKILL.md
- references/arcade-physics.md
- references/performance.md
- references/spritesheets-nineslice.md
- references/tilemaps.md
What this skill tells the agent
Phaser Game Development
Build fast, polished 2D browser games using Phaser 3's scene-based architecture and physics systems.
Philosophy: Games as Living Systems
Games are not static UIs—they are dynamic systems where entities interact, state evolves, and player input drives everything. Before writing code, think architecturally.
Before building, ask:
- What scenes does this game need? (Boot, Menu, Game, Pause, GameOver)
- What entities exist and how do they interact?
- What state must persist across scenes?
- What physics model fits? (Arcade for speed, Matter for realism)
- What input methods will players use?
Core principles:
- Scene-First Architecture: Structure games around scenes, not global state
- Composition Over Inheritance: Build entities from game objects and components
- Physics-Aware Design: Choose physics system before coding collisions
- Asset Pipeline Discipline: Preload everything, reference by key
- Frame-Rate Independence: Use delta time, not frame counting
Game Configuration
Every Phaser game starts with a configuration object.
Minimal Configuration
const config = {
type: Phaser.AUTO, // WebGL with Canvas fallback
width: 800,
height: 600,
scene: [BootScene, GameScene]
};
const game = new Phaser.Game(config);Full Configuration Pattern
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: 'game-container', // DOM element ID
backgroundColor: '#2d2d2d',
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH
},
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false // Enable during development
}
},
scene: [BootScene, MenuScene, GameScene, GameOverScene]
};Physics System Choice
| System | Use When |
|---|---|
| Arcade | Platformers, shooters, most 2D games. Fast, simple AABB collisions |
| Matter | Physics puzzles, ragdolls, realistic collisions. Slower, more accurate |
| None | Menu scenes, visual novels, card games |
Scene Architecture
Scenes are the fundamental organizational unit. Each scene has a lifecycle.
Scene Lifecycle Methods
class GameScene extends Phaser.Scene {
constructor() {
super('GameScene'); // Scene key for reference
}
init(data) {
// Called first. Receive data from previous scene
this.level = data.level || 1;
}
preload() {
// Load assets. Runs before create()
this.load.image('player', 'assets/player.png');
this.load.spritesheet('enemy', 'assets/enemy.png', {
frameWidth: 32, frameHeight: 32
});
}
create() {
// Set up game objects, physics, input
this.player = this.physics.add.sprite(100, 100, 'player');
this.cursors = this.input.keyboard.createCursorKeys();
}
update(time, delta) {
// Game loop. Called every frame
// delta = milliseconds since last frame
this.player.x += this.speed * (delta / 1000);
}
}Scene Transitions
// Start a new scene (stops current)
this.scene.start('GameOverScene', { score: this.score });
// Launch scene in parallel (both run)
this.scene.launch('UIScene');
// Pause/resume scenes
this.scene.pause('GameScene');
this.scene.resume('GameScene');
// Stop a scene
this.scene.stop('UIScene');Recommended Scene Structure
scenes/
├── BootScene.js # Asset loading, progress bar
├── MenuScene.js # Title screen, options
├── GameScene.js # Main gameplay
├── UIScene.js # HUD overlay (launched parallel)
├── PauseScene.js # Pause menu overlay
└── GameOverScene.js # End screen, restart optionGame Objects
Everything visible in Phaser is a Game Object.
Common Game Objects
// Images (static)
this.add.image(400, 300, 'background');
// Sprites (can animate, physics-enabled)
const player = this.add.sprite(100, 100, 'player');
// Text
const score = this.add.text(16, 16, 'Score: 0', {
fontSize: '32px',
fill: '#fff'
});
// Graphics (draw shapes)
const graphics = this.add.graphics();
graphics.fillStyle(0xff0000);
graphics.fillRect(100, 100, 50, 50);
// Containers (group objects)
const container = this.add.container(400, 300, [sprite1, sprite2]);
// Tilemaps
const map = this.make.tilemap({ key: 'level1' });Sprite Creation Patterns
// Basic sprite
const sprite = this.add.sprite(x, y, 'textureKey');
// Sprite with physics body
const sprite = this.physics.add.sprite(x, y, 'textureKey');
// From spritesheet frame
const sprite = this.add.sprite(x, y, 'sheet', frameIndex);
// From atlas
const sprite = this.add.sprite(x, y, 'atlas', 'frameName');Physics Systems
Arcade Physics (Recommended Default)
Fast, simple physics for most 2D games.
// Enable physics on sprite
this.physics.add.sprite(x, y, 'player');
// Or add physics to existing sprite
this.physics.add.existing(sprite);
// Configure body
sprite.body.setVelocity(200, 0);
sprite.body.setBounce(0.5);
sprite.body.setCollideWorldBounds(true);
sprite.body.setGravityY(300);
// Collision detection
this.physics.add.collider(player, platforms);
this.physics.add.overlap(player, coins, collectCoin, null, this);
function collectCoin(player, coin) {
coin.disableBody(true, true); // Remove from physics and hide
this.score += 10;
}Physics Groups
// Static group (platforms, walls)
const platforms = this.physics.add.staticGroup();
platforms.create(400, 568, 'ground').setScale(2).refreshBody();
// Dynamic group (enemies, bullets)
const enemies = this.physics.add.group({
key: 'enemy',
repeat: 5,
setXY: { x: 100, y: 0, stepX: 70 }
});
enemies.children.iterate(enemy => {
enemy.setBounce(Phaser.Math.FloatBetween(0.4, 0.8));
});Matter Physics
For realistic physics simulations.
// Config
physics: {
default: 'matter',
matter: {
gravity: { y: 1 },
debug: true
}
}
// Create bodies
const ball = this.matter.add.circle(400, 100, 25);
const box = this.matter.add.rectangle(400, 400, 100, 50, { isStatic: true });
// Sprite with Matter body
const player = this.matter.add.sprite(100, 100, 'player');
player.setFriction(0.005);
player.setBounce(0.9);Input Handling
Keyboard Input
// Cursor keys
this.cursors = this.input.keyboard.createCursorKeys();
// In update()
if (this.cursors.left.isDown) {
player.setVelocityX(-160);
} else if (this.cursors.right.isDown) {
player.setVelocityX(160);
}
if (this.cursors.up.isDown && player.body.touching.down) {
player.setVelocityY(-330); // Jump
}
// Custom keys
this.spaceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
// Key events
this.input.keyboard.on('keydown-SPACE', () => {
this.fire();
});Pointer/Mouse Input
// Click/tap
this.input.on('pointerdown', (pointer) => {
console.log(pointer.x, pointer.y);
});
// Make object interactive
sprite.setInteractive();
sprite.on('pointerdown', () => {
sprite.setTint(0xff0000);
});
sprite.on('pointerup', () => {
sprite.clearTint();
});
// Drag
this.input.setDraggable(sprite);
this.input.on('drag', (pointer, obj, dragX, dragY) => {
obj.x = dragX;
obj.y = dragY;
});Animations
Creating Animations
// In create() - define once
this.anims.create({
key: 'walk',
frames: this.anims.generateFrameNumbers('player', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1 // Loop forever
});
this.anims.create({
key: 'jump',
frames: [{ key: 'player', frame: 4 }],
frameRate: 20
});
// From atlas
this.anims.create({
key: 'explode',
frames: this.anims.generateFrameNames('atlas', {
prefix: 'explosion_',
start: 1,
end: 8,
zeroPad: 2
}),
frameRate: 16,
hideOnComplete: true
});Playing Animations
Use this skill in a project
Open any RiverX project, search the Skills panel for chongdashu/phaserjs-tinyswords/phaser-gamedev, and install it in one click.
