DEV Community

Ishan Shrestha
Ishan Shrestha

Posted on Originally published at Medium

I built a small C++ game engine so an AI IDE could touch the whole thing

Originally posted on Medium.

I wanted to make a game. I also wanted the AI IDE on my desk to edit the whole running process, not just the scripts.

Godot still makes you do linking and scene wiring in the UI. Unreal would not run on this laptop. Writing a raw Vulkan renderer from scratch meant months before I could drop a cube on screen. So I took the middle: Diligent Engine for the GPU, and I built everything else.

The machine is an Intel HD 620. No discrete GPU. That forced the rest of the design. Keep draw calls low. Cull hard. Do not pull in heavy middleware.

Demo: https://youtu.be/nsptiy-I4Ps
Repo: https://github.com/Ishan5hrestha/SapanaEngine

Why Diligent, not Godot or raw Vulkan

Full engines hide the part I wanted to learn, and they are too fat for this hardware. Raw Vulkan is a career by itself. Diligent sits in between. Pipeline state, resource binding, HLSL once, targets Vulkan / D3D12 / Metal / D3D11 / GL. It is a dependency. It is not the codebase.

I write ECS, scenes, assets, physics, cameras, input, and a flight sim. Diligent draws.

What is in the engine

ECS and scenes. EnTT. Scenes are JSON. Entities get transforms, mesh refs, physics blocks, LOD groups. A loader fills the registry at startup.

Assets. GLB/glTF through Diligent's loader, wrapped in my own cache. Builtin cube and plane for quick tests. String IDs like builtin:cube or meshes/drone.glb.

Rendering. Two modes in config: Basic (forward, color, optional PCF shadows) and PBR (Diligent's GLTF PBR path, behind pimpl). Procedural sky, no skybox texture. Cascaded shadows. Frustum cull, distance LOD, far cull with hysteresis.

Physics. Jolt 5.3.0, FetchContent, pinned. Opt-in. No physics block in the JSON means mesh-only. Static and dynamic bodies, box and plane shapes for now. Public headers never see Jolt. Pimpl.

Flight. The sandbox has a quad. Two profiles on the same craft.

  • DJI: level, altitude hold, heading-frame move.
  • FPV: acro, rate pitch/roll/yaw, idle throttle is freefall.

Four virtual motor forces at the arm corners. Tunables in config/flight.json. Cameras: freelook, chase, FPV nose. L flips the flight profile. K cycles cameras.

Input. Bindings live in JSON. Cursor capture for mouse look.

Most of the C++ came out of the AI IDE. The real work was keeping it light enough that this laptop still runs, and fixing the parts the model got wrong.

Sandbox

Sapana Sandbox — drone, trees, physics cubes on Vulkan

That shot is Sapana Sandbox on Vulkan. Same frame you see in the title bar: mid-60s fps on integrated graphics. Green ground with static physics. Dynamic cubes. Visual-only glTF cube. One flyable drone. About forty static trees with box colliders.

Edit a config or the scene JSON, rebuild, relaunch. No recompile hunt for every tweak. Builds on Linux (Mint 22.3 here) and Windows (win branch).

The bug

Far-distance cull, with LOD enabled, can strobe. Builtin cubes pop. Sky shows through. Freelook and drone share one view path, so both get it. Far hide vs camera far plane, shadow casters dropping while receivers still draw, PCF on basic meshes. Hysteresis helped. It is not fixed. Workaround: turn LOD off in config/lod.json and restart.

What this is not

It is not Unreal. It is not a product. It is a small engine for a specific game, on limited VRAM, where the whole loop is files an IDE can touch.

If you want the boring details, the README in the repo has the layer list, controls, and build steps.

Top comments (0)