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:

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 ConceptUsed for
ApplicationBase class for GalaxyEggbertApp
ContextEngine context passed through all subsystems
Scene3D scene graph root
Node3D transform node; used for terrain blocks, Blupi, objects, camera
StaticModelTerrain block rendering (Box.mdl)
BillboardSetBlupi sprite and object sprites (always faces camera)
MaterialPer-block materials with UV offsets into sprite sheets
TechniqueRendering technique (Diff.xml, DiffAlpha.xml, DiffSkydome.xml)
Texture2DSprite sheet textures loaded from Content/icons/
Camera3D perspective camera (component on camera node)
OctreeSpatial indexing for scene queries
ZoneAmbient lighting and fog per region
LightDirectional lights (sun + fill)
DebugRendererDebug geometry overlay (toggled by F1)
ResourceCacheAsset loading subsystem
FileSystemPath resolution (program dir, user documents dir)
InputKeyboard and mouse state per-frame
EngineExit method (engine->Exit())
UI2D UI overlay for HUD and phase overlays
TextOn-screen text (HUD, phase overlay text)
BorderImageHUD sprite icons (life icons, key icons, gauge)
SoundLoaded WAV resource
SoundSourcePer-channel audio playback node component
E_UPDATEPer-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

AspectU3DNova3D
PlatformsLinux, WindowsLinux, Windows, Web, Android
Graphics backendsOpenGL (Linux), D3D9/D3D11 (Win)SDL Renderer, EasyGL, BGFX, Vulkan
Required pre-buildYes — libUrho3D.aVia git submodule
AndroidNot yet supported in GalaxyEggbertPlanned
EmscriptenNot yet supported in GalaxyEggbertPlanned
C++ APISame Urho3D APISame Urho3D API (goal)