Table of Contents

Gameplay Testing

Gameplay testing involves verifying that core game mechanics work as intended: level completion, character interactions, and collision detection.

Testing Collisions and Interactions

In my collision-mechanic project, I test that Guard objects properly collide with the player:

/**
 * Example: Guard collision detection in update method
 */
update() {
    this.draw();

    if (this.spriteData && typeof this.spriteData.update === 'function') {
        this.spriteData.update.call(this);
    }
    
    // Test: Check if collision detection triggers
    if (!this.playerDestroyed && this.collisionChecks()) {
        this.handleCollisionEvent();
    }

    this.position.y += this.velocity.y;
    this.stayWithinCanvas();
}

/**
 * Test the collision response
 */
handleCollisionEvent() {
    var player = this.gameEnv.gameObjects.find(obj => obj instanceof Player); 
    console.log("Collision has occurred, player has been destroyed.");
    player.destroy();
    this.playerDestroyed = true;
}

How to Test Gameplay:

  1. Play through each level - Verify the player can move and interact with objects
  2. Test collisions - Deliberately run into enemies/obstacles to ensure they respond correctly
  3. Check level completion - Verify winning conditions are triggered when objectives are met
  4. Test character movement - Ensure WASD controls respond properly in all directions
  5. Monitor console - Watch for any error messages or unexpected log outputs

Integration Testing

Integration testing verifies that multiple components work together, such as API calls with backend systems and NPC AI behavior.

Testing Leaderboard Integration

From my local-storage project, the coin collection system integrates with the leaderboard:

/**
 * Test: Coin collection triggers leaderboard submission
 */
document.addEventListener('coinCollected', (e) => {
    const total = e.detail.total;

    let playerName = sessionStorage.getItem('playerName');
    if (!playerName) {
        playerName = prompt('Enter your name for the leaderboard:') || 'Anonymous';
        sessionStorage.setItem('playerName', playerName);
    }

    // Submit to leaderboard - test that this integration works
    leaderboard.submitScore(playerName, total, 'CoinsCollected').catch(err => {
        console.warn('[Leaderboard] submitScore failed:', err);
    });
});

Testing NPC Interactions

In my game levels, NPCs respond to player collisions and interact with dialogue systems:

/**
 * Test: NPC interaction with player
 */
handleCollisionReaction(other) {
    if (other && other.reaction && typeof other.reaction === "function") {
        other.reaction();  // Test that reaction fires
        return;
    }
    
    // Test dialogue system
    if (other && other.id) {
        const targetObject = this.gameEnv.gameObjects.find(obj => 
            obj.spriteData && obj.spriteData.id === other.id
        );
        
        if (targetObject && targetObject.dialogueSystem) {
            targetObject.showReactionDialogue();  // Test dialogue appears
        }
    }
}

How to Test Integration:

  1. Complete gameplay actions - Collect coins, defeat enemies, interact with NPCs
  2. Check data persistence - Verify scores are saved to localStorage and sessionStorage
  3. Verify API responses - Use DevTools Network tab to confirm leaderboard submissions succeed
  4. Test backend communication - Watch for successful status codes (200) in Network tab
  5. Verify state updates - Confirm UI updates after API responses (leaderboard refreshes)

API Error Handling

Robust error handling ensures your game doesn’t crash when APIs fail. Testing error scenarios is critical.

Try-Catch Blocks for API Calls

From heistMusic.js, I use try-catch to handle fetch failures gracefully:

/**
 * Test: Fetch succeeds and handles response
 */
async fetchPreviewUrl() {
    const response = await fetch(this.endpoint);
    if (!response.ok) {
      throw new Error('API request failed (' + response.status + ')');
    }
    const data = await response.json();
    const tracks = (data && Array.isArray(data.results)) ? data.results : [];
    return tracks[0].previewUrl;
}

/**
 * Test: Catch block handles errors gracefully
 */
async startMusic() {
    try {
      const previewUrl = await this.fetchPreviewUrl();
      this.audio = new Audio(previewUrl);
      this.audio.play();
      console.log('Background music: playback started');
    } catch (error) {
      // Test: Error is caught and logged, game doesn't crash
      console.warn('Background music: failed to start', error);
    }
}