vibe coding an orbital mechanics simulation to try out claude code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

7.6 KiB

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
// 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

struct CelestialBody { };
struct OrbitalElements { };
struct Spacecraft { };

Function names: snake_case

propagate_orbital_elements()
find_dominant_body()
update_bodies_physics()

Member variables: snake_case

global_position
local_velocity
parent_index

Constants: UPPER_CASE

PARABOLIC_TOLERANCE
MIN_MASS_RATIO

Enum values: UPPER_CASE with prefix

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
// 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 <br> tag instead of two trailing spaces
Good:
Line 1<br>
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
// 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

// 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: <catch2/matchers/catch_matchers_floating_point.hpp>
#include <catch2/matchers/catch_matchers_floating_point.hpp>

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
# 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
# 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:

v = sqrt(G * M / r)

Sphere of Influence (SOI): Hill sphere approximation

r_soi = a * (m / M)^(2/5)

SOI transitions: 0.5× distance hysteresis to prevent oscillation

Parabolic orbits: Escape velocity

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
# 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:

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:

CelestialBody earth = {0};
strcpy(earth.name, "Earth");
earth.mass = 5.972e24;
earth.radius = 6.371e6;

Error handling: Return codes or NULL pointers

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

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