Architecture
The Direction Lock, layering, and how CNA, Easy3D, and mobile-eggbert relate.
The Direction Lock
Verbatim intent from CLAUDE.md, the project's binding architectural rule set:
Galaxy Eggbert
-> CNA directly
-> Easy3D beside CNA (small helpers only — cameras, texture atlas, billboard/cube batching)
-> mobile-eggbert used read-only as reference / asset / data source
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/Easy3D code goes under
src/GalaxyEggbertCNA/— do not mutatesrc/GalaxyEggbertSimple3D/into the CNA implementation. - Easy3D is a helper library beside CNA — it must not hide CNA (game code calls CNA directly), and must not grow into a scene graph / ECS / 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)
┌────────────▼─────────────┐ ┌─────────────────────┐
│ Easy3D │◄──────┤ cameras, atlas, │
│ (small helper library) │ │ cube/billboard batch│
└────────────┬─────────────┘ └─────────────────────┘
│
┌────────────▼─────────────┐
│ 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 a static + an animated Easy3D::CubeMeshRenderer from the world's non-air blocks. See class reference.
Tile atlas — GETileAtlas
Maps block type IDs to UV rects in object-m.png via Easy3D::TextureAtlas. 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 Easy3D dependency. Shared verbatim by GalaxyEggbertSimple3D and GalaxyEggbertCNA. See World, Chunk, Block.
Dependency Map
| Component | Depends on |
|---|---|
GalaxyEggbertCnaGame | CNA (Game, GameTime, Texture2D, BasicEffect, Keyboard), Easy3D (Camera3D), GEWorldRuntime, GETerrainRenderer, GEBlupiController |
GEWorldRuntime | GalaxyEggbert::Worlds::World only |
GETerrainRenderer | Easy3D (CubeBatch, CubeMesh, CubeMeshRenderer), GETileAtlas, Worlds::World, BlockTypes |
GETileAtlas | Easy3D (TextureAtlas) |
GEBlupiController | GalaxyEggbert::Worlds only — no CNA/Easy3D dependency, scriptable headlessly |
Worlds::World / Chunk / Block | C++ stdlib only |