Teaching Xdebug with Animated Bugs

I recently redid my Xdebug course over at CraftQuest. When I created the original version of the course in 2021, I created a Craft CMS plugin, called Buggy, to help CraftQuest students learn Xdebug in a fun, visual way.

The plugin spawns animated bugs in the Craft CMS Control Panel. The twist is that these visual bugs represent actual software bugs in the code that students need to find and fix using Xdebug.

Bugs animated gif

How it Works

The plugin has a toggle to enable automatic mode. This mode is for debugging and fixing bugs during the course. When automatic mode is enabled, the plugin runs three internal tests that check for intentional bugs in the codebase:

  • A malformed getSwarm() method
  • An incorrect getSwarms() implementation
  • A spray calculation that can return negative numbers

Each detected bug adds to the number of bugs displayed in Craft CMS control panel (up to 80 bugs total). As students use Xdebug to find and fix the bugs listed above, the bug count displayed on the screen decreases, which provides immediate visual feedback on their debugging progress.

The Service Checker Pattern

I had to run two versions of similar services classes in order to get this to work. The clever part is how the plugin switches between modes. A StatusHelper class acts as a service dispatcher:

public function getService(): BugService|BuggyService
{
    if (Buggy::$plugin->getSettings()->automaticBugSpawning) {
        return Buggy::$plugin->buggyService;
    }
    return Buggy::$plugin->bugService;
}

This single method determines which service handles all bug operations. Controllers, Twig variables, and other components simply call (new StatusHelper)->getService() without knowing which mode is active.

The two services share the same interface but behave differently - BuggyService ties bug counts to code defects, while BugService allows manual swarm creation for continued learning after all bugs are fixed.

The Pedagogical Power of Bugs?

Learning a debugger can be frustrating. It’s abstract - you’re stepping through invisible execution paths, inspecting variables in memory, setting breakpoints on lines that may or may not get hit. Students often struggle to connect the dots between “I set a breakpoint” and “I found the problem.”

Buggy flips this on its head by making debugging tangible.

Motivated by Bugs

When you install Buggy with automatic mode enabled, animated bugs immediately start crawling across your Craft CMS control panel. These aren’t random - each bug represents a real software defect in the plugin’s code.

The plugin runs three internal checks on every page load:

private function _runTests(): int
{
    $bugCount = 0;
    $bugCount += $this->_checkGetSwarm();           // 40 bugs
    $bugCount += $this->_checkGetSwarms();          // 20 bugs
    $bugCount += $this->_checkRemainingBugCount();  // 20 bugs
    return $bugCount;
}

With all bugs present, up to 80 insects swarm your screen. The result passes directly to the JavaScript controller:

"new BugController({'minBugs':${bugCount}, 'maxBugs':${bugCount}});"

The Debugging Loop

This creates a powerful feedback loop:

  1. Annoyance drives motivation - Bugs crawling over your interface are distracting. You want them gone. It’s fun and kinda creepy!

  2. Xdebug becomes the solution - To eliminate bugs, students must use Xdebug to find the intentional defects in the code. Step through execution, inspect variables, understand why getSwarm() returns the wrong type or why calculateSprayEffectiveness() doesn’t reduce the bug count as expected.

  3. Immediate visual reward - Fix a bug, reload the page, watch 20-40 bugs disappear. The connection between debugging effort and result is instantaneous and satisfying.

  4. Progressive accomplishment - Students see their swarm shrink from 80 to 60 to 40 to 20 to zero. Each milestone reinforces the learning.

  5. Clear victory condition - A bug-free control panel means you’ve mastered the exercises. No boring “you passed” message. There’s just the clean interface you earned.

Once students fix all the intentional bugs, they can switch to manual mode. The same service checker pattern that powered the learning spawns bugs on demand to practice spray calculations or maybe troll a co-worker by filling the control panel with bugs.

This was a fun approach to teaching for me because it gamified the learning process and made bug finding and fixing fun. Buggy gives you something to see and made it satisfying to eliminate the bugs.