Engine Integration
How Galaxy Eggbert uses Urho3D, U3D, and Nova3D.
The Engine Abstraction Strategy
Galaxy Eggbert targets the Urho3D C++ API exclusively.
There are no #ifdef GE_ENGINE_* guards in the C++ source.
Two pre-built implementations of the Urho3D API exist:
- U3D — the u3d-community fork of Urho3D. Stable; used for Linux and Windows builds.
- Nova3D — Robert Vokac's own Urho3D fork with CNA/SDL3 backend support. Used for Web (Emscripten) and Android targets once it matures.
Switching engines requires only a CMake flag: -DGALAXY_EGGBERT_ENGINE=U3D or =NOVA3D.
If Nova3D fails to compile Galaxy Eggbert, Nova3D must fix itself — not Galaxy Eggbert.
The GEEngine.hpp Header
All engine usage flows through a single include:
// src/GalaxyEggbert/GEEngine.hpp
#pragma once
#include <Urho3D/Urho3DAll.h>
This is the only place the engine is included. Every other source file that needs the engine includes GEEngine.hpp.
Urho3D Concepts Used
| Urho3D Concept | Used for |
|---|---|
Application | Base class for GalaxyEggbertApp |
Context | Engine context passed through all subsystems |
Scene | 3D scene graph root |
Node | 3D transform node; used for terrain blocks, Blupi, objects, camera |
StaticModel | Terrain block rendering (Box.mdl) |
BillboardSet | Blupi sprite and object sprites (always faces camera) |
Material | Per-block materials with UV offsets into sprite sheets |
Technique | Rendering technique (Diff.xml, DiffAlpha.xml, DiffSkydome.xml) |
Texture2D | Sprite sheet textures loaded from Content/icons/ |
Camera | 3D perspective camera (component on camera node) |
Octree | Spatial indexing for scene queries |
Zone | Ambient lighting and fog per region |
Light | Directional lights (sun + fill) |
DebugRenderer | Debug geometry overlay (toggled by F1) |
ResourceCache | Asset loading subsystem |
FileSystem | Path resolution (program dir, user documents dir) |
Input | Keyboard and mouse state per-frame |
Engine | Exit method (engine->Exit()) |
UI | 2D UI overlay for HUD and phase overlays |
Text | On-screen text (HUD, phase overlay text) |
BorderImage | HUD sprite icons (life icons, key icons, gauge) |
Sound | Loaded WAV resource |
SoundSource | Per-channel audio playback node component |
E_UPDATE | Per-frame update event |
Entry Point Macro
// src/GalaxyEggbert/Program.cpp
#include "GalaxyEggbertApp.hpp"
URHO3D_DEFINE_APPLICATION_MAIN(GalaxyEggbertApp)
This Urho3D macro expands to the correct main() signature for the target platform
(standard main on desktop, SDL_main on Android/Emscripten, etc.)
and creates + runs a GalaxyEggbertApp instance.
Event Loop Integration
// GalaxyEggbertApp::Start()
SubscribeToEvent(E_UPDATE, URHO3D_HANDLER(GalaxyEggbertApp, HandleUpdate));
// GalaxyEggbertApp::HandleUpdate()
void GalaxyEggbertApp::HandleUpdate(StringHash, VariantMap& eventData) {
using namespace Update;
GameUpdate(eventData[P_TIMESTEP].GetFloat());
}
The update loop is driven by Urho3D's E_UPDATE event which fires every frame.
The timestep (dt) comes from the engine's time subsystem.
Galaxy Eggbert does not manage its own game loop.
Resource Loading
Resources are loaded through Urho3D::ResourceCache:
auto* cache = context_->GetSubsystem<ResourceCache>();
auto* tex = cache->GetResource<Texture2D>("icons/blupi.png");
auto* tech = cache->GetResource<Technique>("Techniques/Diff.xml");
auto* sound = cache->GetResource<Sound>("sounds/sound001.wav");
Resource paths are relative to the search paths set in GalaxyEggbertApp::Setup():
Data;CoreData;Content. Data and CoreData are from the U3D/Nova3D engine distribution.
Content is the game's own asset directory.
U3D vs Nova3D Differences
| Aspect | U3D | Nova3D |
|---|---|---|
| Platforms | Linux, Windows | Linux, Windows, Web, Android |
| Graphics backends | OpenGL (Linux), D3D9/D3D11 (Win) | SDL Renderer, EasyGL, BGFX, Vulkan |
| Required pre-build | Yes — libUrho3D.a | Via git submodule |
| Android | Not yet supported in GalaxyEggbert | Planned |
| Emscripten | Not yet supported in GalaxyEggbert | Planned |
| C++ API | Same Urho3D API | Same Urho3D API (goal) |