debugging

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".

$ Installer

git clone https://github.com/surfdeeper/surfing-game /tmp/surfing-game && cp -r /tmp/surfing-game/.claude/skills/debugging ~/.claude/skills/surfing-game

// tip: Run this command in your terminal to install the skill


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

QuestionTest 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 ThisDo This Instead
Add console.log, ask user to checkWrite Vitest test
Guess at the problemSystematically isolate with tests
Fix symptomsFind and fix root cause
Manual browser debuggingPlaywright automation
Change code without understandingRead and understand first

Integration with Testing Skill

When debugging, use these test patterns:

  1. Regression test - Fails without fix, passes with fix
  2. Time progression test - Simulates frames over time
  3. Edge case test - Zero, negative, maximum values
  4. 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)?