Files
spacetris/docs/PERFORMANCE_OPTIMIZATION.md
Gregor Klevze 66099809e0 feat: implement textured line clear effects and refine UI alignment
- **Visual Effects**: Upgraded line clear particles to use the game's block texture instead of simple circles, matching the reference web game's aesthetic.
- **Particle Physics**: Tuned particle velocity, gravity, and fade rates for a more dynamic explosion effect.
- **Rendering Integration**: Updated [main.cpp](cci:7://file:///d:/Sites/Work/tetris/src/main.cpp:0:0-0:0) and `GameRenderer` to pass the block texture to the effect system and correctly trigger animations upon line completion.
- **Menu UI**: Fixed [MenuState](cci:1://file:///d:/Sites/Work/tetris/src/states/MenuState.cpp:19:0-19:55) layout calculations to use fixed logical dimensions (1200x1000), ensuring consistent centering and alignment of the logo, buttons, and settings icon across different window sizes.
- **Code Cleanup**: Refactored `PlayingState` to delegate effect triggering to the rendering layer where correct screen coordinates are available.
2025-11-21 21:19:14 +01:00

4.1 KiB

Performance Optimization Recommendations

Current Performance Analysis

Memory Management

  • Good: Proper RAII patterns, smart pointers
  • Improvement: Object pooling for frequently created/destroyed objects

Rendering Performance

  • Current: SDL3 with immediate mode rendering
  • Optimization Opportunities: Batch rendering, texture atlasing

Game Logic Performance

  • Current: Simple collision detection, adequate for Tetris
  • Good: Efficient board representation using flat array

Specific Optimizations

1. Object Pooling for Game Pieces

// src/gameplay/PiecePool.h
class PiecePool {
private:
    std::vector<std::unique_ptr<Piece>> available;
    std::vector<std::unique_ptr<Piece>> inUse;
    
public:
    std::unique_ptr<Piece> acquire(PieceType type);
    void release(std::unique_ptr<Piece> piece);
    void preAllocate(size_t count);
};

2. Texture Atlas for UI Elements

// src/graphics/TextureAtlas.h
class TextureAtlas {
private:
    SDL_Texture* atlasTexture;
    std::unordered_map<std::string, SDL_Rect> regions;
    
public:
    void loadAtlas(const std::string& atlasPath, const std::string& configPath);
    SDL_Rect getRegion(const std::string& name) const;
    SDL_Texture* getTexture() const { return atlasTexture; }
};

3. Batch Rendering System

// src/graphics/BatchRenderer.h
class BatchRenderer {
private:
    struct RenderCommand {
        SDL_Texture* texture;
        SDL_Rect srcRect;
        SDL_Rect dstRect;
    };
    
    std::vector<RenderCommand> commands;
    
public:
    void addSprite(SDL_Texture* texture, const SDL_Rect& src, const SDL_Rect& dst);
    void flush();
    void clear();
};

4. Memory-Efficient Board Representation

// Current: std::array<int, COLS*ROWS> board (40 integers = 160 bytes)
// Optimized: Bitset representation for filled/empty + color array for occupied cells

class OptimizedBoard {
private:
    std::bitset<COLS * ROWS> occupied;  // 25 bytes (200 bits)
    std::array<uint8_t, COLS * ROWS> colors;  // 200 bytes, but only for occupied cells
    
public:
    bool isOccupied(int x, int y) const;
    uint8_t getColor(int x, int y) const;
    void setCell(int x, int y, uint8_t color);
    void clearCell(int x, int y);
};

5. Cache-Friendly Data Structures

// Group related data together for better cache locality
struct GameState {
    // Hot data (frequently accessed)
    std::array<uint8_t, COLS * ROWS> board;
    Piece currentPiece;
    int score;
    int level;
    int lines;
    
    // Cold data (less frequently accessed)
    std::vector<PieceType> bag;
    Piece holdPiece;
    bool gameOver;
    bool paused;
};

Performance Measurement

1. Add Profiling Infrastructure

// src/core/Profiler.h
class Profiler {
private:
    std::unordered_map<std::string, std::chrono::high_resolution_clock::time_point> startTimes;
    std::unordered_map<std::string, double> averageTimes;
    
public:
    void beginTimer(const std::string& name);
    void endTimer(const std::string& name);
    void printStats();
};

// Usage:
// profiler.beginTimer("GameLogic");
// game.update(deltaTime);
// profiler.endTimer("GameLogic");

2. Frame Rate Optimization

// Target 60 FPS with consistent frame timing
class FrameRateManager {
private:
    std::chrono::high_resolution_clock::time_point lastFrame;
    double targetFrameTime = 1000.0 / 60.0; // 16.67ms
    
public:
    void beginFrame();
    void endFrame();
    double getDeltaTime() const;
    bool shouldSkipFrame() const;
};

Expected Performance Gains

  1. Object Pooling: 30-50% reduction in allocation overhead
  2. Texture Atlas: 20-30% improvement in rendering performance
  3. Batch Rendering: 40-60% reduction in draw calls
  4. Optimized Board: 60% reduction in memory usage
  5. Cache Optimization: 10-20% improvement in game logic performance

Implementation Priority

  1. High Impact, Low Effort: Profiling infrastructure, frame rate management
  2. Medium Impact, Medium Effort: Object pooling, optimized board representation
  3. High Impact, High Effort: Texture atlas, batch rendering system