Skip to main content
Consistent code style improves readability, debuggability, and maintainability. These guidelines describe best practice for Basilisk contributors. They are guidelines, not absolute rules — deviations are acceptable when carefully reasoned and documented in the code. Foundational references: Where this document is silent, the relevant foundational guidelines apply.
Before contributing, read CONTRIBUTING.md for pull request requirements, branch naming, and pre-commit setup.

Non-conforming legacy code

Some Basilisk code predates this guide. When working with it:
  1. All new code must conform to this guide.
  2. For minor edits to non-conforming code, follow the existing local style — do not mix styles.
  3. For major work on non-conforming code, take the opportunity to re-style it to conform.
  4. Unless you have significant spare time, do not undertake wholesale conversion of the existing codebase.

Naming conventions

The following notation schemes are used throughout this document:
SchemeDescriptionExample
CamelCaseStarts with capital; capital letter per word; no underscoresSpacecraftDynamics
camelCaseLike CamelCase but lowercase first letterspacecraftDynamics
under_scoredLowercase only; words separated by underscoresspacecraft_dynamics
ALL_CAPITALSAll uppercase; words separated by underscoresMAX_ITERATION_COUNT

Variables

No single-letter variable names. The only exceptions are i as an iteration index and a select set of conventional mathematical symbols.

Mathematical variables and reference frames

Naming follows the textbook Analytical Mechanics of Space Systems by Schaub and Junkins. A vector v expressed in frame B is written vector_B. An angular rate of frame B with respect to frame R, with components in B, is written omega_BR_B. A direction cosine matrix mapping from N to B is written dcm_BN. The corresponding MRP attitude σ_B/N is written sigma_BN.
The Intel Eigen library’s .toRotationMatrix() returns [NB], not [BN]. Account for this when converting quaternions or MRPs to a DCM.
Common examples:
QuantityVariable name
Position of B relative to N in N frame componentsr_BN_N
Inertial time derivative of r_BN_NrDot_BN_N
Unit direction vector from B to S in B framesHat_SB_B
Inertial time derivative of body angular rate in B frameomegaDot_BN_B
First derivative with respect to xxPrime
Second derivative with respect to xxDPrime
Inertia tensor of hub about point C in B frameIHubPntC_B

Module and message naming

Message variables

Message variable names follow this pattern:
// C interface
SomeMsg_C descriptionInMsg;       // input message
SomeMsg_C descriptionOutMsg;      // output message

// C++ interface
ReadFunctor<SomeMsgPayload> descriptionInMsg;   // input message
Message<SomeMsgPayload> descriptionOutMsg;      // output message

// Buffer variable for read data
SomeMsgPayload descriptionInBuffer;
  • SomeMsgPayload — the message structure type.
  • In / Out — the direction relative to the module.
  • Msg — explicitly marks the variable as a message.
  • Buffer — explicitly marks the variable as holding read data.

Message definitions

C message payloads live in src/architecture/msgPayloadDefC/ as *.h files. C++ message payloads live in src/architecture/msgPayloadDefCpp/ as *.h files.
  • File names use UpperCamelCase and must match the message name inside the file.
  • File names end with MsgPayload (for example, SpecialSensorMsgPayload.h).
#ifndef SPECIAL_SENSOR_MESSAGE2_H
#define SPECIAL_SENSOR_MESSAGE2_H

/*! @brief Describe the purpose of the message */
typedef struct {
    double sensorOutput_B[3];   //!<  sensor vector in B frame components
    double sensorSignal;        //!<  raw sensor signal
    int status;                 //!<  sensor status flag
} SpecialSensorMsgPayload;

#endif
After adding a message definition, run python3 conanfile.py to regenerate the SWIG interface files.

C/C++ conventions

Follow the Stroustrup/Sutter Core Guidelines. Key Basilisk-specific points:
  • Format all C/C++ files with clang-format before committing. The repository ships a .clang-format file (based on Mozilla style).
  • Use pre-commit hooks to automate formatting on commit.
  • Wrap sections that must not be reformatted with:
// clang-format off
// ... manually formatted code ...
// clang-format on
  • Document each struct member with a Doxygen //!< comment:
double thrustForce_N;   //!< [N] thrust force magnitude in the inertial frame
  • Include unit comments on every numeric literal or variable with physical meaning:
double simTime = 100.0;  // [s]
double altitude = 400e3; // [m]

Python conventions

Follow PEP 8 with these Basilisk-specific additions:
  • Variables use lowerCamelCase (not snake_case) to maintain consistency with the C/C++ interface exposed via SWIG.
  • Inline comments are acceptable when brief.
  • No spaces around math operators (*, /, +, -) inside expressions:
# Correct
x = (4*9/2)-1

# Incorrect
x = (4 * 9 / 2) - 1
  • Annotate physical quantities with unit comments on the same line:
simTime = 500.0          # [s]
orbitRadius = 7000e3     # [m]
angularRate = 0.01       # [rad/s]
thrust = 1.5             # [N]
  • Write docstrings as valid reStructuredText (RST) so they render correctly with Sphinx:
def computeOrbit(semiMajorAxis, eccentricity):
    """
    Compute the orbital period from Keplerian elements.

    :param semiMajorAxis: semi-major axis of the orbit  # [m]
    :type semiMajorAxis: float
    :param eccentricity: orbital eccentricity (dimensionless)
    :type eccentricity: float
    :return: orbital period  # [s]
    :rtype: float
    """

Running tests

All unit and integrated tests must pass before pushing code to the repository.
# Run the full test suite (pytest + gtest)
python run_all_test.py

# Run pytest with parallel execution across 8 processes
python3 -m pytest -n 8

# Generate an HTML validation report
python3 -m pytest --report
The pytest-xdist package (installed by requirements_dev.txt) enables the -n flag for parallel test execution. The pytest-html package enables the --report flag.

Code formatting tools

pre-commit

Install and enable pre-commit inside the repository to automatically format code on each commit:
pip install pre-commit
pre-commit install --hook-type pre-commit --hook-type commit-msg
To run pre-commit manually on a specific file:
pre-commit run --files <file>
When pre-commit modifies files, stage the changes and commit again.

clang-format

Install via pip and run from the command line:
pip install clang-format
clang-format -i {filename} -style=file
In CLion, enable ClangFormat under Settings → Editor → Code Style, then reformat with Ctrl+Alt+L. For Xcode, set up an Automator quick action pointing to your clang-format binary.

Contribution workflow

  1. Create a branch named feature/bsk-XXX--short-desc (linked to a GitHub ticket) or hotfix/short-desc.
  2. Keep commits focused — each commit should represent one logical change.
  3. Rebase onto develop before opening a pull request: git rebase develop.
  4. Open a PR against develop using the repository PR template.
  5. Include a release-note snippet in docs/source/Support/bskReleaseNotesSnippets/.
  6. Ensure at least one reviewer approves and CI passes before merging.
  7. Use the Merge strategy only — do not use “Squash and merge” or “Rebase and merge”.

Build docs developers (and LLMs) love