Back Index Next
Documentation Index Testing & Verification

Debugging

Click a technique to see how it was used in Heist.exe.


Debugging in Heist.exe

Debugging is how you find and fix problems in code. Across Gem.js, Guard.js, heistMusic.js, and the level files, six different debugging techniques were applied — each targeting a different type of problem.


flowchart LR
    A[Bug Found] --> B{Where is it?}
    B --> C[Game Logic<br>console.log]
    B --> D[Collision Zones<br>Hitbox Overlay]
    B --> E[API / Network<br>Network Tab]
    B --> F[DOM Elements<br>Elements Tab]
    B --> G[Session State<br>Application Tab]
    B --> H[Exact Frame<br>Sources + Breakpoint]
    C --> I[✅ Fixed]
    D --> I
    E --> I
    F --> I
    G --> I
    H --> I

The Six Techniques

🖨️ Console Debugging — write console.log() at key moments to see what the code is doing

Exactly what it is: console.log() outputs text to the DevTools Console without pausing the game. It’s the first line of attack: add a log where you think a problem might be, run the code, and check the output to see if that code actually ran and what values it had.

From Heist.exe:

// Gem.js — line 14: Log when gem spawns
console.log('Gem created:', this.spriteData?.id, 'at position', this.position);

// Gem.js — collect() method: Log collection event
console.log(`Gem collected! +${this.value} | Total: ${this.gameEnv?.stats?.coinsCollected}`);

// Guard.js — lines 40, 47: Log every bounce
console.log(this.velocity.y);  // Output when Guard hits bottom
console.log(this.velocity.y);  // Output when Guard hits top

// Guard.js — lines 59-60: Log collision event
console.log("Collision has occurred, player has been destroyed.");

// heistMusic.js: Warn about failed API
console.warn('Background music: failed to start', error);

Use console.log() for normal information, console.warn() for potential problems, console.error() for failures.


Hitbox Visualization — render collision zones on-screen as semi-transparent overlays

Exactly what it is: Instead of guessing where collision boundaries are, render them directly on the canvas with a semi-transparent color. Then you can see exactly which regions will trigger collisions — essential for lining up hitboxes with what the player actually sees on screen.

From Heist.exe:

// HeistL2.js — lines 105-145: All borders defined with visible: true
const border_top = {
    id: 'border_top',
    x: width * -0.0029, y: height * 0.0, width: width * 1.0029, height: height * 0.0587,
    color: 'rgba(0, 255, 136, 0.5)',  // Semi-transparent green
    visible: true,                      // Render on-screen
    hitbox: { widthPercentage: 1.0, heightPercentage: 1.0 }
} 

const border_bottom = {
    id: 'border_bottom',
    x: width * 0.0, y: height * 0.9371, width: width * 1.0, height: height * 0.0629,
    color: 'rgba(0, 255, 136, 0.5)',
    visible: true,
    hitbox: { widthPercentage: 1.0, heightPercentage: 1.0 }
}

// Once positions are confirmed correct, turn off visibility:
// visible: false,  // or widthPercentage: 0.0

The green overlays show exactly where the collision zones are, making it easy to verify Guards bounce at the right spots and players can’t clip through walls.


Source-Level Debugging — pause execution at specific lines and step through frame-by-frame

Exactly what it is: You set a breakpoint on a line of code, then run the game. When that line is reached, execution pauses and you can inspect every variable’s current value. Then you step forward one line at a time, watching the values change, until you understand exactly where the bug happens.

From Heist.exe:

// Guard.js — lines 59-60: Natural breakpoint location
console.log("Collision has occurred, player has been destroyed.");
player.destroy();
this.playerDestroyed = true;

// Open DevTools (F12), go to Sources tab
// Click on line number 60 to set a breakpoint
// Play the game until Guard hits Player
// Execution pauses; you can now:
//   • Hover over variables to see their values
//   • Open the Console to run expressions like gameEnv.gameObjects.length
//   • Step to the next line (F10) to see what happens next

The console.log() calls you already have in your code act as natural breakpoint targets.


Network Debugging — inspect API requests and responses in the DevTools Network tab

Exactly what it is: When your code calls an external API (like iTunes Search), the Network tab shows exactly what was sent, what was received, the HTTP status code, and how long it took. This is essential for finding bugs in API integration.

From Heist.exe:

// heistMusic.js: Fetch from iTunes Search API
const response = await fetch(this.endpoint);
if (!response.ok) {
    throw new Error('API request failed (' + response.status + ')');
}
const data = await response.json();

// Open DevTools → Network tab
// Play the game and watch:
//   • Request URL: https://itunes.apple.com/search?term=...
//   • Status: 200 (success) or 404/500 (failure)
//   • Response tab: the actual JSON returned
//   • Headers: cookies, content-type, cache headers
//   • Timing: how long the request took

If the status isn’t 200, the explicit error message makes it clear: “API request failed (404)” or “(500)”.


Application Debugging — inspect session state stored on gameEnv

Exactly what it is: Your game stores data that persists across frames and levels — coin totals, boolean flags, player stats. The Application tab in DevTools lets you see all this live state, inspect it at any moment, and even modify it to test edge cases.

From Heist.exe:

// Gem.js — collect() method: Update shared gameEnv stats
if (this.gameEnv) {
    if (!this.gameEnv.stats) this.gameEnv.stats = { coinsCollected: 0 };
    this.gameEnv.stats.coinsCollected = (this.gameEnv.stats.coinsCollected || 0) + this.value;
}

// heistMusic.js: Runtime flags
this.started = true;
this.isPlaying = true;

// Open DevTools → Application tab
// Expand gameEnv in the console or watch window
// See coinsCollected increment as you collect gems
// See started and isPlaying toggle as music plays

Element Inspection — view live DOM mutations and CSS in the Elements tab

Exactly what it is: Your JavaScript can create, modify, or hide HTML elements. The Elements tab shows the live DOM tree, including dynamically injected elements, their inline CSS, and their content. This is useful for verifying that your element modifications actually took effect.

From Heist.exe:

// heistMusic.js: Dynamically create button and inject into page
const btn = document.createElement('button');
btn.textContent = 'Toggle Music';
btn.style.cssText = 'position: fixed; top: 10px; right: 10px; z-index: 9999;';
document.body.appendChild(btn);

// Gem.js: Hide canvas on collection
if (this.canvas) this.canvas.style.display = 'none';

// Open DevTools → Elements tab
// Search for the button or look for canvas elements
// Expand to see inline CSS: style="display: none" on hidden gems
// Verify that elements are actually in the DOM even if invisible

If an element isn’t showing on screen but should be, the Elements tab immediately shows why: display: none, opacity: 0, positioned off-screen, or missing entirely.


Technique File DevTools Tab
Console Debugging Gem.js, Guard.js, heistMusic.js Console
Hitbox Visualization HeistL1.js, HeistL3.js Canvas overlay
Source-Level Debugging Guard.js, Gem.js Sources
Network Debugging heistMusic.js Network
Application Debugging Gem.js, heistMusic.js Application
Element Inspection heistMusic.js, Gem.js Elements

Workflow: start with console.log to narrow down where the bug is, then switch to the matching DevTools tab to go deeper into why it’s happening.