K.Engine

image

K.Engine is a WIP custom game engine written in C++.

You can test the current development build here. The build folder holds a current build of the repository.

Features

Modules

Module Contents
K.Engine.Core Application loop, window, layer stack, ImGui editor shell, demo
K.Engine.Graphics Batched renderer (quads/cubes), DrawMesh for terrain, camera, lights
K.Engine.Physics Shapes, collision manifolds, rigidbodies, PhysicsWorld (broadphase + solver), raycasts
K.Engine.Terrain HeightField, LOD TerrainChunk meshing, Terrain (noise gen + sculpting)
K.Engine.Common ECS, math, events, QualitySettings dial, Transform, scene components, noise
K.Engine.Input Keyboard/mouse polling, platform window
K.Engine.Editor Scene serializer (.kscene) + C++ scripting (ScriptBehavior, registry, built-ins)

Editor, scenes & scripting

The app is an editor over an ECS world. Every world item is an entity with components (Transform, Prop, LightSource, Rigidbody, Collider, Script, …); the Explorer lists them and the Properties panel edits them. Play snapshots the world and runs physics + scripts; Stop restores the snapshot, so editing is always non-destructive. File → Save/Open Scene serializes the world (and environment) to a .kscene text file.

Game logic lives in C++ behaviours — engine for the game, not games for the engine. A behaviour derives from KDot::ScriptBehavior, uses the KDot namespace, and is registered by name; attach it via a Script component. Because behaviours compile into the binary, the same code runs on native and web (no separate scripting VM):

class Spin : public KDot::ScriptBehavior {
    void OnUpdate(float dt) override {
        if (auto* t = GetTransform())
            t->rotation = glm::angleAxis(glm::radians(90.0f * dt),
                                         glm::vec3(0, 1, 0)) * t->rotation;
    }
};
KE_REGISTER_SCRIPT(Spin, "Spin"); // now selectable in the Script component

Built-ins: Spin, Hover, Patrol (see K.Engine.Editor/src/Script/BuiltinScripts.cpp).

The fidelity dial

Everything detail-related reads from one master value in QualitySettings (K.Engine.Common/include/Core/QualitySettings.hpp), in the range [0, 1]:

KDot::QualitySettings::Get().SetFidelity(0.65f); // project default
Fidelity Render dist Terrain chunk edge Max LOD Shadows
0.00 (Iruna) 120 17 2 off
0.65 (K.Engine) ~1730 65 5 2048
1.00 (Elden) 2600 129 6 4096

Changing it at runtime (there’s a slider in the demo’s Inspector panel) re-derives render distance, LOD bands, terrain density, shadow map size, light budget and texture sampling, so a settings menu only ever touches one call.

Terrain

Physics

Rendering & input

Demo controls: WASD fly · right-drag look · scroll zoom · left-click sculpt (hold Shift to lower) · R re-drop the ball.

Cross-platform

The engine now builds on both the web (Emscripten/WebGL2) and native desktop (GLFW + GLEW, OpenGL 3.3 core). Platform differences are isolated:

Roadmap: WebGPU & Vulkan

The gameplay systems (terrain, physics, ECS, config, math) are graphics-API agnostic, so the remaining work is backend-only, behind the RHI seam (RHI/Device/Buffer/Pipeline interfaces + GraphicsAPI.hpp, selected via the KE_BACKEND_* CMake options):

  1. ✅ Native desktop OpenGL (window/loop/RHI seam, shader adaptation).
  2. ✅ RHI device abstraction + OpenGL backend (RHI/GLDevice); GrassRenderer ported onto it (buffers + pipeline + std140 uniform buffer, zero direct GL).
  3. Vulkan — implement rhi::Device for Vulkan; port the remaining renderer. Native high-performance desktop path.
  4. WebGPU — implement rhi::Device for WebGPU; move the web target onto it.

Building (web)

Building (native desktop)

Install the dependencies, then a normal CMake build:

cmake -S . -B build-native -DCMAKE_BUILD_TYPE=Release
cmake --build build-native -j
./build-native/bin/K.Engine

The platform-agnostic modules (Physics / Terrain / Common) can also be compiled and unit-tested with a normal host compiler (e.g. g++ -std=c++17 -I glm ...), independently of any graphics backend.