Skip to content

Why Custom Hooks?

The real power of phaser-hooks comes from creating reusable hooks.

Without custom hooks, you repeat yourself:

// ❌ Repetitive - every scene needs this
class GameScene extends Phaser.Scene {
create() {
const player = withLocalState(this, 'player', {
hp: 100,
maxHp: 100,
level: 1,
exp: 0
});
}
}
class BattleScene extends Phaser.Scene {
create() {
const player = withLocalState(this, 'player', { // Same key, same initial value
hp: 100,
maxHp: 100,
level: 1,
exp: 0
});
}
}

Create a custom hook:

// ✅ Define once, use everywhere
export function withPlayer(scene: Phaser.Scene) {
return withLocalState(scene, 'player', {
hp: 100,
maxHp: 100,
level: 1,
exp: 0
});
}
// Usage - clean and consistent
const player = withPlayer(this);

DRY - Define state shape once ✅ Type-safe - TypeScript infers everywhere ✅ Encapsulation - Hide implementation details ✅ Testability - Easy to mock in tests ✅ Refactoring - Change once, updates everywhere

Instead of this mess across 10 scenes:

withLocalState(this, 'player', { hp: 100, maxHp: 100, level: 1 })

You have this clean API:

const player = withPlayer(this);