Coding Style

The conventions the code base actually follows, checked against the tree on 2026-11-10. There is no formatter: follow the surrounding file.

Language and layout

Namespaces

NamespaceWhereWhat lives there
GalaxyEggbertinclude/GalaxyEggbert/, src/GalaxyEggbert/*.cppRecord codecs and tables: BlockDefinitionRegistry, MoveObjectRecord, BigDecorRecord, HintZoneRecord, HubDoors
GalaxyEggbert::Worldsinclude/GalaxyEggbert/Worlds/, src/GalaxyEggbert/Worlds/The voxel container (World, Chunk, Block, bit packing, binary I/O)
GalaxyEggbert::Definclude/GalaxyEggbert/Def/The original's enums: ObjectType, SoundChannel, GamePhase, BlupiAction...
GalaxyEggbert::Gamesrc/GalaxyEggbert/Game/The game: BlupiController, InteractionSystem, WorldRuntime, renderers, Hud, InputPad, Sound, SaveData, Autoplay...
GalaxyEggbert::Editorsrc/GalaxyEggbert/Editor/The in-game 3D world editor
GalaxyEggbert::CNAsrc/GalaxyEggbertCNA/The application host only: GalaxyEggbertGame, main.cpp, Android asset copying

Header-only helpers often get a nested namespace of their own: Game::CratePush, Game::BrickEdges, Game::TextMetrics, Editor::AutoTile.

Naming

Headers and dependencies

Comments cite the original and the ledgers

Comments in this code base are long and carry dates and ids. When you copy behaviour from the original, cite the reference file and line; when you deviate, say so and point at the ledger row. A real example, from src/GalaxyEggbert/Game/CratePush.hpp:

namespace GalaxyEggbert::Game::CratePush
{
    // How Blupi moves a crate (ObjectType12), from Mobile Eggbert's Decor.cpp (2026-11-01, the
    // fidelity audit's GP-crate rows, plans/audit/behavior_differences.md BD-0001):
    //
    // - While pushing (action Push) he walks CaisseGetMove(5) pixels a 20 Hz tick
    //   (Decor.cpp:3388/3446); while pulling (Pop) he backs away CaisseGetMove(3) (:3410/3468).
    ...
    // The original's 64-pixel block is one Galaxy cell.
    inline constexpr float kPixelsPerCell = 64.0f;
    inline constexpr float kOriginalTicksPerSecond = 20.0f;
    ...
    // A 3D adaptation (M3D-0002): a crate that cannot go only because it lies off the lane of its
    // move by up to this much across ... first slides into the lane, at the same speed.

When you change behaviour that a comment documents, fix the comment. Some long comments (for example at the top of SaveData.hpp and GalaxyEggbertGame.hpp) describe earlier states; trust the code and the ledgers over them.

Determinism

The simulation runs on a fixed 1/60 s tick, and the golden trace, the autoplay playthroughs, the demo replays and the resume feature all depend on it replaying identically. No wall-clock time, unseeded randomness or frame-rate dependence in the simulation. Presentation-only work (the 3D effects, interpolated drawing above 60 frames a second) must leave the simulation untouched.

Generated files and stable IDs

Never edit a generated file by hand. Change its generator and regenerate: avatars3d/** (model converters), tools/data/blocks.csv (DumpBlockDefinitions), BoltPaths.hpp, GlueStrands.hpp, LavaSurfaceData.hpp, plans/inventory/*.md, the generated ledger tables, and every worlds3d/*.vwr that has a script in tools/worlds/.
Never renumber IDs. Def::ObjectType values, block icon numbers (the index into Content/icons/object-m.png) and sound channel numbers are the original's and are stored in world files, demos and resume logs.

Python

Shell

bash with set -u (or set -euo pipefail), a header comment with the usage that the script prints when called without arguments (sed -n '2,12p' "$0"), paths derived from BASH_SOURCE, and scratch output in the git-ignored build-probe/ directory of the repository, never /tmp.

Related pages