This video features a code review of a user-submitted C++ game built with SDL2, created by a programmer experienced in Unity and C# but new to C++. The reviewer, Cherno, praises the project for its clean structure, functional gameplay, and adherence to good practices, especially considering the difficulties often faced when learning C++'s tooling like CMake. The review covers the project's repository organization (including excellent README and screenshots), common issues with resource loading paths in Visual Studio, and the game's polished user interface and mechanics. Cherno then dives into the code, providing constructive feedback on C++ specific aspects such as the use of static members vs. class instances for configuration, best practices for string handling and resource loading (e.g., using string_view and arrays instead of std::string and std::map for predictable lists), proper pointer initialization, and the correct application of polymorphism and virtual destructors in base classes. The video highlights that the primary hurdles for new C++ developers often lie in the build system and environment setup rather than the core programming logic.
Summarizing a C++ SDL2 Game Project Review
0:00 Project Introduction: The video begins with a review of a user-submitted C++ game made with SDL2, created by a developer experienced in Unity and C# but new to C++.
0:42 Initial Project Impressions: Cherno praises the project's repository for its well-organized directories, inclusion of a license, a comprehensive README with gameplay screenshots, and clear instructions on how to play, which he suggests should be a requirement for all submissions.
2:02 Resource Loading Issues: The reviewer identifies a common problem with resource loading paths in Visual Studio, where the working directory differs between running from within the IDE versus outside, requiring manual copying of a 'resources' folder. He suggests using post-build steps or setting the working directory to alleviate this.
3:41 Game Polish and Features: The game is shown to be well-polished, featuring functional menus, music selection, arrow key controls, a "boost" mechanic, sound effects, and a debug UI accessible via the Tab key.
4:22 Usability Feedback: Minor suggestions for improvement include making the game window resizable (or full screen) and adding a back button in menus.
6:41 Clean Main Function: The main function is lauded for its simplicity and clean structure, adhering to the C++ standard where return 0 is optional.
Class Layout: Cherno suggests a preferred class organization with public, private static, private method, and private member sections for better readability.
Static vs. Instance Members (Config): He advises against using static variables for configuration, instead recommending an instance-based approach within the main game class, potentially accessible globally via a singleton pattern for cleaner, more explicit access.
Dynamic Resource Paths: Recommends using a separate config file for dynamic resource paths instead of compiler definitions to avoid recompilation on changes.
String Handling: Advocates for std::string_view over std::string for read-only strings to improve performance and memory usage.
Asset Lists: Suggests using std::array instead of std::vector for fixed-size lists of assets and maps (std::map or std::unordered_map) with human-readable string IDs for textures, rather than integer indices, to prevent issues when inserting new assets.
Raw Pointers: It's acceptable to use raw pointers for C-style APIs like SDL, but they should always be initialized to nullptr.
Smart Pointers (std::unique_ptr): Explicitly setting std::unique_ptr to nullptr upon declaration is unnecessary as their constructors handle default initialization. nullptr should be used instead of NULL.
21:27 UI Button Data Structure: Discusses the use of std::map<int, MainMenuButton> for UI buttons, suggesting an std::array or std::vector would be more appropriate for a predictable, ordered list of elements due to better iteration performance and memory locality.
24:46 Header File Management: Emphasizes the importance of including header files in the project structure (e.g., in CMake) to ensure they are searchable and properly handled by IDE features.
Virtual Destructors: Highlights the critical importance of a virtual destructor for any base class intended for subclassing to prevent memory leaks.
Empty Functions: Recommends declaring empty virtual functions directly in the header for leaner code.
26:01 C++ Standard Features: Points out that with C++17 and later, inline static can be used for static member variables declared in headers, eliminating the need for separate definitions in .cpp files.
27:01 Entity Component System (ECS) vs. Inheritance: Discusses the trade-offs between an inheritance-based entity model and an ECS. For a simple game, the current inheritance model is deemed appropriate and easy to understand, avoiding unnecessary complexity.
28:23 Overall Conclusion: The project is a "very, very good start with C++," with the core programming logic and rendering being well-executed. The main challenges for new C++ developers typically lie in understanding the build system (CMake), linking libraries (SDL), and managing compiler include paths and pre-processor definitions.