Debugging

Table of Contents

  1. Console Debugging
  2. Hit Box Visualization
  3. Source-Level Debugging
  4. Network Debugging

Debugging is the process of finding and fixing errors in your code. It uses tools like console logs, DevTools breakpoints, network inspection, and hitbox visualization to understand what’s happening inside a program.

Subrequirements

Console Debugging

What was learned: Console debugging means using console.log() to print game state, variable values, and method calls at key points so you can see what's happening inside the program. Adding strategic logs in Pong's update and collision methods helped track down a bug where the ball occasionally tunneled through the paddle at high speed.
Evidence:
  • Pong Game: console.log calls in Ball.update() and collision methods to track velocity and position (View Pong Game)
  • Local Storage Demo: console.warn('[Leaderboard] submitScore failed:', err) logs API failures without crashing the game (Local Storage Demo)
// From _projects/local-storage/levels/localStorageDemo.js — strategic warning log
leaderboard.submitScore(playerName, total, 'CoinsCollected').catch(err => {
    console.warn('[Leaderboard] submitScore failed:', err);
    // Logs the error but doesn't crash — game keeps running
});

// From hacks/pong.md — debugging ball state in update()
// Strategic log: only fires when velocity direction changes (bounce event)
if (hitLeft) {
    this.velocity.x = Math.abs(this.velocity.x);
    console.log('[Ball] Bounced off LEFT paddle — vx:', this.velocity.x, 'pos:', this.position.x.toFixed(1));
}

Code Runner Challenge

Hit Run to see strategic console debugging in action — the same pattern used in Pong and the Local Storage Demo. Notice how the logs are labeled with [tags] and only fire at meaningful events, not every frame.

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Quick Quiz: Console Debugging

  1. What is the main purpose of using console.log in your code?
    • a) To make the code run faster
    • b) To print out values and help debug
    • c) To add comments
  2. When should you use console.warn instead of console.log?
  3. How can console debugging help you find bugs?
Show Answers 1. b) To print out values and help debug 2. When you want to highlight warnings or potential problems, not just normal info. 3. It lets you see what your code is doing step by step, so you can spot where things go wrong.

Hit Box Visualization

What was learned: Hitbox visualization means drawing the collision boundaries of game objects on screen so you can see exactly where collisions are being detected. Toggling hitbox display in the adventure game let me spot that the player's collision box was too large, causing the character to stop walking before visually touching a barrier.
Evidence:
  • Collision Mechanics Level: hitbox: { widthPercentage: 0.1, heightPercentage: 0.2 } on NPC objects — tuned by visualizing where collisions fired (Collision Demo)
  • Local Storage Demo: Player hitbox { widthPercentage: 0.45, heightPercentage: 0.4 } refined after visual inspection to reduce coin ghost-hits
// From _projects/collisions-mechanic/levels/GameLevelCollisionMechanicsLessonLevel.js
// Hitbox percentages tuned by toggling visual overlay during testing
const playerData = {
    hitbox: { widthPercentage: 0, heightPercentage: 0 },  // full sprite — was too large
    // ↑ set to 0 after visual debug showed collisions firing 20px before actual contact
};

const npcData1 = {
    hitbox: { widthPercentage: 0.1, heightPercentage: 0.2 },
    // ↑ 10% inset each side — tuned visually so player must be close before triggering
};

// Toggle hitbox rendering — common debug pattern
function drawHitbox(ctx, obj, show) {
    if (!show) return;
    ctx.strokeStyle = 'rgba(255,0,0,0.8)';
    ctx.lineWidth = 2;
    ctx.strokeRect(obj.hitX, obj.hitY, obj.hitW, obj.hitH);
}

Code Runner Challenge

Hit Run to see hitbox visualization toggling on and off — the same technique used to tune the collision percentages in GameLevelCollisionMechanicsLessonLevel.js. The red rectangles show exactly where collisions would fire.

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Source-Level Debugging

What was learned: Source-level debugging means using the browser's DevTools Sources tab to set breakpoints and step through code line by line. This lets you pause execution mid-function and inspect every variable's value at that exact moment — far more powerful than console.log for complex bugs.
Evidence:
  • Pong Game: Set a breakpoint inside checkCollision() to step through ball-paddle logic frame by frame and find the tunneling bug
  • Local Storage Demo: Breakpoint in the coinCollected event handler to confirm e.detail.total was correct before submitScore ran
// Source-level debugging — the debugger statement triggers DevTools breakpoint
// (Remove before production — this is a development-only tool)

function checkCollision(ball, paddle) {
    debugger;  // ← DevTools will pause here; inspect ball.x, ball.y, paddle.y in Variables panel
    const hit =
        ball.x - ball.radius < paddle.x + paddle.width &&
        ball.y > paddle.y &&
        ball.y < paddle.y + paddle.height;
    return hit;
}

// Step-through workflow (from DevTools Sources tab):
// 1. Open DevTools → Sources tab
// 2. Find the file (e.g. custompong.md or hacks/pong.md)
// 3. Click the line number to set a breakpoint — no code change needed
// 4. Use F10 (Step Over) to go line by line, F11 (Step Into) to enter functions
// 5. Hover over variables to see their current values

Code Runner Challenge

Hit Run to see how debugger statements work as in-code breakpoints. In a real browser DevTools session, execution would pause at each debugger line so you can inspect every variable — this simulation logs what you'd see in the Variables panel.

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Network Debugging

What was learned: Network debugging means using the browser's Network tab to inspect every fetch request — the URL, method, headers, response status, and returned data. When the leaderboard stopped saving scores, checking the Network tab showed a CORS error in the response headers, which led to fixing the backend endpoint configuration.
Evidence:
  • Local Storage Demo: Inspected the POST /api/leaderboard request in the Network tab to confirm the score payload was correct and the response returned 200 OK (Local Storage Demo)
  • Pong Game: Checked Network tab for any failed asset loads (sprites, backgrounds) that caused blank screen bugs
// From _projects/local-storage/levels/localStorageDemo.js
// Network tab shows: POST → /api/leaderboard, Status 200, Response: {"status":"ok"}
// Error case: Status 0 or CORS error → check response headers for Access-Control-Allow-Origin

leaderboard.submitScore(playerName, total, 'CoinsCollected').catch(err => {
    // Network tab shows the failed request — .catch() handles it gracefully
    console.warn('[Leaderboard] submitScore failed:', err);
    // Common causes visible in Network tab:
    // - Status 0: CORS blocked (no Access-Control-Allow-Origin header)
    // - Status 401: not authenticated
    // - Status 500: server error — check Response body for details
});

Code Runner Challenge

Hit Run to simulate network request inspection — the same information you'd read from the DevTools Network tab. Each fetch logs its method, URL, status, and response data, plus error details if it fails.

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Application Debugging

What was learned: Application debugging uses the DevTools Application tab to inspect cookies, localStorage, and sessionStorage — the persistent data your app stores in the browser. When coin counts weren't saving correctly, the Application tab showed the coinsCollected localStorage key had a stale string value that broke parseInt().
Evidence:
  • Local Storage Demo: Inspected localStorage['coinsCollected'] and sessionStorage['playerName'] in the Application tab while testing the leaderboard (Local Storage Demo)
// From _projects/local-storage/levels/localStorageDemo.js
// Application tab shows: localStorage → coinsCollected: "3"
// Bug: value was stored as string — parseInt() fixed it

const coinsCollected = parseInt(localStorage.getItem('coinsCollected') || '0');
//                     ↑ parseInt() essential — localStorage always returns strings
localStorage.setItem('coinsCollected', coinsCollected + 1);

// sessionStorage used for player name — visible in Application tab
let playerName = sessionStorage.getItem('playerName');
if (!playerName) {
    playerName = prompt('Enter your name:') || 'Anonymous';
    sessionStorage.setItem('playerName', playerName);
}

Code Runner Challenge

Hit Run to see localStorage and sessionStorage being written, read, and inspected — exactly the data you'd examine in the DevTools Application tab. Watch how parseInt() is required because storage always returns strings.

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Element Inspection

What was learned: Element inspection uses the DevTools Elements panel to examine the HTML and CSS of the page — including the canvas element and any DOM objects created by the game engine. Inspecting the canvas element confirmed its width and height attributes were being set correctly by GameEnv.create(), and checking computed styles helped fix a layout issue where the game was rendering off-center.
Evidence:
  • Pong Game: Inspected the <canvas> element to confirm width/height matched Config values and the canvas wasn't being scaled by CSS
  • Local Storage Demo: Used Elements panel to check that the leaderboard <div> had the correct z-index and wasn't hidden behind the canvas
// From hacks/pong.md — canvas setup that Element Inspector verifies
const canvas = document.getElementById('gameCanvas');
canvas.width  = Config.canvas.width;   // attribute (not CSS width) — sets rendering resolution
canvas.height = Config.canvas.height;

// Common bug: CSS width ≠ canvas.width → stretched/blurry rendering
// Element Inspector shows:
//   Attributes: width="800" height="500"    ← rendering resolution (correct)
//   Styles: width: 100% (if set by CSS)     ← display size (may differ — causes blur)

// Fix: keep CSS width = canvas.width, or set explicitly:
canvas.style.width  = Config.canvas.width  + 'px';
canvas.style.height = Config.canvas.height + 'px';

Code Runner Challenge

Hit Run to see element property inspection in code — the same information you'd read from the DevTools Elements panel. Watch how the canvas attribute width differs from CSS width and why that matters for rendering quality.

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Gamerunner — Debug Mode Pong

This Pong game has a built-in debug overlay. Press D to toggle debug mode, which shows hitboxes (red), ball velocity vector (yellow), and live state values — the same technique used to tune collision boxes in the adventure game. Use W/S and Arrow keys to play.

Challenge

Pong with toggleable debug overlay showing hitboxes and state

Lines: 1 Characters: 0
Game Status: Not Started