Skip to content

Debug Mode

Debug mode is a built-in development tool that provides detailed logging for all state operations. It’s extremely useful for development and troubleshooting state management issues.

Enable debug mode by passing { debug: true } in the options parameter:

import { withLocalState } from 'phaser-hooks';
export class GameScene extends Phaser.Scene {
create() {
// Enable debug mode for this state
const playerState = withLocalState(
this,
'player',
{
hp: 100,
level: 1,
},
{ debug: true } // Enable debug logging
);
// All operations will now be logged to the console
playerState.set({ hp: 90, level: 2 });
const currentPlayer = playerState.get();
playerState.on('change', (newPlayer) => {
console.log('Player state changed:', newPlayer);
});
}
}

When debug mode is enabled, you’ll see detailed logs in your browser’s developer console for:

[phaser-hooks] 2024-01-15 10:30:45 [INIT] player - Initializing state with value: {hp: 100, level: 1}
[phaser-hooks] 2024-01-15 10:30:46 [SET] player - Updating state: {hp: 90, level: 2} (was: {hp: 100, level: 1})
[phaser-hooks] 2024-01-15 10:30:47 [GET] player - Retrieved state: {hp: 90, level: 2}
[phaser-hooks] 2024-01-15 10:30:48 [EVENT] player - Added change listener
[phaser-hooks] 2024-01-15 10:30:49 [EVENT] player - Removed change listener
[phaser-hooks] 2024-01-15 10:30:50 [EVENT] player - Cleared all listeners
[phaser-hooks] 2024-01-15 10:30:51 [VALIDATE] player - Validation passed for value: {hp: 90, level: 2}
[phaser-hooks] 2024-01-15 10:30:52 [VALIDATE] player - Validation failed: HP cannot be negative
[phaser-hooks] 2024-01-15 10:30:53 [ERROR] player - Failed to set value: HP cannot be negative

To view debug logs:

  1. Open your browser’s Developer Tools (F12 or right-click → Inspect)
  2. Go to the Console tab
  3. Run your Phaser game
  4. Look for logs prefixed with [phaser-hooks]
const playerState = withLocalState(
this,
'player',
{ hp: 100 },
{ debug: true }
);
playerState.set({ hp: 90 });
// [phaser-hooks] [SET] player - Updating state: {hp: 90} (was: {hp: 100})
const gameSettings = withGlobalState(
this,
'settings',
{ volume: 0.8 },
{ debug: true }
);
gameSettings.set({ volume: 0.5 });
// [phaser-hooks] [SET] settings - Updating state: {volume: 0.5} (was: {volume: 0.8})
const userSettings = withPersistentState(
'userSettings',
{ theme: 'dark' },
'local',
{ debug: true }
);
userSettings.set({ theme: 'light' });
// [phaser-hooks] [SET] userSettings - Updating state: {theme: 'light'} (was: {theme: 'dark'})
// [phaser-hooks] [PERSIST] userSettings - Saved to localStorage
const healthPercent = withComputedState(
this,
'healthPercent',
playerState,
(player) => (player.hp / player.maxHp) * 100,
{ debug: true }
);
// [phaser-hooks] [COMPUTE] healthPercent - Computed value: 90 (source changed)

Only enable debug mode for the specific states you’re troubleshooting:

export class GameScene extends Phaser.Scene {
create() {
// Debug only the problematic state
const problemState = withLocalState(
this,
'problem',
{ value: 0 },
{ debug: true } // Debug enabled
);
// No debug for this one
const normalState = withLocalState(
this,
'normal',
{ value: 0 }
// No debug option
);
}
}

Debug mode is especially useful for troubleshooting validation:

export class GameScene extends Phaser.Scene {
create() {
const healthState = withLocalState(
this,
'health',
100,
{
validator: (value) => {
if (value < 0) return 'Health cannot be negative';
if (value > 100) return 'Health cannot exceed 100';
return true;
},
debug: true,
}
);
try {
healthState.set(150);
} catch (error) {
// [phaser-hooks] [VALIDATE] health - Validation failed: Health cannot exceed 100
// [phaser-hooks] [ERROR] health - Failed to set value: Health cannot exceed 100
console.error('Validation error:', error.message);
}
healthState.set(75);
// [phaser-hooks] [VALIDATE] health - Validation passed for value: 75
// [phaser-hooks] [SET] health - Updating state: 75 (was: 100)
}
}

Use browser console filters to focus on specific information:

  1. Open the Console
  2. Click the filter icon
  3. Enter filter patterns:
    • [phaser-hooks] - Show all hooks logs
    • [SET] - Show only set operations
    • [ERROR] - Show only errors
    • player - Show only player state logs
  1. Open the Console
  2. Use the search/filter box at the top
  3. Enter your filter term
export class DebugScene extends Phaser.Scene {
create() {
// Enable debug for problematic inventory state
const inventoryState = withLocalState<string[]>(
this,
'inventory',
[],
{
validator: (value) => {
if (value.length > 10) {
return 'Inventory cannot exceed 10 items';
}
return true;
},
debug: true, // Debug enabled
}
);
// Add items and watch the logs
inventoryState.set(['sword']);
// [phaser-hooks] [VALIDATE] inventory - Validation passed
// [phaser-hooks] [SET] inventory - Updating state: ["sword"] (was: [])
inventoryState.set([...inventoryState.get(), 'potion']);
// [phaser-hooks] [GET] inventory - Retrieved state: ["sword"]
// [phaser-hooks] [VALIDATE] inventory - Validation passed
// [phaser-hooks] [SET] inventory - Updating state: ["sword", "potion"] (was: ["sword"])
inventoryState.on('change', (newInventory) => {
console.log('Inventory changed:', newInventory);
});
// [phaser-hooks] [EVENT] inventory - Added change listener
try {
// Try to add too many items
inventoryState.set([
'item1', 'item2', 'item3', 'item4', 'item5',
'item6', 'item7', 'item8', 'item9', 'item10', 'item11',
]);
} catch (error) {
// [phaser-hooks] [VALIDATE] inventory - Validation failed: Inventory cannot exceed 10 items
// [phaser-hooks] [ERROR] inventory - Failed to set value
console.error('Error:', error.message);
}
}
}

✅ Enable debug mode during development for troubleshooting

✅ Use selective debugging for specific problematic states

✅ Use console filters to focus on relevant logs

✅ Check debug logs when state behaves unexpectedly

✅ Document issues using debug log timestamps

❌ Don’t leave debug mode enabled in production - it adds overhead

❌ Don’t enable debug for all states - too much noise

❌ Don’t ignore validation errors shown in debug logs

❌ Don’t forget to remove debug: true before releasing

Use environment variables to conditionally enable debug mode:

export class GameScene extends Phaser.Scene {
create() {
const isDevelopment = process.env.NODE_ENV === 'development';
const playerState = withLocalState(
this,
'player',
{ hp: 100 },
{ debug: isDevelopment } // Only debug in development
);
}
}

Or use a configuration file:

config.ts
export const DEBUG_HOOKS = process.env.NODE_ENV === 'development';
// GameScene.ts
import { DEBUG_HOOKS } from './config';
export class GameScene extends Phaser.Scene {
create() {
const playerState = withLocalState(
this,
'player',
{ hp: 100 },
{ debug: DEBUG_HOOKS }
);
}
}

Debug mode has minimal performance impact, but:

  • Adds console output overhead - Can slow down when logging thousands of operations
  • Should be disabled in production - No need for logging in production builds
  • Use selectively - Enable only for states you’re debugging