Engine API
Public engine lifecycle, global services, scene loading, runtime helpers, and gameplay-facing helpers.
Include
#include <EngineExports.hpp>Public::Engine is a singleton facade over the internal engine. Game code should use this public class instead of including internals/Engine.hpp.
auto& engine = Public::Engine::getInstance();Lifecycle
| API | Purpose |
|---|---|
static Engine& getInstance() | Access the singleton facade. |
Initialize(bool skipResizeCallback = false) | Initialize engine systems, then process pending custom component registrations. |
Loop(bool renderManagerAuthority = true, bool renderScene = true) | Run one frame of update/render work. |
Shutdown() | Shut down engine systems. |
IsActive() | Return whether the app should keep looping. |
Typical game loop:
auto& engine = Public::Engine::getInstance();
engine.Initialize();
while (engine.IsActive()) {
engine.Loop();
}
engine.Shutdown();NVEditor uses the optional Loop flags because the editor owns some rendering and ImGui flow. Normal games can use defaults.
Runtime Timing and Window
| API | Purpose |
|---|---|
HasWindow() const | Check whether the main window object exists. |
GetDeltaTime() const | Frame delta used by gameplay updates. |
GetPotentialDeltaTime() const | Raw/uncapped candidate delta used internally by timing code. |
GetWindowWidth() const | Current OS window width. |
GetWindowHeight() const | Current OS window height. |
GetRenderWidth() const | Active render target width. |
GetRenderHeight() const | Active render target height. |
SetWindowTitle(const std::string& title) | Update window title. |
SetWindowSize(int width, int height) | Resize window; returns false for non-positive sizes. |
SetWindowPosition(int x, int y) | Move window position. |
SetFullscreen(bool fullscreen) | Switch fullscreen mode. |
SetCursorVisibility(bool visible) | Hide or show the cursor. |
SetMouseCapture(bool capture) | Enable or disable mouse capture. |
SetClearColor(float r, float g, float b, float a) | Set active render clear color. |
IsWindowFocused() const | Query whether the game window has focus. |
IsCursorLocked() const | Query cursor lock state. |
Global Services
| API | Returns |
|---|---|
GetCoordinator() | Public::ECS::Coordinator& for entities, components, and systems. |
GetInputManager() | Public::Input::InputManager&. |
GetFlagManager() | Public::Input::FlagManager&. |
GetPhysicsSystem() | Public::ECS::Systems::Builtin::PhysicsSystem*, or nullptr if unavailable. |
Example:
auto& coord = engine.GetCoordinator();
auto& input = engine.GetInputManager();
if (auto* physics = engine.GetPhysicsSystem()) {
physics->SetSimulationEnabled(true);
}Command-Line Flags
Pass argc/argv into the flag manager before checking flags:
engine.GetFlagManager().passFlags(argc, argv);
if (ISFLAG("--hotReload")) {
LOG_INFO("Hot reload enabled");
}
auto maybeValue = FLAGVALUE("--useProject");
if (maybeValue) {
LOG_INFO("Project path: " + *maybeValue);
}The macros are convenience wrappers over GetFlagManager():
ISFLAG("--flag")
FLAGVALUE("--flag")Resource Loading, IDs, and Counts
These APIs allow runtime-only tooling and gameplay systems to ensure assets are loaded before use.
| API | Returns | Purpose |
|---|---|---|
LoadMesh(const std::string&) | bool | Load a mesh by path/ID. |
LoadMaterial(const std::string&) | std::string | Load and return a material ID; returns empty on failure. |
LoadTexture(const std::string&, const std::string& textureType = "diffuse") | bool | Load a texture by path and slot role. |
LoadShader(const std::string&) | bool | Load and compile/register a shader. |
HasMesh(const std::string&) | bool | Check mesh registry state. |
HasMaterial(const std::string&) | bool | Check material registry state. |
HasTexture(const std::string&) | bool | Check texture registry state. |
HasShader(const std::string&) | bool | Check shader registry state. |
GetMeshCount() const | size_t | Total loaded meshes. |
GetMaterialCount() const | size_t | Total loaded materials. |
GetTextureCount() const | size_t | Total loaded textures. |
GetShaderCount() const | size_t | Total loaded shaders. |
GetSceneCount() const | size_t | Total loaded scenes tracked by resource manager. |
GetMeshIDs() const | std::vector<std::string> | Sorted mesh IDs. |
GetMaterialIDs() const | std::vector<std::string> | Material IDs. |
GetTextureIDs() const | std::vector<std::string> | Texture IDs. |
GetShaderIDs() const | std::vector<std::string> | Shader IDs. |
RemoveMeshResource(const std::string&) | bool | Remove mesh from resource cache. |
RemoveMaterialResource(const std::string&) | bool | Remove material from resource cache. |
RemoveTextureResource(const std::string&) | bool | Remove texture from resource cache. |
RemoveShaderResource(const std::string&) | bool | Remove shader from resource cache. |
engine.LoadMesh("assets/objects/crate.glb");
engine.LoadMaterial("basic");
engine.LoadShader("basic");
engine.LoadTexture("textures/asphalt/Road012B_4K-PNG_NormalDX.png", "normal");
auto meshes = engine.GetMeshIDs();Scene Loading
engine.LoadScene("outside");Scene loading searches for:
outside.jsonlevels/outside.jsonscenes/outside.json
Scene JSON must include version and ent. See Scene JSON.
To reload a scene from a gameplay hotkey, clear current entities first:
if (input.GetKeyDown(Public::Input::Key::Code::R)) {
coord.clearAllEntities();
engine.LoadScene("test_place");
}Entity, Transform, and Hierarchy Helpers
| API | Returns | Purpose |
|---|---|---|
CreateEntity() | EntityID | Create a new entity. |
DestroyEntity(EntityID) | void | Destroy the entity and attached components. |
GetTransform(EntityID, Transform&) const | bool | Read full transform by copy. |
SetTransform(EntityID, const Transform&) | bool | Overwrite full transform values. |
GetTransformPosition(EntityID, float[3]) const | bool | Read position. |
SetTransformPosition(EntityID, float x, float y, float z) | bool | Create transform if missing and set position. |
GetTransformRotation(EntityID, float[4]) const | bool | Read quaternion rotation. |
SetTransformRotation(EntityID, float x, float y, float z, float w) | bool | Create transform if missing and set rotation. |
GetTransformScale(EntityID, float[3]) const | bool | Read scale. |
SetTransformScale(EntityID, float x, float y, float z) | bool | Create transform if missing and set scale. |
GetParent(EntityID) const | EntityID | Immediate parent or INVALID_ENTITY. |
GetChildren(EntityID) const | std::vector<EntityID> | Immediate child snapshot. |
GetChildCount(EntityID) const | size_t | Immediate child count. |
GetChild(EntityID, size_t index) const | EntityID | Child by index or INVALID_ENTITY if out of range. |
IsDescendantOf(EntityID entity, EntityID ancestor) const | bool | True when ancestor appears in parent chain. |
SetParent(EntityID, EntityID parent, bool keepExistingChildren = false) | bool | Re-parent while updating both parent and child lists. keepExistingChildren is currently accepted for compatibility and not used yet. |
Component Search Helpers
These convenience templates are available on Public::Engine:
| API | Returns | Purpose |
|---|---|---|
GetComponent<T>(EntityID) const | T* | Runtime lookup of a single component pointer. |
GetComponentInChildren<T>(EntityID, bool includeSelf = true) const | T* | First matching component found by depth-first traversal. |
GetEntitiesWithComponentInChildren<T>(EntityID, bool includeSelf = true) const | std::vector<EntityID> | All matching entity IDs in the transform subtree. |
Physics Convenience API
Public::Engine also mirrors many common PhysicsSystem body operations for gameplay convenience.
| API | Returns | Purpose |
|---|---|---|
HasPhysicsBody(EntityID) const | bool | Check whether a body is created for this entity. |
SetPhysicsSimulationEnabled(bool) | bool | Enable/disable global physics stepping. |
IsPhysicsSimulationEnabled() const | bool | Query simulation state. |
SetPhysicsGravity(const float[3]) | bool | Set world gravity. |
GetPhysicsGravity(float[3]) const | bool | Read world gravity. |
SetBodyLinearVelocity(EntityID, const float[3]) | bool | Set body linear velocity. |
GetBodyLinearVelocity(EntityID, float[3]) const | bool | Read body linear velocity. |
AddBodyForce(EntityID, const float[3]) | bool | Add force each step. |
AddBodyImpulse(EntityID, const float[3]) | bool | Add one-frame impulse. |
SetBodyEnabled(EntityID, bool) | bool | Enable/disable a single body. |
TryGetBodyEnabled(EntityID, bool&) | bool | Read body enabled state. |
GetBodyTransform(EntityID, float[3], float[4]) const | bool | Read body pose. |
SetBodyTransform(EntityID, const float[3], const float[4]) | bool | Write body pose. |
TeleportRigidBody(EntityID, const float[3], const float[4] = nullptr) | bool | Teleport body position with optional rotation. |
Raycast(const float[3], const float[3], float, PhysicsRaycastHit&) const | bool | World ray query; check hit.hit on success. |
When you need simulation filters, body handles, or stepping control, use GetPhysicsSystem() directly.
Procedural Runtime Generation
auto pickup = engine.SpawnMeshEntity("assets/props/pickup.glb", {});SpawnMeshEntity creates an entity with:
Transform(using provided transform)MeshRenderer(mesh + material list)
If materialNames is empty or all names fail, fallback material is basic.
Returned entity id is INVALID_ENTITY if load or component creation fails.
Public::ECS::Components::Transform spawnPoint{};
spawnPoint.position = {1.2f, 0.0f, -4.0f};
spawnPoint.scale = {0.5f, 0.5f, 0.5f};
auto enemy = engine.SpawnMeshEntity("assets/characters/enemy.glb",
{"basic"},
spawnPoint);Custom Component Registration
For a scene JSON component type that is not built into the engine, register a creator before Initialize():
using json = nlohmann::json;
struct Spin {
float speed = 1.0f;
};
inline void CreateSpinComponent(Public::ECS::EntityID entity, const json& data) {
Spin spin{};
spin.speed = data.value("speed", 1.0f);
Public::Engine::getInstance().GetCoordinator().addComponent(entity, spin);
}
int main(int argc, char* argv[]) {
auto& engine = Public::Engine::getInstance();
engine.RegisterComponent("Spin", CreateSpinComponent);
engine.Initialize();
auto& coord = engine.GetCoordinator();
coord.registerComponent<Spin>();
}RegisterComponent stores pending registrations and forwards them to scene loading during Initialize(). The type name must match the scene component "type" string.
Recommended Startup Order
int main(int argc, char* argv[]) {
Public::Debug::DebugManager::getInstance().Initialize("game.log");
auto& engine = Public::Engine::getInstance();
engine.GetFlagManager().passFlags(argc, argv);
engine.RegisterComponent("Freecam", CreateFreecamComponent);
engine.RegisterComponent("MonkeyRot", CreateMonkeyRotComponent);
engine.Initialize();
auto& coord = engine.GetCoordinator();
coord.registerComponent<Freecam>();
coord.registerComponent<MonkeyRot>();
auto freecamSystem = coord.registerSystem<FreecamSystem>();
auto monkeySystem = coord.registerSystem<MonkeyRotSystem>();
engine.LoadScene("nevo_image1");
while (engine.IsActive()) {
engine.Loop();
}
engine.Shutdown();
}Register scene creators before Initialize; register ECS storage/systems after Initialize.
