Skip to content
Development
Skill

/phaser-arcade-physics

Use Phaser 4 Arcade Physics: enable the world, give sprites bodies, set velocity/acceleration/gravity, and resolve collisions with colliders, overlaps, groups, and world bounds. Use when a Phaser game needs movement or collisions — when the user mentions Arcade Physics,

From plugin
awesome-gamedev-agent-skills
6.3k77 skills

Claude Code

$ npx -y skills add gamedev-skills/awesome-gamedev-agent-skills --skill phaser-arcade-physics --agent claude-code

SKILL.md

phaser-arcade-physics.SKILL.md
name: phaser-arcade-physics
description: >
  Phaser 4 Arcade Physics movement and collision: bodies, velocity, gravity, colliders vs
  overlaps, groups and bullet pools. Use for a Phaser platformer or top-down controller, or a
  sprite that ignores physics, onFloor() always false or bodies passing through walls. Not for
  scenes and the loader (`phaser-core`), coyote time (`platformer`) or tunnelling theory
  (`physics-tuning`).

Phaser 4 Arcade Physics

Moves and collides sprites with Phaser's Arcade engine: axis-aligned rectangles and circles, no rotation in collision, no joints. That is enough for most platformers, shooters and top-down games, and it is fast. New projects target **Phaser 4.2**; check the installed major before editing an existing project. If the game needs hinges, springs, slopes or rotated polygons, Matter physics is the separate engine for that, and its bodies never collide with Arcade bodies.

When to use

  • Platformer or top-down movement, gravity, bouncing, world bounds, and collision or overlap

between sprites, groups and tilemap layers.

  • The config has `physics: { default: 'arcade' }`, or code calls `this.physics.add.*`,

`body.setVelocity` or `this.physics.add.collider`.

  • Not for scene structure and loading (`phaser-core`), jump-feel rules such as coyote time

(`platformer`), or fixed timestep and tunnelling in general (`physics-tuning`).

Workflow

1. **Enable the world with debug drawing on**: `physics: { default: 'arcade', arcade: { gravity: { x: 0, y: 600 }, debug: true } }`. Body outlines and velocity lines answer most "why didn't it collide" questions at a glance. Turn debug off before release. 2. **Create bodies through the physics factory**: `this.physics.add.sprite` (dynamic), `this.physics.add.staticImage` or `staticGroup` (walls and ground), or `this.physics.add.existing(obj)` for an object you already made. 3. **Move dynamic bodies through the body** with velocity, acceleration and gravity. Writing `x`/`y` directly teleports the body past colliders. 4. **Register each `collider` and `overlap` once in `create`.** A collider separates bodies; an overlap only reports contact (pickups, triggers, hurtboxes). 5. **Use groups** so one collider covers many objects, and pool projectiles with `maxSize`. 6. **Verify** with the probe in [Verify](#verify).

Patterns

1. Enable Arcade Physics

const config = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: { x: 0, y: 600 }, // top-down games use { x: 0, y: 0 }
      debug: true,               // body outlines and velocity while building
    },
  },
  scene: [PlayScene],
};

2. Top-down movement

update() {
  const speed = 220;
  const body = this.player.body;
  body.setVelocity(0);
  if (this.cursors.left.isDown) body.setVelocityX(-speed);
  if (this.cursors.right.isDown) body.setVelocityX(speed);
  if (this.cursors.up.isDown) body.setVelocityY(-speed);
  if (this.cursors.down.isDown) body.setVelocityY(speed);
  body.velocity.normalize().scale(speed); // diagonals at the same speed (zero stays zero)
}

3. Platformer with a ground check

create() {
  this.platforms = this.physics.add.staticGroup();
  this.platforms.create(400, 568, 'ground');

  this.player = this.physics.add.sprite(100, 450, 'player');
  this.player.setCollideWorldBounds(true);
  this.player.body.setSize(20, 36, true); // hitbox tighter than the art, centred

  this.physics.add.collider(this.player, this.platforms); // once, here
  this.cursors = this.input.keyboard.createCursorKeys();
}

update() {
  const onGround = this.player.body.blocked.down; // same as body.onFloor()
  const dir = (this.cursors.right.isDown ? 1 : 0) - (this.cursors.left.isDown ? 1 : 0);
  this.player.setVelocityX(dir * 160);
  if (this.cursors.up.isDown && onGround) this.player.setVelocityY(-450);
}

4. Collider vs overlap

// Push apart, then react.
this.physics.add.collider(this.player, this.enemies, (player, enemy) => this.hurt(player, enemy));

// Detect only. The optional 4th argument returns false to skip a pair before the callback.
this.physics.add.overlap(this.player, this.coins, (player, coin) => {
  coin.disableBody(true, true); // deactivate and hide; the group can reuse it
  this.registry.inc('score', 10);
});

5. Pooled projectiles

create() {
  this.bullets = this.physics.add.group({ defaultKey: 'bullet', maxSize: 30 });
}

fire(x, y) {
  const bullet = this.bullets.get(x, y); // an inactive member, or a new one under maxSize
  if (!bullet) return;                   // every bullet is in flight
  bullet.enableBody(true, x, y, true, true);
  bullet.body.setAllowGravity(false);
  bullet.setVelocityY(-500);
}

update() {
  // Return off-screen bullets to the pool, or firing stops after 30 shots.
  for (const bullet of this.bullets.getChildren()) {
    if (bullet.active && bullet.y < -32) bullet.disableBody(true, true);
  }
}

Verify

1. `npm run build` (or `npx tsc --noEmit`) passes. 2. Probe the running game. If `phaser-core`'s headless smoke script is in use, put this body in its `page.evaluate(() => { ... })` after a two-second wait, adjusting the scene key and object names:

const s = window.game.scene.getScene('play');
return {
  bodies: s.physics.world.bodies.size,          // dynamic bodies alive
  staticBodies: s.physics.world.staticBodies.size,
  playerOnFloor: s.player.body.blocked.down,    // true once the player has landed
  playerY: Math.round(s.player.y),
};

Expect `playerOnFloor: true` and a `playerY` resting on the ground for a platformer, and a body count that stays flat while firing (the pool is recycling). 3. With `debug: true`, take a screenshot and check that hitboxes sit on the art. Without browser automation, ask the user to run with `debug: true` and report whether the outlines match the sprites and where the player stops.

G

Read more
@gamedev-skills
Ships withawesome-gamedev-agent-skills

<img src="docs/assets/awesome-gamedev-agent-skills-banner.png" width="820" alt="awesome-gamedev-agent-skills — game-dev skills for AI coding agents.

Stars on GitHub

Momentum

stars in total
6.3k
Star history of gamedev-skills/awesome-gamedev-agent-skills on GitHub, a chart by star-history.com

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills12d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc13d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about phaser-arcade-physics.

Which coding agents can use phaser-arcade-physics?
phaser-arcade-physics installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.