Files
spacetris/docs/CODE_ORGANIZATION.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

12 KiB

Code Organization & Structure Improvements

Progress Tracker

Phase 1: Core Reorganization - IN PROGRESS ⚠️

Completed:

  • Created new directory structure (interfaces/, application/, assets/, input/, state/, memory/)
  • Created core interfaces (IRenderer.h, IAudioSystem.h, IAssetLoader.h, IInputHandler.h, IGameRules.h)
  • Created ServiceContainer for dependency injection
  • Moved ApplicationManager to core/application/
  • Moved AssetManager to core/assets/
  • Moved InputManager to core/input/
  • Moved StateManager to core/state/
  • Moved Game files to gameplay/core/
  • Moved Font files to graphics/ui/
  • Moved Starfield files to graphics/effects/
  • Moved RenderManager and GameRenderer to graphics/renderers/
  • Moved LineEffect to gameplay/effects/
  • Cleaned up duplicate files
  • Audio and Scores files already properly located

⚠️ Currently In Progress:

  • Updated critical include paths in main.cpp, state files, graphics renderers
  • Fixed RenderManager duplicate method declarations
  • Resolved GameRenderer.h and LoadingState.cpp include paths
  • ⚠️ Still fixing remaining include path issues (ongoing)
  • ⚠️ Still debugging Game.h redefinition errors (ongoing)

Next Steps:

  • Complete all remaining #include statement updates
  • Resolve Game.h redefinition compilation errors
  • Test successful compilation of both tetris and tetris_refactored targets
  • Update documentation
  • Begin Phase 2 - Interface implementation

Phase 2: Interface Extraction - NOT STARTED

Phase 3: Module Separation - NOT STARTED

Phase 4: Documentation & Standards - NOT STARTED

Current Structure Analysis

Strengths

  • Clear domain separation (core/, gameplay/, graphics/, audio/, etc.)
  • Consistent naming conventions
  • Modern C++ header organization
  • Proper forward declarations

Areas for Improvement

  • ⚠️ Some files in root src/ should be moved to appropriate subdirectories
  • ⚠️ Missing interfaces/contracts
  • ⚠️ Some circular dependencies
  • ⚠️ CMakeLists.txt has duplicate entries

Proposed Directory Restructure

src/
├── core/                           # Core engine systems
│   ├── interfaces/                 # Abstract interfaces (NEW)
│   │   ├── IRenderer.h
│   │   ├── IAudioSystem.h
│   │   ├── IAssetLoader.h
│   │   ├── IInputHandler.h
│   │   └── IGameRules.h
│   ├── application/               # Application lifecycle (NEW)
│   │   ├── ApplicationManager.cpp/h
│   │   ├── ServiceContainer.cpp/h
│   │   └── SystemCoordinator.cpp/h
│   ├── assets/                    # Asset management
│   │   ├── AssetManager.cpp/h
│   │   └── AssetLoader.cpp/h
│   ├── input/                     # Input handling
│   │   └── InputManager.cpp/h
│   ├── state/                     # State management
│   │   └── StateManager.cpp/h
│   ├── memory/                    # Memory management (NEW)
│   │   ├── ObjectPool.h
│   │   └── MemoryTracker.h
│   └── Config.h
│   └── GlobalState.cpp/h
│   └── GravityManager.cpp/h
├── gameplay/                       # Game logic
│   ├── core/                      # Core game mechanics
│   │   ├── Game.cpp/h
│   │   ├── Board.cpp/h            # Extract from Game.cpp
│   │   ├── Piece.cpp/h            # Extract from Game.cpp
│   │   └── PieceFactory.cpp/h     # Extract from Game.cpp
│   ├── rules/                     # Game rules (NEW)
│   │   ├── ClassicTetrisRules.cpp/h
│   │   ├── ModernTetrisRules.cpp/h
│   │   └── ScoringSystem.cpp/h
│   ├── effects/                   # Visual effects
│   │   └── LineEffect.cpp/h
│   └── mechanics/                 # Game mechanics (NEW)
│       ├── RotationSystem.cpp/h
│       ├── KickTable.cpp/h
│       └── BagRandomizer.cpp/h
├── graphics/                       # Rendering and visual
│   ├── renderers/                 # Different renderers
│   │   ├── RenderManager.cpp/h
│   │   ├── GameRenderer.cpp/h
│   │   ├── UIRenderer.cpp/h       # Extract from various places
│   │   └── EffectRenderer.cpp/h   # New
│   ├── effects/                   # Visual effects
│   │   ├── Starfield.cpp/h
│   │   ├── Starfield3D.cpp/h
│   │   └── ParticleSystem.cpp/h   # New
│   ├── ui/                        # UI components
│   │   ├── Font.cpp/h
│   │   ├── Button.cpp/h           # New
│   │   ├── Panel.cpp/h            # New
│   │   └── ScoreDisplay.cpp/h     # New
│   └── resources/                 # Graphics resources
│       ├── TextureAtlas.cpp/h     # New
│       └── SpriteManager.cpp/h    # New
├── audio/                          # Audio system
│   ├── Audio.cpp/h
│   ├── SoundEffect.cpp/h
│   ├── MusicManager.cpp/h         # New
│   └── AudioMixer.cpp/h           # New
├── persistence/                    # Data persistence
│   ├── Scores.cpp/h
│   ├── Settings.cpp/h             # New
│   ├── SaveGame.cpp/h             # New
│   └── Serialization.cpp/h        # New
├── states/                         # Game states
│   ├── State.h                     # Base interface
│   ├── LoadingState.cpp/h
│   ├── MenuState.cpp/h
│   ├── LevelSelectorState.cpp/h
│   ├── PlayingState.cpp/h
│   ├── PausedState.cpp/h          # New
│   ├── GameOverState.cpp/h        # New
│   └── SettingsState.cpp/h        # New
├── network/                        # Future: Multiplayer (NEW)
│   ├── NetworkManager.h
│   ├── Protocol.h
│   └── MultiplayerGame.h
├── utils/                          # Utilities (NEW)
│   ├── Logger.cpp/h
│   ├── Timer.cpp/h
│   ├── MathUtils.h
│   └── StringUtils.h
├── platform/                      # Platform-specific (NEW)
│   ├── Platform.h
│   ├── Windows/
│   ├── Linux/
│   └── macOS/
└── main.cpp                       # Keep original main
└── main_new.cpp                   # Refactored main

Module Dependencies

Clean Dependency Graph

Application Layer:    main.cpp → ApplicationManager
Core Layer:          ServiceContainer → All Managers
Gameplay Layer:      Game → Rules → Mechanics
Graphics Layer:      RenderManager → Renderers → Resources
Audio Layer:         AudioSystem → Concrete Implementations
Persistence Layer:   SaveSystem → Serialization
Platform Layer:      Platform Abstraction (lowest level)

Dependency Rules

  1. No circular dependencies
  2. Higher layers can depend on lower layers only
  3. Use interfaces for cross-layer communication
  4. Platform layer has no dependencies on other layers

Header Organization

1. Consistent Header Structure

// Standard template for all headers
#pragma once

// System includes
#include <vector>
#include <memory>

// External library includes
#include <SDL3/SDL.h>

// Internal includes (from most general to most specific)
#include "core/interfaces/IRenderer.h"
#include "graphics/resources/Texture.h"
#include "MyClass.h"

// Forward declarations
class GameRenderer;
class TextureAtlas;

// Class definition
class MyClass {
    // Public interface first
public:
    // Constructors/Destructors
    MyClass();
    ~MyClass();
    
    // Core functionality
    void update(double deltaTime);
    void render();
    
    // Getters/Setters
    int getValue() const { return value; }
    void setValue(int v) { value = v; }

// Private implementation
private:
    // Member variables
    int value{0};
    std::unique_ptr<GameRenderer> renderer;
    
    // Private methods
    void initializeRenderer();
};

2. Include Guards and PCH

// PrecompiledHeaders.h (NEW)
#pragma once

// Standard library
#include <vector>
#include <memory>
#include <string>
#include <unordered_map>
#include <chrono>
#include <functional>
#include <algorithm>

// External libraries (stable)
#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>

// Common project headers
#include "core/Config.h"
#include "core/interfaces/IRenderer.h"

Code Style Improvements

1. Consistent Naming Conventions

// Classes: PascalCase
class GameRenderer;
class TextureAtlas;

// Functions/Methods: camelCase
void updateGameLogic();
bool isValidPosition();

// Variables: camelCase
int currentScore;
double deltaTime;

// Constants: UPPER_SNAKE_CASE
const int MAX_LEVEL = 30;
const double GRAVITY_MULTIPLIER = 1.0;

// Private members: camelCase with suffix
class MyClass {
private:
    int memberVariable_;  // or m_memberVariable
    static int staticCounter_;
};

2. Documentation Standards

/**
 * @brief Manages the core game state and logic for Tetris
 * 
 * The Game class handles piece movement, rotation, line clearing,
 * and scoring according to classic Tetris rules.
 * 
 * @example
 * ```cpp
 * Game game(startLevel);
 * game.reset(0);
 * game.move(-1);  // Move left
 * game.rotate(1); // Rotate clockwise
 * ```
 */
class Game {
public:
    /**
     * @brief Moves the current piece horizontally
     * @param dx Direction to move (-1 for left, +1 for right)
     * @return true if the move was successful, false if blocked
     */
    bool move(int dx);
    
    /**
     * @brief Gets the current score
     * @return Current score value
     * @note Score never decreases during gameplay
     */
    int score() const noexcept { return score_; }
};

CMake Improvements

1. Modular CMakeLists.txt

# CMakeLists.txt (main)
cmake_minimum_required(VERSION 3.20)
project(tetris_sdl3 LANGUAGES CXX)

# Global settings
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Find packages
find_package(SDL3 CONFIG REQUIRED)
find_package(SDL3_ttf CONFIG REQUIRED)

# Add subdirectories
add_subdirectory(src/core)
add_subdirectory(src/gameplay)
add_subdirectory(src/graphics)
add_subdirectory(src/audio)
add_subdirectory(src/persistence)
add_subdirectory(src/states)

# Main executable
add_executable(tetris src/main.cpp)
target_link_libraries(tetris PRIVATE 
    tetris::core
    tetris::gameplay 
    tetris::graphics
    tetris::audio
    tetris::persistence
    tetris::states
)

# Tests
if(BUILD_TESTING)
    add_subdirectory(tests)
endif()

2. Module CMakeLists.txt

# src/core/CMakeLists.txt
add_library(tetris_core
    ApplicationManager.cpp
    StateManager.cpp
    InputManager.cpp
    AssetManager.cpp
    GlobalState.cpp
    GravityManager.cpp
)

add_library(tetris::core ALIAS tetris_core)

target_include_directories(tetris_core 
    PUBLIC ${CMAKE_SOURCE_DIR}/src
    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
)

target_link_libraries(tetris_core 
    PUBLIC SDL3::SDL3 SDL3_ttf::SDL3_ttf
)

# Export for use by other modules
target_compile_features(tetris_core PUBLIC cxx_std_20)

Implementation Timeline

Phase 1: Core Reorganization (Week 1-2)

  1. Create new directory structure
  2. Move files to appropriate locations
  3. Update CMakeLists.txt files
  4. Fix include paths

Phase 2: Interface Extraction (Week 3-4)

  1. Create interface headers
  2. Update implementations to use interfaces
  3. Add dependency injection container

Phase 3: Module Separation (Week 5-6)

  1. Split large classes (Game, ApplicationManager)
  2. Create separate CMake modules
  3. Establish clean dependency graph

Phase 4: Documentation & Standards (Week 7-8)

  1. Add comprehensive documentation
  2. Implement coding standards
  3. Add static analysis tools
  4. Update build scripts

Benefits

  1. Maintainability: Clear module boundaries and responsibilities
  2. Testability: Easy to mock and test individual components
  3. Scalability: Easy to add new features without affecting existing code
  4. Team Development: Multiple developers can work on different modules
  5. Code Reuse: Modular design enables component reuse