# Coding Standards - Orbital Mechanics Simulation
## Code Style
- **C-style C++**: structs and functions only, NO classes or templates
- **File extensions**: Use `.cpp` extensions for all source files (for future C++ features if needed)
- **Include guards**: All headers use include guards (e.g., `#ifndef MODULE_NAME_H`)
- **Function design**: Small, focused functions with single responsibilities
```cpp
// Header file with include guard
#ifndef ORBITAL_MECHANICS_H
#define ORBITAL_MECHANICS_H
struct OrbitalElements {
double semi_major_axis;
double eccentricity;
double true_anomaly;
};
OrbitalElements propagate_orbital_elements(OrbitalElements elements, double dt, double parent_mass);
#endif
```
## Naming Conventions
**Struct names**: PascalCase
```cpp
struct CelestialBody { };
struct OrbitalElements { };
struct Spacecraft { };
```
**Function names**: snake_case
```cpp
propagate_orbital_elements()
find_dominant_body()
update_bodies_physics()
```
**Member variables**: snake_case
```cpp
global_position
local_velocity
parent_index
```
**Constants**: UPPER_CASE
```cpp
PARABOLIC_TOLERANCE
MIN_MASS_RATIO
```
**Enum values**: UPPER_CASE with prefix
```cpp
enum BurnDirection { BURN_PROGRADE, BURN_RETROGRADE };
enum TriggerType { TRIGGER_TIME, TRIGGER_TRUE_ANOMALY };
```
## Comments
- **Minimal comments**: Code should be self-documenting
- **Non-obvious logic only**: Comment only what cannot be inferred from the code
- **No decorative blocks**: No `===`, `---`, or ASCII art comment blocks
```cpp
// Good: minimal comments
if (vec3_distance(pos, parent_pos) > soi_radius) {
return 0;
}
// Bad: excessive decoration
// ========================================
// SOI Check Function
// ========================================
// This function checks if we're in SOI
// ========================================
```
## Whitespace
- **No trailing whitespace**: All files (including markdown) must not have trailing whitespace
- **Pre-commit hook**: Automatically strips trailing whitespace
- **Markdown line breaks**: Use `
` tag instead of two trailing spaces
```markdown
Good:
Line 1
Line 2
Bad:
Line 2
Line 4
```
## Memory Management
- **Dynamic arrays**: Use `malloc` and `free`
- **Struct-based design**: No RAII or smart pointers
- **Manual cleanup**: Destroy functions handle cleanup
```cpp
// Allocation
SimulationState* sim = malloc(sizeof(SimulationState));
sim->bodies = malloc(max_bodies * sizeof(CelestialBody));
// Cleanup
void destroy_simulation(SimulationState* sim) {
free(sim->bodies);
free(sim->spacecraft);
free(sim);
}
```
## Code Organization
**Layer separation**: Physics, Simulation, Configuration, Rendering layers
**Physics module independence**: Physics functions use parameter-based signatures, no dependencies on simulation structures
```cpp
// Good: parameter-based, independent
Vec3 vec3_add(Vec3 a, Vec3 b);
Mat3 mat3_rotation_orbital(double omega, double i, double omega_upper);
// Avoid: depends on specific structures
Vec3 compute_global_position(CelestialBody* body); // Simulation layer
```
**Headers vs implementation**:
- Headers (`.h`): Declarations only
- Implementation (`.cpp`): Function definitions
## Floating-Point Comparisons (Testing)
- **Use `WithinAbs()`**: Required for floating-point comparisons
- **Avoid `Approx()`**: Deprecated in Catch2
- **Required header**: ``
```cpp
#include
TEST_CASE("orbital energy conservation") {
double energy = calculate_total_energy(sim);
REQUIRE_THAT(energy, WithinAbs(expected, 1e-6));
}
```
## Git Workflow
- **Small commits**: Logical separation of changes
- **Concise messages**: One-line commit messages preferred
- **Build before commit**: Run `make && make test` before committing
```bash
# Verify build and tests pass
make && make test
# Commit with descriptive message
git add .
git commit -m "add parabolic orbit propagation"
```
## Build System
**Makefile targets**:
- `make` or `make all`: Build simulation
- `make test`: Build and run automated tests
- `make clean`: Remove build artifacts
- `make rebuild`: Clean and rebuild
**Default configuration**:
- Time step: 60 seconds for solar system scale
- Physics steps per frame: 100 (default)
- Simulation time per frame: 60s × 100 = 6000 seconds at 1× speed
```bash
# Full build
make
# Run tests
make test
# Clean and rebuild
make rebuild
```
## Physics Considerations
**Time step**: 60 seconds for solar system scale
**Circular orbit velocity**:
```cpp
v = sqrt(G * M / r)
```
**Sphere of Influence (SOI)**: Hill sphere approximation
```cpp
r_soi = a * (m / M)^(2/5)
```
**SOI transitions**: 0.5× distance hysteresis to prevent oscillation
**Parabolic orbits**: Escape velocity
```cpp
v² = 2GM / r
```
**Hyperbolic orbits**: Positive total energy with asymptotic velocity at infinity
**Analytical propagation**: Uses Kepler equation solvers (not RK4 integration)
- Elliptical: E - e·sin(E) = M
- Parabolic: D + D³/3 = M (Barker's equation)
- Hyperbolic: H - e·sinh(H) = M
## Module Dependencies
```
Physics (foundation, no dependencies)
↓
Orbital Mechanics (depends only on Physics)
↓
Spacecraft, Maneuver (depend on Physics)
↓
Simulation (depends on Physics, Orbital Mechanics, Spacecraft, Maneuver)
↓
Config Loader (depends on Simulation)
Config Validator (depends on Simulation and Orbital Mechanics)
Renderer (depends on Simulation)
UI Renderer (depends on Renderer and Simulation)
```
**Key principles**:
- Physics is completely independent
- Lower layers never depend on upper layers
- Each module has clear, minimal dependencies
## Testing Guidelines
- **Framework**: Catch2
- **Run tests**: `make test`
- **Test configs**: Located in `tests/configs/`
- **Descriptive names**: Use clear test case names
```bash
# Run all tests
make test
# Run specific test config
./orbit_test '[config_name]'
# Test with debug output (shows INFO messages)
./orbit_test -s '[config_name]'
```
**Test structure**:
```cpp
TEST_CASE("elliptical orbit energy conservation", "[energy]") {
SimulationState* sim = create_simulation(10, 1, 0, 60.0);
load_system_config(sim, "tests/configs/elliptical.toml");
double initial_energy = calculate_system_total_energy(sim);
for (int i = 0; i < 100; i++) {
update_simulation(sim);
}
double final_energy = calculate_system_total_energy(sim);
REQUIRE_THAT(final_energy, WithinAbs(initial_energy, 1e-6));
destroy_simulation(sim);
}
```
## Common Patterns
**Struct initialization**:
```cpp
CelestialBody earth = {0};
strcpy(earth.name, "Earth");
earth.mass = 5.972e24;
earth.radius = 6.371e6;
```
**Error handling**: Return codes or NULL pointers
```cpp
int result = some_function();
if (result != 0) {
return result;
}
CelestialBody* body = find_body(sim, "Earth");
if (body == NULL) {
return -1;
}
```
**Const correctness**: Use `const` for read-only parameters
```cpp
Vec3 vec3_add(const Vec3 a, const Vec3 b) {
Vec3 result = { a.x + b.x, a.y + b.y, a.z + b.z };
return result;
}
```
## File Organization
**Directory structure**:
```
src/
physics.h/cpp
orbital_mechanics.h/cpp
simulation.h/cpp
spacecraft.h/cpp
maneuver.h/cpp
config_loader.h/cpp
config_validator.h/cpp
renderer.h/cpp
ui_renderer.h/cpp
test_utilities.h/cpp
tests/
test_*.cpp
configs/
configs/
*.toml
docs/
*.md
```
## Pre-commit Hooks
The project uses a pre-commit hook that:
- Strips trailing whitespace from all files
- Prevents commits with trailing whitespace
**If you see a "trailing whitespace" error**:
1. The hook has automatically fixed the files
2. Review the changes
3. Stage them again and retry the commit