Debugging Showcase
Debugging
Table of Contents
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
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.
- Pong Game:
console.logcalls 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.
Quick Quiz: Console Debugging
- 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
- When should you use console.warn instead of console.log?
- 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
- 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.
Source-Level Debugging
- 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
coinCollectedevent handler to confirme.detail.totalwas 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.
Network Debugging
- Local Storage Demo: Inspected the
POST /api/leaderboardrequest 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.
Application Debugging
coinsCollected localStorage key had a stale string value that broke parseInt().
- Local Storage Demo: Inspected
localStorage['coinsCollected']andsessionStorage['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.
Element Inspection
- 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.
Gamerunner — Debug Mode Pong
Challenge
Pong with toggleable debug overlay showing hitboxes and state