Engine Integration

How Galaxy Eggbert uses CNA directly, with cna-engine's strict modules as small helpers beside it.

Direct CNA — Not an Abstraction Layer

Unlike the older Simple3D direction (which wrapped Urho3D behind an abstraction so the engine could theoretically be swapped), GalaxyEggbertCNA calls CNA directly. CNA is an XNA-compatible, SDL3-based C++ game framework — game code uses its Microsoft::Xna::Framework::* namespaces and types with no engine-selection indirection layer.

cna-engine's Role — a Helper, Not a Hiding Layer

The strict modules of cna-engine (CMake targets CnaEngine::Core and CnaEngine::Graphics, namespace CnaEngine::Graphics; XNA 4.0 types only) live beside CNA, not above it. Game code still calls CNA directly for anything the engine modules don't specifically help with. Their job here is narrow: a camera, texture regions, CPU-side mesh building for boxes, plates and billboards, and GPU meshes drawn with the game's own effects. They are not a scene graph and not a replacement engine.

Until 2026-10-20 this role was filled by the sibling helper library easy-3d (namespace Easy3D). easy-3d was removed that day and replaced by cna-engine's strict modules; the meshes the game builds are the same vertices and indices, bit for bit (verified by cna-engine's Easy3DEquivalenceTests).

What cna-engine provides, used by GalaxyEggbertCNA

ClassRoleReplaced (easy-3d)
CnaEngine::Graphics::CameraDrives View/Projection every frame: SetLookAt(position, target, up) (view exactly XNA Matrix::CreateLookAt), SetPerspective(fov, aspect, near, far), View(), Projection(). The game keeps the look-at target itself (cameraTarget_).Easy3D::Camera3D
CnaEngine::Graphics::UvRect / TextureAtlasTexture regions: UvRect (u0, v0, u1, v1); TextureAtlas is cna-engine's counterpart of Easy3D::TextureAtlas. GETileAtlas returns UvRects, still computed with the game's own BlockTypes::tileUV() (unchanged)Easy3D::UvRect (U0, V0, U1, V1), Easy3D::TextureAtlas
CnaEngine::Graphics::MeshBuilderCPU-side mesh building, positions + one texture coordinate: AddBox, AddPlate, AddCrossedPlates, AddBillboard, AddVertex/AddTriangle/AddQuadCubeBatch, BillboardBatch, BuildCubeMesh, Append*Mesh
CnaEngine::Graphics::GpuMeshUpload(device, mesh, VertexLayout::PositionTexture()) to CNA buffers; Draw(device, effect) applies each pass of a caller-supplied BasicEffectEasy3D::CubeMeshRenderer, BillboardMeshRenderer

The game's own header src/GalaxyEggbert/Game/TexturedMesh.hpp adds four small helpers for its one vertex format: MakeTexturedMeshBuilder(), TexturedVertex(position, uv), AddCenteredBox(mesh, center, size, faces | uv) and UploadTexturedMesh(device, meshData). The teleporter's pyramid tip (easy-3d's AppendPyramidTipMesh) is now the game's own AddPyramidTip() in src/GalaxyEggbert/Game/TerrainRenderer.cpp.

Not taken over from easy-3d

easy-3d's separate CPU batches were not taken over — the builder is the batch. easy-3d's DebugDraw was never used by the game.

CNA APIs Used Directly by GalaxyEggbertCnaGame

CNA typeUsed for
Microsoft::Xna::Framework::GameBase class for GalaxyEggbertCnaGame
GameTimeDelta time passed to Update/Draw
Graphics::Texture2DLoads object-m.png
Graphics::BasicEffectTextured, untextured-vertex-color-off shader for terrain draw
Input::Keyboard / KeysArrow keys + Space each frame
Color, Rectangle, MatrixStandard XNA-compatible math/graphics types
VertexBuffer / IndexBuffer / DrawIndexedPrimitivesBehind GETerrainRenderer's meshes, created and drawn through cna-engine's GpuMesh (Upload once, Draw(device, effect) per frame)

Entry Point

// src/GalaxyEggbertCNA/main.cpp
int main() {
    auto* game = new GalaxyEggbert::CNA::GalaxyEggbertCnaGame();
    game->Run();
    delete game;
}

Lifecycle Overrides

class GalaxyEggbertCnaGame : public Microsoft::Xna::Framework::Game {
    void LoadContent() override;              // load world, texture, build terrain renderer
    void Update(GameTime& gameTime) override;  // advance anim phase, read input, step Blupi, update camera
    void Draw(const GameTime& gameTime) override; // clear, set effect matrices, draw terrain
};

Comparison: Simple3D vs. CNA Integration Style

AspectGalaxyEggbertSimple3DGalaxyEggbertCNA
Engine accessThrough Simple3D's Urho3D-shaped abstractionDirect CNA API calls, no abstraction layer
Helper libraryNone (Simple3D itself is the abstraction)cna-engine's strict modules (CnaEngine::Core, CnaEngine::Graphics), explicitly small and non-hiding — easy-3d until 2026-10-20
RenderingScene-graph nodes with StaticModel/BillboardSetMeshes built with MeshBuilder, drawn with explicit GpuMesh::Draw calls via BasicEffect
StatusOnly fully playable targetTerrain + collision-only movement only