Welcome to the B-Lec project! This guide will help you understand the codebase and contribute effectively.
Clone the repository:
git clone https://github.com/yourusername/B-Lec.git
cd B-LecCreate build directory:
mkdir build
cd buildConfigure with tests enabled (recommended for development):
# Windows
cmake -G "Visual Studio 17 2022" -A x64 -DBUILD_TESTS=ON ..
# Linux/macOS
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON ..Build:
cmake --build .Run tests:
cmake --build . --target run_tests- include/: Public API headers, organized by module
- src/: Implementation files, same organization as include/
- code_testing/: Unit tests, one per module
- CMakeLists.txt: Build configuration
- ARCHITECTURE.md: Detailed architecture documentation
- BUILDING.md: Build instructions for users
Window Module (include/window/window_manager.h)
- Manages GLFW window lifecycle
- Handles window events and properties
- ~100 lines of code per file
Input Module (include/input/input_handler.h)
- Tracks keyboard and mouse state
- Provides input querying APIs
- ~150 lines of code per file
Render Module (include/render/)
renderer.h: Basic OpenGL operationsfont.h: Bitmap font rendering- ~200 lines of code total
Debug Module (include/debug/debug_overlay.h)
- Displays real-time debug information
- Manages debug state and rendering
- ~150 lines of code per file
Header files (include your guards at the top):
#ifndef BLEC_MODULE_CLASS_H
#define BLEC_MODULE_CLASS_H
namespace blec {
namespace module {
/// Brief description of what this class does
class ClassName {
public:
/// Explain what this does
bool PublicMethod();
private:
// Private members start with underscore
int member_;
};
} // namespace module
} // namespace blec
#endif // BLEC_MODULE_CLASS_HImplementation files:
#include "module/class.h"
#include <necessary_headers>
namespace blec {
namespace module {
// Implementation with clear comments explaining logic
bool ClassName::PublicMethod() {
// Do something
return true;
}
} // namespace module
} // namespace blec✅ Good:
class WindowManager { };
bool InitializeGLFW();
void GetFramebufferSize(int* width, int* height);
const int kWindowWidth = 1280;
std::string window_title_;❌ Bad:
class WindowMgr { }; // Don't abbreviate
bool init_glfw(); // Methods should be PascalCase
void getFramebufferSize(int* w, int* h); // Avoid abbreviations
#define WINDOW_WIDTH 1280 // Use constexpr or const
std::string windowTitle; // Member variables should be snake_case with _- Add declaration to header:
/// Returns the current frame rate in frames per second
double GetCurrentFPS() const;- Implement in source file:
double WindowManager::GetCurrentFPS() const {
// Implementation with logic comments if complex
return fps_;
}- Write tests:
TEST_CASE(TestGetCurrentFPS) {
WindowManager wm;
ASSERT_GE(wm.GetCurrentFPS(), 0.0);
ASSERT_LE(wm.GetCurrentFPS(), 1000.0); // Reasonable upper bound
}- Check all usages with grep/search:
grep -r "FunctionName" src/ include/- Update signature if needed in header
- Update implementation in source
- Update tests to verify behavior
- Update documentation in comments
Example: Adding a "World" module for game world management
- Create header
include/world/world.h:
#ifndef BLEC_WORLD_WORLD_H
#define BLEC_WORLD_WORLD_H
namespace blec {
namespace world {
class World {
public:
World();
~World();
bool Initialize();
void Update(double deltaTime);
void Shutdown();
private:
// Members...
};
} // namespace world
} // namespace blec
#endif // BLEC_WORLD_WORLD_H-
Create implementation
src/world/world.cpp -
Update CMakeLists.txt:
add_executable(blec
# ... existing sources ...
src/world/world.cpp
)-
Create tests
code_testing/world/test_world.cpp -
Update test CMakeLists.txt:
set(TEST_SOURCES
# ... existing tests ...
world/test_world.cpp
)- Integrate in main.cpp if needed
The render module now supports 3D graphics with camera, mesh, and matrix operations:
- Camera (
camera.h): Manages viewpoint and controls - Mesh (
mesh.h): Stores geometry and renders 3D objects - Renderer 3D methods: Perspective projection and state management
Basic setup:
#include "render/camera.h"
blec::render::Camera camera;
// Initialize with position and target
camera.Initialize(glm::vec3(0.0f, 0.0f, 5.0f), // Camera position
glm::vec3(0.0f, 0.0f, 0.0f)); // Look-at target
// Configure speeds (optional, have sensible defaults)
camera.SetMovementSpeed(5.0f); // Units per second
camera.SetRotationSpeed(0.005f); // Radians per pixelHandle input in main loop:
// WASD movement
if (input_handler.IsKeyDown(GLFW_KEY_W)) {
camera.MoveForward(delta_time * 5.0);
}
if (input_handler.IsKeyDown(GLFW_KEY_S)) {
camera.MoveForward(-delta_time * 5.0);
}
if (input_handler.IsKeyDown(GLFW_KEY_A)) {
camera.MoveRight(-delta_time * 5.0);
}
if (input_handler.IsKeyDown(GLFW_KEY_D)) {
camera.MoveRight(delta_time * 5.0);
}
// Space/Ctrl for up/down
if (input_handler.IsKeyDown(GLFW_KEY_SPACE)) {
camera.MoveUp(delta_time * 5.0);
}
if (input_handler.IsKeyDown(GLFW_KEY_LEFT_CONTROL)) {
camera.MoveUp(-delta_time * 5.0);
}
// Mouse look
double mouse_dx = 0.0, mouse_dy = 0.0;
input_handler.GetMouseLookDelta(&mouse_dx, &mouse_dy);
camera.Yaw(mouse_dx * 0.005f);
camera.Pitch(-mouse_dy * 0.005f); // Inverted Y for natural look
// Update camera state
camera.Update(delta_time);Get camera matrices for rendering:
glm::mat4 view = camera.GetViewMatrix();
renderer.SetView(view);Create a colored cube:
#include "render/mesh.h"
// Create a cube with 6 different colored faces
blec::render::Mesh cube = blec::render::Mesh::CreateCube();
// Enable back-face culling for optimization
cube.SetBackfaceCulling(true);Render a mesh:
// In render loop:
renderer.Begin3D(window_width, window_height, 45.0f); // 45° FOV
// Set up matrices
glm::mat4 view = camera.GetViewMatrix();
renderer.SetView(view);
glm::mat4 model = glm::mat4(1.0f); // Identity = object at origin
renderer.SetModel(model);
// Enable features
renderer.EnableDepthTest();
renderer.EnableBackfaceCulling();
// Render the geometry
cube.Render();
renderer.DisableBackfaceCulling();
renderer.End3D();#include "render/camera.h"
#include "render/mesh.h"
// Setup phase
blec::render::Camera camera;
camera.Initialize(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f));
blec::render::Mesh cube = blec::render::Mesh::CreateCube();
cube.SetBackfaceCulling(true);
// Main loop
while (!window_manager.ShouldClose()) {
// ... input handling (see above) ...
// Update camera
camera.Update(delta_time);
// Render 3D scene
renderer.Begin3D(fb_width, fb_height, 45.0f);
renderer.SetView(camera.GetViewMatrix());
// Render cube
glm::mat4 cube_model = glm::mat4(1.0f);
renderer.SetModel(cube_model);
renderer.EnableDepthTest();
renderer.EnableBackfaceCulling();
cube.Render();
renderer.End3D();
// Render 2D overlay on top
renderer.Begin2D(fb_width, fb_height);
// ... render debug overlay, HUD, etc ...
renderer.End2D();
window_manager.SwapBuffers();
input_handler.ResetMouseDelta();
}Coordinate System:
- X-axis: Points to the right
- Y-axis: Points up
- Z-axis: Points towards the camera (right-hand rule)
Camera Movement:
- Use
MoveForward()for depth (along view direction) - Use
MoveRight()for lateral movement (strafe) - Use
MoveUp()for vertical movement - Use
Yaw()to rotate left/right - Use
Pitch()to look up/down
Mesh Colors: The default cube has 6 faces with different colors:
- Front (Z+): Red
- Back (Z-): Green
- Right (X+): Blue
- Left (X-): Yellow
- Top (Y+): Cyan
- Bottom (Y-): Magenta
Performance:
- Always enable
EnableBackfaceCulling()to skip rendering hidden faces - Enable
EnableDepthTest()so objects render in correct order - Disable culling/depth before rendering 2D overlay
Common Issues:
- White/blank screen: Check camera position isn't inside the cube
- Inverted controls: Change sign of mouse delta in Pitch
- Flickering: Check depth test is enabled before rendering 3D
- Objects disappear: Check near/far planes in Begin3D FOV range objects
The BlockSystem manages a 3D voxel grid where each voxel (block) can be air (empty) or solid. It includes frustum culling to efficiently determine which blocks are visible from the camera's perspective.
Key concepts:
- Block: A single voxel with a type (0 = air, 1+ = solid types)
- Grid: 3D array of blocks with configurable dimensions
- AABB: Axis-aligned bounding box for each block
- Frustum: 6-plane view frustum extracted from camera matrices
- Visibility: Blocks that intersect the view frustum
Initialize the block system:
#include "world/block_system.h"
blec::world::BlockSystem block_system;
// Initialize with grid dimensions and block size
block_system.Initialize(32, // Width (X)
32, // Height (Y)
32, // Depth (Z)
1.0f); // Block size in world unitsCreate some test blocks:
// Creates a 3×3×3 cube of solid blocks at the grid center
block_system.CreateTestBlocks();
// Get block counts
int total = block_system.GetTotalBlockCount(); // Non-air blocks
int visible = block_system.GetVisibleBlockCount(); // Blocks in frustumGet and set blocks:
// Set a block (returns true if successful)
bool success = block_system.SetBlock(10, 5, 10, 1); // Set solid block at (10,5,10)
// Get block type
uint8_t block_type = block_system.GetBlock(10, 5, 10);
if (block_type == 0) {
// It's air
} else {
// It's a solid block
}
// Check if position is valid
if (x >= 0 && x < 32 && y >= 0 && y < 32 && z >= 0 && z < 32) {
// Position is within bounds
}Convert between grid and world coordinates:
// Get world-space position of a block's center
glm::vec3 world_pos = block_system.GetBlockWorldPosition(10, 5, 10);
// Get bounding box of a block
blec::world::AABB bbox = block_system.GetBlockAABB(10, 5, 10);
// bbox.min and bbox.max are glm::vec3Update visibility each frame:
// In your main loop:
// 1. Create projection matrix
int fb_width, fb_height;
window_manager.GetFramebufferSize(&fb_width, &fb_height);
float aspect = static_cast<float>(fb_width) / fb_height;
glm::mat4 projection = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 100.0f);
// 2. Get view matrix from camera
glm::mat4 view = camera.GetViewMatrix();
// 3. Extract frustum from matrices
block_system.ExtractFrustum(view, projection);
// 4. Update which blocks are visible
block_system.UpdateVisibility();
// 5. Query results
int total_blocks = block_system.GetTotalBlockCount();
int visible_blocks = block_system.GetVisibleBlockCount();Pass data to debug overlay:
debug_overlay.SetBlockCounts(total_blocks, visible_blocks);#include "world/block_system.h"
#include "render/camera.h"
// Setup phase
blec::world::BlockSystem block_system;
block_system.Initialize(32, 32, 32, 1.0f);
block_system.CreateTestBlocks();
blec::render::Camera camera;
camera.Initialize(glm::vec3(0.0f, 15.0f, 30.0f), glm::vec3(16.0f, 16.0f, 16.0f));
// Main loop
while (!window_manager.ShouldClose()) {
// ... handle input and update camera ...
// Update frustum and visibility
int fb_width, fb_height;
window_manager.GetFramebufferSize(&fb_width, &fb_height);
float aspect = static_cast<float>(fb_width) / fb_height;
glm::mat4 projection = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 100.0f);
glm::mat4 view = camera.GetViewMatrix();
block_system.ExtractFrustum(view, projection);
block_system.UpdateVisibility();
// Update debug info
glm::vec3 cam_pos = camera.GetPosition();
debug_overlay.SetCameraPosition(cam_pos.x, cam_pos.y, cam_pos.z);
debug_overlay.SetCameraOrientation(camera.GetYaw(), camera.GetPitch());
debug_overlay.SetBlockCounts(
block_system.GetTotalBlockCount(),
block_system.GetVisibleBlockCount()
);
// ... rendering ...
}Time Complexity:
GetBlock()/SetBlock(): O(1) - Direct array accessExtractFrustum(): O(1) - Matrix operations and plane extractionUpdateVisibility(): O(N) where N = total non-air blocksGetBlockAABB(): O(1) - Simple coordinate math
Memory Usage:
- Grid storage: width × height × depth bytes (1 byte per block)
- Example: 32×32×32 grid = 32,768 bytes (~32 KB)
Optimization Tips:
- Only call
UpdateVisibility()when camera moves or blocks change - Grid dimensions should be powers of 2 for cache efficiency
- Test blocks are positioned at grid center, ensuring they're visible from default camera position
Building structures:
// Create a floor
for (int x = 0; x < 32; x++) {
for (int z = 0; z < 32; z++) {
block_system.SetBlock(x, 0, z, 1); // Solid block at y=0
}
}
// Create a wall
for (int y = 0; y < 10; y++) {
for (int x = 0; x < 32; x++) {
block_system.SetBlock(x, y, 0, 1); // Wall at z=0
}
}Checking visibility before rendering:
for (int z = 0; z < 32; z++) {
for (int y = 0; y < 32; y++) {
for (int x = 0; x < 32; x++) {
uint8_t block = block_system.GetBlock(x, y, z);
if (block == 0) continue; // Skip air
// Get world position and AABB
glm::vec3 pos = block_system.GetBlockWorldPosition(x, y, z);
blec::world::AABB bbox = block_system.GetBlockAABB(x, y, z);
// Only render if visible (already filtered by UpdateVisibility)
// Your rendering code here...
}
}
}No blocks visible:
- Check camera position isn't too far from blocks
- Verify frustum near/far planes encompass block positions
- Ensure
UpdateVisibility()is called afterExtractFrustum() - Check projection matrix field of view isn't too narrow
All blocks always visible:
- Verify frustum is being extracted with correct matrices
- Check that view and projection matrices are properly computed
- Ensure projection matrix matches the one used for rendering
Incorrect block counts:
- Use
CreateTestBlocks()for known 27-block configuration - Verify grid is initialized before setting blocks
- Check bounds when setting blocks (out-of-bounds calls return false)
The UIManager handles all user interface elements including the crosshair, pause menu, and mouse lock state. It manages game state transitions between playing and paused modes.
Key concepts:
- Crosshair: Always visible targeting reticle in screen center
- Pause Menu: Overlay with buttons for Resume and Quit
- Mouse Lock: GLFW cursor mode toggling for camera control
- Button Interaction: Hit detection for menu buttons
Initialize the UI manager:
#include "ui/ui_manager.h"
blec::ui::UIManager ui_manager;
// Initialize with window dimensions
int window_width = 1280;
int window_height = 720;
ui_manager.Initialize(window_width, window_height);Toggle pause state:
// Detect ESC key press
static bool esc_was_down = false;
if (input_handler.IsKeyDown(GLFW_KEY_ESCAPE)) {
if (!esc_was_down) {
ui_manager.TogglePause();
esc_was_down = true;
}
} else {
esc_was_down = false;
}
// Or set pause state explicitly
ui_manager.SetPaused(true); // Pause
ui_manager.SetPaused(false); // Resume
// Check pause state
if (ui_manager.IsPaused()) {
// Game is paused - show menu, unlock mouse
}Update mouse lock based on pause state:
GLFWwindow* window = window_manager.GetHandle();
if (ui_manager.IsPaused()) {
// Unlock mouse - show cursor, normal behavior
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
} else {
// Lock mouse - hide cursor, infinite movement for camera
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}Mouse lock modes:
GLFW_CURSOR_NORMAL: Cursor visible, normal behavior (for menus)GLFW_CURSOR_DISABLED: Cursor hidden, locked to window center (for gameplay)
Handle mouse clicks on menu buttons:
if (ui_manager.IsPaused()) {
// Get cursor position
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
// Check for left mouse button click
if (input_handler.IsMouseButtonDown(GLFW_MOUSE_BUTTON_LEFT)) {
auto action = ui_manager.HandleMouseClick(
static_cast<float>(mouse_x),
static_cast<float>(mouse_y)
);
if (action == blec::ui::UIManager::ButtonAction::Resume) {
ui_manager.TogglePause(); // Resume game
} else if (action == blec::ui::UIManager::ButtonAction::Quit) {
window_manager.SetShouldClose(true); // Exit app
}
// action == ButtonAction::None means no button was clicked
}
}Render crosshair and pause menu:
// In your main loop rendering phase:
// Render 2D overlay
renderer.Begin2D(fb_width, fb_height);
// Render crosshair (always visible)
ui_manager.RenderCrosshair(renderer);
// Render pause menu (only shown when paused)
ui_manager.RenderPauseMenu(renderer, font);
// ... render other UI elements (debug overlay, HUD, etc.) ...
renderer.End2D();Update UI when window size changes:
// If window is resizable, update UI dimensions
int new_width, new_height;
window_manager.GetFramebufferSize(&new_width, &new_height);
ui_manager.UpdateScreenDimensions(new_width, new_height);#include "ui/ui_manager.h"
#include "window/window_manager.h"
#include "input/input_handler.h"
#include "render/renderer.h"
#include "render/font.h"
// Setup phase
blec::ui::UIManager ui_manager;
ui_manager.Initialize(1280, 720);
blec::window::WindowManager window_manager;
blec::input::InputHandler input_handler;
blec::render::Renderer renderer;
blec::render::BitmapFont font;
// ... initialize other systems ...
static bool esc_was_down = false;
// Main loop
while (!window_manager.ShouldClose()) {
window_manager.PollEvents();
// Handle ESC to toggle pause
if (input_handler.IsKeyDown(GLFW_KEY_ESCAPE)) {
if (!esc_was_down) {
ui_manager.TogglePause();
esc_was_down = true;
}
} else {
esc_was_down = false;
}
// Update mouse lock
GLFWwindow* window = window_manager.GetHandle();
if (ui_manager.IsPaused()) {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
// Handle pause menu clicks
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
if (input_handler.IsMouseButtonDown(GLFW_MOUSE_BUTTON_LEFT)) {
auto action = ui_manager.HandleMouseClick(
static_cast<float>(mouse_x),
static_cast<float>(mouse_y)
);
if (action == blec::ui::UIManager::ButtonAction::Resume) {
ui_manager.TogglePause();
} else if (action == blec::ui::UIManager::ButtonAction::Quit) {
window_manager.SetShouldClose(true);
}
}
} else {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// ... handle gameplay: camera movement, etc. ...
}
// ... update game logic ...
// Rendering
int fb_width, fb_height;
window_manager.GetFramebufferSize(&fb_width, &fb_height);
renderer.SetViewport(fb_width, fb_height);
renderer.Clear(0.1f, 0.15f, 0.2f, 1.0f);
// ... render 3D scene ...
// Render 2D UI
renderer.Begin2D(fb_width, fb_height);
ui_manager.RenderCrosshair(renderer);
ui_manager.RenderPauseMenu(renderer, font);
renderer.End2D();
window_manager.SwapBuffers();
}Adjust crosshair appearance (in ui_manager.h):
kCrosshairSize: Line length (default 20px)kCrosshairThickness: Line width (default 2px)- Modify color in
RenderCrosshair()viaSetColor(r, g, b, a)
Adjust pause menu layout (in ui_manager.h):
kButtonWidth: Button width (default 150px)kButtonHeight: Button height (default 40px)kButtonSpacing: Vertical gap between buttons (default 20px)kMenuBackgroundAlpha: Background opacity (default 0.7)
Button colors (in RenderPauseMenu()):
- Resume button: Green
(0.2, 0.6, 0.2, 0.9) - Quit button: Red
(0.6, 0.2, 0.2, 0.9) - Background: Black
(0.0, 0.0, 0.0, 0.7)
Freeze gameplay when paused:
if (!ui_manager.IsPaused()) {
// Only update game logic when not paused
camera.Update(delta_time);
block_system.UpdateVisibility();
// ... other game updates ...
}Both ESC and button resume:
// ESC key
if (esc_was_down && !input_handler.IsKeyDown(GLFW_KEY_ESCAPE)) {
ui_manager.TogglePause();
}
// Resume button
auto action = ui_manager.HandleMouseClick(x, y);
if (action == UIManager::ButtonAction::Resume) {
ui_manager.TogglePause();
}Custom button actions:
// Add more buttons by extending ButtonAction enum
// Modify RenderPauseMenu() to draw additional buttons
// Update HandleMouseClick() to detect new button hitsMouse not locking:
- Verify GLFW window is created and current
- Check
!ui_manager.IsPaused()before settingGLFW_CURSOR_DISABLED - Ensure GLFW version 3.4+ supports cursor modes
Crosshair not visible:
- Check
RenderCrosshair()is called in 2D rendering phase - Verify renderer is in 2D mode via
Begin2D() - Ensure alpha blending is enabled for transparency
Pause menu not showing:
- Verify
ui_manager.IsPaused()returns true - Check
RenderPauseMenu()is called afterBegin2D() - Ensure screen dimensions are set via
Initialize()
Buttons not responding:
- Verify mouse coordinates are in screen space (not normalized)
- Check
glfwGetCursorPos()provides correct values - Ensure click detection happens when paused
ESC closes instead of pausing:
- Remove any
window_manager.SetShouldClose()calls tied to ESC - Use toggle detection with
esc_was_downflag - Verify
TogglePause()is called, notSetShouldClose()
❌ Bad test:
TEST_CASE(TestEverything) {
MyClass obj;
obj.DoSomething(); // Unclear what we're testing
}✅ Good test:
TEST_CASE(TestInitialization) {
MyClass obj;
ASSERT_TRUE(obj.Initialize());
ASSERT_TRUE(obj.IsInitialized());
}
TEST_CASE(TestInvalidInput) {
MyClass obj;
ASSERT_FALSE(obj.SetValue(-1)); // Negative values invalid
}
TEST_CASE(TestStateTransition) {
MyClass obj;
obj.Start();
ASSERT_TRUE(obj.IsRunning());
obj.Stop();
ASSERT_FALSE(obj.IsRunning());
}- One test class/function per test case
- Test name starts with "Test"
- Test structure: Setup → Execute → Verify
- Clear assertion messages
- Test both success and error cases
Test locally before committing:
cmake --build . --target run_testsFix any failing tests immediately - they help catch regressions.
- Build with debug symbols:
cmake -DCMAKE_BUILD_TYPE=Debug ..- Run in debugger:
# GDB (Linux/macOS)
gdb ./bin/blec
# Visual Studio (Windows)
# Open .sln and press F5- Add debug logging:
std::fprintf(stderr, "DEBUG: variable value = %d\n", value);- Update InputHandler (if needed) to recognize the key
- Add handler in main.cpp:
if (input_handler.IsKeyDown(GLFW_KEY_F3)) {
// Your code here
}- Document in controls section of README
-
Profile the application:
- Use platform profilers (perf on Linux, Instruments on macOS, VTune on Windows)
- Check FPS in debug overlay
-
Identify bottleneck:
- Is it CPU? GPU? Rendering?
-
Optimize the bottleneck:
- Don't premature optimize
- Measure before and after
- Consider trade-offs (readability vs performance)
-
Verify with tests that optimization doesn't break functionality
Always explain "why", not just "what":
// ❌ Not helpful - the code is obvious
int width = 800; // Set width to 800
// ✅ Helpful - explains the reason
// Use 1280 width to match primary monitor resolution on modern laptops
constexpr int kWindowWidth = 1280;If you make structural changes:
- Update ARCHITECTURE.md with new design
- Update diagrams if needed
- Update module descriptions
- Update data flow if changed
If you add user-facing features:
- Update README.md with new features
- Update BUILDING.md if build process changed
- Update controls in BUILDING.md if input changed
Before submitting a pull request:
- Code compiles without warnings
- All tests pass
- New code has unit tests
- Code follows naming conventions
- Comments explain complex logic
- No hardcoded paths or magic numbers
- Documentation updated
- Commit messages are clear
Search for a function:
grep -r "FunctionName" .Find all TODOs:
grep -r "TODO" src/ include/Count lines of code:
find src include -name "*.cpp" -o -name "*.h" | xargs wc -lFormat code (if using clang-format):
find src include -name "*.cpp" -o -name "*.h" | xargs clang-format -iCheck for compilation warnings:
# Linux/macOS
cmake -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wpedantic -Werror" ..
# Then build and fix warnings- Read the header file comments
- Check the ARCHITECTURE.md section
- Look at the test file for usage examples
- Search for usages in main.cpp or other modules
- Check if there's a failing test
- Add debug output to identify the problem
- Write a test that reproduces the issue
- Fix the issue
- Verify test now passes
- Create an issue describing the feature
- Discuss design with maintainers
- Create a branch for the feature
- Follow the guidelines above
- Submit PR with reference to the issue
- Respond to feedback constructively
- Ask questions if feedback is unclear
- Mark conversations as resolved when done
- Thank reviewer for their time
- Look for clarity and correctness
- Suggest improvements kindly
- Ask questions to understand intent
- Approve when satisfied
- BUILDING.md: How to build the project
- ARCHITECTURE.md: System design and module details
- code_testing/README.md: Testing framework and examples
- Include file comments: Method documentation
- Test files: Usage examples and edge cases
Good luck! Happy coding! 🚀