| name | debugging |
| description | Apply systematic debugging methodology. Use when investigating bugs, unexpected behavior, or when user reports issues. Auto-apply when conversation includes "bug", "broken", "not working", "wrong", "glitch", "flickering". |
Debugging Skill
Core Principle
Automate first, ask questions never. If you can write a test to verify behavior, do that instead of asking the user to manually check something.
Debugging Decision Tree
Bug reported
│
▼
Can I reproduce in a test?
│
├─ YES → Write failing test first
│ │
│ ▼
│ Does test fail?
│ │
│ ├─ YES → Debug the logic
│ │
│ └─ NO → Bug is in rendering/CSS layer
│
└─ NO → Need more info from user (specific steps, values)
Systematic Isolation
| Question | Test Strategy |
|---|---|
| Is the calculation correct? | Unit test with known inputs |
| Is the rendering correct? | Integration test, inspect CSS |
| Is it browser-specific? | Playwright test |
| Is it timing-related? | Time progression integration test |
| Is it state-related? | Expose window.__debug, inspect values |
Common Bug Patterns
1. CSS Transitions + 60fps React
Symptom: Values correct in test, visual is wrong/flickering in browser.
Cause: CSS transitions on elements that React updates every frame.
Detection:
# Find transitions on frequently-updated elements
grep -r "transition:" src/ui/*.css
Fix: Remove CSS transitions from elements in the game loop render path.
2. State Not Updating
Symptom: UI shows stale data.
Test:
it('state updates over time', () => {
const { rerender } = render(<Component time={0} />);
const value0 = getValue();
rerender(<Component time={1000} />);
const value1 = getValue();
expect(value1).not.toEqual(value0);
});
3. Calculation Drift
Symptom: Values slowly diverge from expected over time.
Test:
it('no drift over many iterations', () => {
let state = initialState;
for (let i = 0; i < 10000; i++) {
state = update(state, 16); // 16ms per frame
}
expect(state.value).toBeCloseTo(expected, 2);
});
Debug State Exposure
For browser inspection, expose state in dev mode:
// In game loop
if (import.meta.env.DEV) {
window.__debug = {
state: world.setLullState,
gameTime: world.gameTime,
computed: { /* derived values */ }
};
}
Then in browser console: window.__debug.state
Anti-Patterns
| Don't Do This | Do This Instead |
|---|---|
Add console.log, ask user to check |
Write Vitest test |
| Guess at the problem | Systematically isolate with tests |
| Fix symptoms | Find and fix root cause |
| Manual browser debugging | Playwright automation |
| Change code without understanding | Read and understand first |
Integration with Testing Skill
When debugging, use these test patterns:
- Regression test - Fails without fix, passes with fix
- Time progression test - Simulates frames over time
- Edge case test - Zero, negative, maximum values
- Snapshot test - For complex state objects
Debugging Checklist
- Can I write a failing test?
- Does the test isolate the bug?
- Have I checked CSS interactions?
- Have I verified state values?
- Is there a timing/animation issue?
- Did I find the root cause (not just symptoms)?