Architecture
The Direction Lock, layering, and how CNA, cna-engine, and mobile-eggbert relate.
The Direction Lock
The intent of CLAUDE.md, the project's binding architectural rule set:
Galaxy Eggbert
-> CNA directly
-> cna-engine's strict modules beside CNA (CnaEngine::Core, CnaEngine::Graphics —
camera, mesh builder, GPU meshes, texture regions; XNA 4.0 types only)
-> mobile-eggbert used read-only as reference / asset / data source
Until 2026-10-20 the helpers beside CNA were the sibling library easy-3d (namespace
Easy3D: cameras, texture atlas, billboard/cube batching). cna-engine's strict modules
replaced it that day; see Engine Integration for what
replaced what.
This supersedes an older direction: Galaxy Eggbert -> Simple3D -> U3D / Urho3D / Nova3D -> (CNA someday).
Rules That Follow From the Lock
- Do not expand the Simple3D/U3D/Nova3D direction except to keep
GalaxyEggbertSimple3Dworking (bug fixes, faithful-remake gameplay parity are fine; new engine-layer investment is not). - Do not modify
../mobile-eggbertwithout explicit user approval; do not refactor it or split it into a sharedcorelibrary. - Do not copy mobile-eggbert code or data (tables, enums, save-format byte layout, sprite/frame logic) into Galaxy Eggbert without explicit approval — even data that "looks like just data."
- Reusing mobile-eggbert assets (PNGs, sounds, world files) by file path / build-time copy is allowed.
- New CNA/cna-engine code goes under
src/GalaxyEggbertCNA/— do not mutatesrc/GalaxyEggbertSimple3D/into the CNA implementation. - cna-engine's strict modules are helpers beside CNA — they must not hide CNA (game code calls CNA directly); they are not a scene graph or a replacement engine.
- No Lua unless explicitly requested by the user. No MeshCraft, Mesh World, Nova3D, or further Simple3D features re-added to the active path.
../simple-3dmay be read (never modified) only when genuinely needed forGalaxyEggbertSimple3Dwork.- No
#ifdefengine guards in either target — each speaks its own API directly.
High-Level Layering
┌──────────────────────────────────────────────────────────┐
│ mobile-eggbert (read-only reference: assets + behavior) │
└───────────────────────┬────────────────────────────────────┘
│ assets reused by file path / build-time copy
│ code/data referenced, never copied without approval
┌────────────▼─────────────┐
│ CNA (game framework)│ ← XNA-compatible, SDL3-based
└────────────┬─────────────┘
│ used directly (not hidden)
┌────────────▼─────────────┐ ┌─────────────────────┐
│ cna-engine strict modules │◄──────┤ camera, UV regions, │
│ (CnaEngine::Graphics) │ │ MeshBuilder, GpuMesh│
└────────────┬─────────────┘ └─────────────────────┘
│
┌────────────▼─────────────┐
│ GalaxyEggbertCNA │ ← long-term target (this doc's focus)
│ GalaxyEggbertCnaGame │
│ GEWorldRuntime, GETerrainRenderer,
│ GETileAtlas, GEBlupiController
└────────────┬─────────────┘
│ uses (engine-agnostic, shared)
┌────────────▼─────────────┐
│ GalaxyEggbert::Worlds │
│ World / Chunk / Block / │
│ BlockMetadata / VoxelConfig│
└──────────────────────────┘
(Separately, GalaxyEggbertSimple3D — built on Simple3D/U3D — remains the
only fully playable target and stays as reference until CNA reaches parity.)
GalaxyEggbertCNA Components
Entry point — main.cpp
Constructs a GalaxyEggbertCnaGame, calls Run(), deletes it.
Game — GalaxyEggbertCnaGame
Subclasses Microsoft::Xna::Framework::Game (CNA's game base class), overriding
LoadContent(), Update(GameTime&), Draw(const GameTime&).
Owns the world runtime, terrain renderer, Blupi controller, and camera.
See class reference.
World runtime — GEWorldRuntime
Wraps a Worlds::World; loads .vwr or (secondary path) mobile-eggbert .txt; drives the 6 fps tile-animation phase. See class reference.
Terrain renderer — GETerrainRenderer
Builds static and animated terrain meshes with cna-engine's MeshBuilder from the world's non-air blocks and draws them as CnaEngine::Graphics::GpuMeshes (until 2026-10-20: Easy3D::CubeMeshRenderer). See class reference.
Tile atlas — GETileAtlas
Maps block type IDs to CnaEngine::Graphics::UvRects in object-m.png, computed with BlockTypes::tileUV(). See class reference.
Player controller — GEBlupiController
Invisible, collision-only movement placeholder: grid collision, step-up traversal, gravity, jump. See class reference.
World data model — GalaxyEggbert::Worlds
Engine-agnostic. No CNA or cna-engine dependency. Shared verbatim by GalaxyEggbertSimple3D and GalaxyEggbertCNA. See World, Chunk, Block.
Dependency Map
| Component | Depends on |
|---|---|
GalaxyEggbertCnaGame | CNA (Game, GameTime, Texture2D, BasicEffect, Keyboard), cna-engine (CnaEngine::Graphics::Camera), GEWorldRuntime, GETerrainRenderer, GEBlupiController |
GEWorldRuntime | GalaxyEggbert::Worlds::World only |
GETerrainRenderer | cna-engine (MeshBuilder, GpuMesh, via TexturedMesh.hpp), GETileAtlas, Worlds::World, BlockTypes |
GETileAtlas | cna-engine (UvRect), BlockTypes |
GEBlupiController | GalaxyEggbert::Worlds only — no CNA/cna-engine dependency, scriptable headlessly |
Worlds::World / Chunk / Block | C++ stdlib only |