Design Principles

Easy3D / Guide / Design Principles

Easy3D has unusually explicit boundaries, written down before the code. The project's history includes several larger 3D abstraction attempts (Simple3D, Nova-3D, MeshCraft, Mesh World); Easy3D exists precisely to not repeat them. These principles are enforced in code review and documented so they survive contributors and time.

Principle 1 — Companion, not engine

Easy3D sits beside CNA. A game still creates and drives its CNA Game, graphics device, and input directly. Easy3D removes repetitive glue only: cameras, billboard/cube batching, a texture atlas, debug drawing. There is no Easy3D::Game, no "run everything" object, and there never will be.

Principle 2 — CNA types stay visible

Easy3D APIs accept and return Microsoft::Xna::Framework::Vector3, Matrix, and friends directly. No parallel math types, no wrappers that exist just to rename CNA. Consequences you will notice in the API:

Principle 3 — Small, boring, testable

Minimal helper classes over frameworks. One small change at a time. Every helper that can be tested without linking all of CNA has such a test (see Testing). The batching classes deliberately do no GPU work — they store plain data, which is trivially testable, and rendering arrives in a later phase as a separate, decidable step.

Principle 4 — Grow only when needed

Easy3D grows only as far as its first consumer, Galaxy Eggbert, actually needs. If a feature is not needed soon, it is not built now. Anything not on the Roadmap is out of scope until explicitly approved.

Hard limits

The following are out of bounds without explicit approval. If you find yourself building any of these, it does not belong in Easy3D:

ExcludedWhy
Entity/component framework (ECS)Engine territory; games structure themselves.
Physics, navigation, networkingFull-engine subsystems, far beyond glue code.
Scene editor, asset database, resource cache, plugin systemTooling/infrastructure that belongs to an engine or the game.
Model importer / MeshCraft importEasy3D stays billboard / cube / tile only (see Decision 6 below).
PBR renderer or any "full engine" subsystemEasy3D is not a renderer; even its future draw path will be thin CNA adapters.
Lua scriptingCurrently out of scope; see Decision 5 below.
Eggbert-specific logicTile meanings, animation tables, level formats, gameplay rules live in the games.

Recorded design decisions

The repository keeps a decision log (docs/QUESTIONS.md). The decisions so far, summarized:

1. CNA math types are used directly

Camera helpers and batch items use CNA's Vector3/Vector2/Matrix directly — no aliases, no wrappers. The linkage consequence (CNA types are defined in CNA's .cpp files) is accepted and handled by the build system. TextureAtlas keeps its own PODs for pixel/UV rectangles.

2. The CNA CMake target is CNA

Confirmed as the stable, public target name Easy3D relies on: a STATIC, C++23 library whose PUBLIC include directory is ../cna/include.

3. CNA linkage is opt-in

Linking CNA pulls in heavy transitive dependencies, so the default build stays headers-only and the camera example/tests are gated behind EASY3D_LINK_CNA (default OFF) or a parent-provided CNA target. The add_subdirectory + parent-target-detection approach is sufficient; no find_package(CNA) config or prebuilt-library path is needed for now.

4. Compiled static library, not header-only

Easy3D is a normal compiled STATIC library (easy3d). Header-only was considered and rejected.

5. Lua is out of scope

Lua is intentionally not part of this version. If it is ever approved, it would be an optional, separate module within the repository (working name easy3d-lua) — but no Lua code is added before explicit approval.

6. Billboard / cube / tile only — no 3D models

For the first Galaxy Eggbert versions, Easy3D supports no 3D model loading or import. That remains a hard limit unless separately, explicitly approved later.

7. Blupi renders as a billboard

Galaxy Eggbert will initially render Blupi as a 2D billboard built from existing Mobile Eggbert sprite animations. BillboardBatch + TextureAtlas are the two Easy3D pieces this needs — no 3D model path required.

Relationship to earlier libraries

Easy3D is not Simple3D and must not grow back into Simple3D; it is not Nova-3D or a Urho3D-style abstraction either. Nez, libGDX, and Simple3D serve as conceptual inspiration only — their code is never copied. The recurring failure mode Easy3D guards against: a "helper library" accreting subsystems until it hides the runtime underneath. Every hard limit above exists because some predecessor crossed it.