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