Skip to content

Troubleshooting

This guide helps you diagnose and fix common issues when developing with PixelRoot32.

Compilation Problems

Common Compilation Errors

Error: Library not found

Solution: Ensure PixelRoot32-Game-Engine is properly installed
- Check platformio.ini has correct lib_deps
- Verify library version matches (use exact version, not ^)
- Try: pio lib install

Error: Include file not found

Solution: Check include paths
- Verify lib_extra_dirs in platformio.ini
- Check that library is in lib/ directory
- Ensure correct namespace (pixelroot32::)

Error: Undefined reference

Solution: Link missing libraries
- Check all required libraries are listed
- Verify TFT_eSPI is installed for ESP32
- Check SDL2 is installed for Native builds

Error: Build flags not recognized

Solution: Verify build flag syntax
- Use -D FLAG_NAME (not --define)
- Check flag names are correct
- Ensure flags are in correct environment section

Configuration Issues

Wrong display type: - Verify DisplayType matches your hardware - Check TFT_eSPI build flags match display - Test with different display types

Incorrect pin configuration: - Verify GPIO pins match your wiring - Check pin numbers in platformio.ini - Ensure pins aren't used by other peripherals

Hardware Problems (ESP32)

Display Not Working

Symptoms: - Blank screen - Garbled display - No output

Solutions: 1. Check wiring: - Verify SPI connections (MOSI, SCLK, DC, RST) - Check power supply (3.3V or 5V as required) - Ensure ground connections

  1. Verify configuration:
  2. Check display type matches hardware
  3. Verify pin numbers in platformio.ini
  4. Test with known working configuration

  5. SPI frequency:

  6. Lower SPI frequency (try 20MHz instead of 40MHz)
  7. Some displays need slower speeds
  8. Check display datasheet for max frequency

  9. Display initialization:

  10. Try different rotation values
  11. Check display width/height settings
  12. Verify TFT_eSPI driver is correct

Buttons Not Responding

Symptoms: - No input detected - Buttons don't trigger actions - Input feels laggy

Solutions: 1. Check wiring: - Verify button connections to GPIO pins - Check pull-up/pull-down resistors - Test buttons with multimeter

  1. Verify pin configuration:
  2. Check InputConfig pin numbers
  3. Ensure pins match hardware
  4. Verify pins aren't used elsewhere

  5. Input debouncing:

  6. Add hardware debouncing (capacitor)
  7. Check InputManager is being updated
  8. Verify input is read in update(), not draw()

  9. Button logic:

  10. Test with isButtonDown() vs isButtonPressed()
  11. Check button indices match configuration
  12. Verify input is accessed correctly

Audio Not Working

Symptoms: - No sound output - Distorted audio - Audio glitches

Solutions: 1. DAC Configuration: - Verify DAC pin (25 or 26 for ESP32) - Check sample rate (11025 Hz recommended) - Ensure audio backend is initialized

  1. I2S Configuration:
  2. Verify I2S pin connections (BCLK, LRCK, DOUT)
  3. Check external DAC is powered
  4. Verify I2S DAC is compatible

  5. Audio quality:

  6. Lower sample rate if distorted
  7. Reduce volume levels
  8. Check for too many simultaneous sounds
  9. Verify audio buffer size

  10. Hardware:

  11. Check speaker connections
  12. Verify amplifier is powered
  13. Test with different audio hardware
  14. Check audio cable connections

Power Issues

Symptoms: - ESP32 resets randomly - Display flickers - Unstable operation

Solutions: 1. Power supply: - Use adequate power supply (500mA+ recommended) - Check voltage is stable (3.3V) - Add decoupling capacitors

  1. Current draw:
  2. Display draws significant current
  3. Audio amplifier adds load
  4. Reduce brightness if possible

  5. Wiring:

  6. Use thick wires for power
  7. Keep power wires short
  8. Add capacitors near ESP32

Performance Problems

Low FPS

Symptoms: - Game runs slowly - Laggy movement - Stuttering

Solutions: 1. Reduce entity count: - Limit active entities (MAX_ENTITIES = 32) - Disable off-screen entities - Use object pooling

  1. Optimize rendering:
  2. Use viewport culling
  3. Reduce draw calls
  4. Use tilemaps instead of individual sprites
  5. Limit sprite count

  6. Simplify logic:

  7. Cache expensive calculations
  8. Reduce collision checks
  9. Lower update frequency for non-critical entities

  10. Check hardware:

  11. Verify ESP32 is running at full speed (240MHz)
  12. Check for thermal throttling
  13. Ensure adequate power supply

Frame Drops

Symptoms: - Occasional stuttering - Inconsistent frame times - Periodic freezes

Solutions: 1. Identify bottlenecks: - Profile frame time - Check for expensive operations - Look for blocking code

  1. Optimize update loop:
  2. Avoid dynamic allocation
  3. Cache calculations
  4. Reduce string operations

  5. Memory issues:

  6. Check for memory leaks
  7. Reduce memory usage
  8. Use object pooling

Freezes/Crashes

Symptoms: - Game stops responding - ESP32 resets - Watchdog resets

Solutions: 1. Memory issues: - Check available heap memory - Reduce entity count - Avoid dynamic allocation - Use object pooling

  1. Infinite loops:
  2. Check for infinite loops in update()
  3. Verify collision detection doesn't loop
  4. Check animation logic

  5. Stack overflow:

  6. Avoid large stack allocations
  7. Reduce recursion depth
  8. Move large data to heap (carefully)

  9. Watchdog:

  10. Ensure update() completes quickly
  11. Add yield() calls if needed
  12. Check for blocking operations

Memory Problems

Out of Memory

Symptoms: - Compilation fails - Runtime crashes - "Allocation failed" errors

Solutions: 1. Reduce memory usage: - Use 1bpp sprites instead of 2bpp/4bpp - Store data in flash (const/constexpr) - Reduce entity count - Use object pooling

  1. Optimize data:
  2. Reuse sprites
  3. Compress tilemap data
  4. Remove unused code/data

  5. Memory management:

  6. Avoid dynamic allocation in game loop
  7. Pre-allocate all resources
  8. Use static buffers

Memory Fragmentation

Symptoms: - Gradual performance degradation - Allocation failures over time - Crashes after running for a while

Solutions: 1. Use object pooling: - Pre-allocate entities - Reuse objects instead of creating/destroying - Avoid frequent new/delete

  1. Pre-allocate resources:
  2. Allocate everything in init()
  3. Use fixed-size arrays
  4. Avoid dynamic containers

Native Build Problems

SDL2 Not Found

Symptoms: - Compilation fails - Linker errors - Missing SDL2 symbols

Solutions: 1. Install SDL2: - Windows (MSYS2): pacman -S mingw-w64-x86_64-SDL2 - Linux: sudo apt-get install libsdl2-dev - macOS: brew install sdl2

  1. Check paths:
  2. Verify include paths in platformio.ini
  3. Check library paths
  4. Ensure SDL2 version is compatible

  5. Linker flags:

  6. Verify -lSDL2 is in build flags
  7. Check library search paths
  8. Ensure SDL2 DLL is accessible (Windows)

Window Not Opening

Symptoms: - Program runs but no window - Console shows errors - Immediate exit

Solutions: 1. Check SDL2 initialization: - Verify SDL2 is properly initialized - Check for SDL2 error messages - Ensure display config is correct

  1. Graphics drivers:
  2. Update graphics drivers
  3. Check SDL2 video backend
  4. Test with simple SDL2 program

  5. Console output:

  6. Run from terminal to see errors
  7. Check for error messages
  8. Verify SDL2 is working

Debugging Techniques

Serial Debugging (ESP32)

void setup() {
    Serial.begin(115200);
    // ... initialization

    Serial.println("Engine initialized");
}

void update(unsigned long deltaTime) override {
    // Debug output
    if (frameCount % 60 == 0) {
        Serial.print("FPS: ");
        Serial.println(1000.0f / deltaTime);
    }
    frameCount++;
}

Memory Monitoring

#ifdef PLATFORM_ESP32
#include <Arduino.h>

void checkMemory() {
    Serial.print("Free heap: ");
    Serial.println(ESP.getFreeHeap());
    Serial.print("Largest block: ");
    Serial.println(ESP.getMaxAllocHeap());
}
#endif

Performance Profiling

class Profiler {
private:
    unsigned long updateTime = 0;
    unsigned long drawTime = 0;

public:
    void startUpdate() {
        updateTime = micros();
    }

    void endUpdate() {
        updateTime = micros() - updateTime;
    }

    void log() {
        Serial.print("Update: ");
        Serial.print(updateTime);
        Serial.print("us, Draw: ");
        Serial.println(drawTime);
    }
};

Visual Debugging

  • Draw hitboxes: Visualize collision boxes
  • Show FPS: Display frame rate on screen
  • Entity count: Show active entity count
  • Memory usage: Display memory statistics

Common Patterns for Debugging

Isolate the Problem

  1. Minimal reproduction: Create smallest code that shows issue
  2. Disable features: Turn off systems one by one
  3. Test incrementally: Add features back one at a time

Check the Basics

  1. Verify initialization: Ensure engine.init() is called
  2. Check scene setup: Verify scene is set and initialized
  3. Test on both platforms: Compare ESP32 vs Native behavior
  4. Review recent changes: What changed before the issue?

Use Logging

#define DEBUG_MODE

#ifdef DEBUG_MODE
    #define DEBUG_LOG(x) Serial.println(x)
#else
    #define DEBUG_LOG(x)
#endif

// Usage
DEBUG_LOG("Entity created");
DEBUG_LOG("Collision detected");

Getting Help

If you can't resolve an issue:

  1. Check documentation: Review relevant guides
  2. Search examples: Look at example games
  3. Review code: Check engine source code
  4. Community: Ask on Discord or GitHub
  5. Report issue: Create detailed bug report

Bug Report Template

When reporting issues, include:

  • Platform: ESP32 or Native
  • Hardware: Display type, ESP32 model
  • Code: Minimal reproduction code
  • Error messages: Full error output
  • Expected behavior: What should happen
  • Actual behavior: What actually happens
  • Steps to reproduce: How to trigger the issue

See Also


Note: Many issues are configuration-related. Double-check your setup before assuming a bug.