SuGar Engine is a custom C++17 Vulkan-based 3D game engine built with GLFW and CMake. It is being built around one bet: win the inner development loop — instant iteration and debuggable systems — rather than chasing feature parity with the big engines. See ROADMAP.md for the full vision and plan.
M1 / Track A done; Track B underway ("the iteration engine")
The engine is a working runtime with a full editor on top: a clean Edit → Play
→ Stop cycle with snapshot/restore and a fixed-timestep loop; a behavior +
input system; hand-rolled physics with collision events; prefabs & glTF import;
quaternion transforms; a hand-rolled audio mixer; and an editor with scene
picking, gizmos, undo/redo, duplicate/delete, multi-select, hierarchy
reparenting, and component management — all on top of the Vulkan renderer, asset
pipeline, hot reload, and shadow mapping. Track B (the wedge) is well underway:
a hardened editor command system (transactions, entity remapping, compression),
time-travel debugging (snapshot ring-buffer + timeline scrubbing + frame
stepping), an ECS query console, and — the headline — code hot reload: a
layered Editor -> Engine -> Core split with gameplay in a DLL that hot-swaps
live when recompiled, state preserved.
Positioning: "A Vulkan engine designed for instant iteration and debuggable systems — not just rendering power." Open-source, dev-led, aimed at indie devs.
EngineStatemachine: Edit / Play / Paused- Scene snapshot/restore — Play snapshots the live scene to memory; Stop restores it, discarding all gameplay mutations
- Fixed 60 Hz gameplay update loop (
updateSystems) — deterministic, frame-rate independent; rendering stays uncapped - Declared system schedule (Phase 13A) — the gameplay pipeline (script →
physics → collision dispatch → audio) is a
SystemSchedulerofSystems that each declare their read/write component sets; runs in deterministic order, with independence analysis (stages()) as the foundation for future parallelism - Editor Play / Pause / Stop toolbar with a viewport state tint
- Behavior system — stateless, name-registered behaviors (
onStart/onUpdate); all per-entity state lives in components (reload-ready) - Input mapping — named actions/axes over raw input; behaviors never touch GLFW key codes
- Hand-rolled physics — semi-implicit Euler integration, gravity, box/sphere collision (broadphase → narrowphase → impulse resolution), restitution + Coulomb friction, on the fixed step
- Prefabs — save an entity subtree to
.prefab, instantiate additively, revert instances to source - 3D model import — glTF/glb via tinygltf (parse-only, isolated); nodes → ECS hierarchy with quaternion transforms, PBR factors + base-color texture
- Quaternion transforms —
Transformrotations are quaternions (gimbal-free, native to glTF); the inspector edits Euler degrees
- Hand-rolled mixer over a thin device backend (miniaudio used only as the device layer + file decoder; voice mixing/pitch resampling is our own)
AudioSource(clip / volume / pitch / loop / playOnStart / spatial) andAudioListener(master gain) componentsAudioClipis aResourceManagerasset like Mesh/Texture — handle-based, cached, ref-counted, hot-reloadable- Distance attenuation for spatial sources relative to the active listener
- Collision-triggered sounds via a general collision-event system (see below)
- Pause freezes the mix; Stop silences all voices; drag-drop
.wav/.mp3/.flac/ .oggonto an entity in the editor
PhysicsWorldemitsCollisionEvent { a, b, point, normal, impulse }per contact each step- Dispatched to
Behavior::onCollisionon the involved entities — one primitive for landing/footstep sounds, destruction, particle spawning, gameplay triggers - Built-in
CollisionSfxbehavior plays an entity'sAudioSourceon impact
- Snapshot ring-buffer — a full-scene snapshot is captured every fixed step during Play (rolling ~10 s window)
- Timeline panel — scrub backward to restore and inspect any recorded frame, with a seconds-behind-live readout
- Frame stepping — step through history frame-by-frame, or advance the live sim one fixed step at a time; Resume Live to return to play
- Timeline bookmarks — tag a frame with a label and jump Previous/Next
- Live hot-patch — the inspector edits the running scene directly, so component data changes apply while playing with no restart
- Code hot reload — gameplay behaviors live in a
SuGarGameDLL; rebuild it while the engine runs and it auto-swaps (debounced file-watch, or F8 / "Reload Scripts"). Behaviors reconnect by name and component state is preserved - ECS query console —
<component> [where <field> <op> <value>](e.g.rigidbody where vel.y < 0); click a match to select it - Pluggable snapshot backend (
ISnapshotStorage) — the Timeline is decoupled from how frames are stored (JSON today; binary/delta later)
- Vulkan-based forward renderer
- Offscreen rendering with ImGui viewport integration
- Depth testing and proper render pass separation
- Multi-light system (ambient + diffuse + specular)
- Physically-inspired materials (metallic + roughness)
- Directional shadow mapping with PCF filtering
- Gamma correction for improved visual output
- Layered architecture —
Editor -> Engine -> Core, whereSuGarCoreis a Vulkan-free shared library (ECS, components, math, behaviors) and gameplay lives in aSuGarGameDLL that links only Core and is loaded at runtime. The same Core could back multiple games. - Fully authoritative Entity Component System (ECS)
- Components:
Transform(quaternion rotation),Mesh,Material,Hierarchy,Name,Script,RigidBody,Collider,PrefabInstance,AudioSource,AudioListener - Hierarchical transforms with parent-child relationships
- Deterministic draw list generation
- Handle-based
ResourceManager - Cached mesh + texture loading
- GPU resource lifetime management
- Hot reload (in-place resource updates)
- Cross-platform texture loading via stb_image (no Windows/WIC lock-in)
- Dockable editor layout (ImGui docking)
- Hierarchy panel (ECS-driven) with drag-and-drop reparenting (cycle-safe)
- Inspector panel (live component editing) with jitter-free quaternion rotation
editing (
EditorTransformCache) - Viewport panel (render-to-texture) with click-to-select scene picking (camera ray vs entity AABB) and translate/rotate/scale gizmos (ImGuizmo)
- Multi-select (Ctrl-click in hierarchy/viewport), duplicate (Ctrl+D), and delete (Del)
- Undo/redo command history (Ctrl+Z / Ctrl+Y) for transform edits, reparent, duplicate, delete, and component add/remove
- Component management — add/remove components + editable script behavior
- Prefab instance controls — Revert and Apply-to-Prefab
- Asset browser with color-coded thumbnail tiles + drag-and-drop
- Play Controls panel (runtime state)
- Filesystem-based asset registry
- Drag & drop:
.obj→ mesh,.png / .jpg / .jpeg→ texture - Live asset updates without restarting the engine
| Input | Action |
|---|---|
W A S D |
Move camera (FREE mode) |
Mouse |
Look around |
1 / 2 / 3 |
FREE / ORBIT / FOLLOW camera |
F5 / F9 |
Save / reload scene |
F6 |
Play / Stop |
F7 |
Pause / Resume |
F8 |
Hot-reload the game module (behaviors) |
Ctrl+Z / Ctrl+Y |
Undo / Redo |
Ctrl+D / Del |
Duplicate / Delete selected |
Ctrl+Click |
Add to selection (hierarchy / viewport) |
Esc |
Exit |
- Vulkan SDK
- CMake 3.21+
- Visual Studio 2022 (C++)
cmake -S . -B build
cmake --build build --config Debug --target SuGarEngine --parallel 1# Run from the project root so assets resolve correctly
build\Debug\SuGarEngine.exeEach subsystem has a quick headless confidence test. Run them (no window/Vulkan) before launching the editor:
$env:SUGAR_SELFTEST = "1"; build\Debug\SuGarEngine.exe; $env:SUGAR_SELFTEST = ""Prints a per-test PASS/FAIL table (with timings) for CoreBoundary, CommandHistory, EntityQuery, SnapshotStorage, Physics, SystemScheduler, Serializer, BehaviorRegistry, and RegistryGraph.
Full plan in ROADMAP.md. Summary:
- Phase 1–4 (done) — Vulkan setup, renderer (swapchain/depth/materials), ECS, editor, asset pipeline, hot reload, advanced lighting + shadows, optimization
- Phase 5 (done) — Runtime foundation (Play mode: snapshot/restore + update loop)
- Phase 6–9 (done) — behaviors + input mapping, hand-rolled physics, prefabs + glTF import, quaternion transforms, hand-rolled audio
- Phase 10 (done) — editor UX (10A picking + jitter-free rotation + reparenting; 10B gizmos + undo/redo + duplicate; 10C multi-select + delete + component management + prefab Revert/Apply + thumbnails). M1 / Track A complete.
- Track B (in progress) — the wedge: 11A editor command infrastructure;
11B time-travel scrubbing + frame stepping + ECS query console; 11C snapshot
backend abstraction + timeline bookmarks done. Phase 12 code hot reload:
12A/12B/12C done — layered
Editor -> Engine -> Core(Vulkan-freeSuGarCoreshared lib) with gameplay behaviors in aSuGarGameDLL that links only Core, loaded at runtime and hot-reloaded live when recompiled. Phase 13A done — opinionated scheduling: the gameplay pipeline is now declaredSystems with read/write sets behind a deterministicSystemScheduler(independence analysis in place; parallel execution, incremental rebuilds, and architecture lints later). Also later: reload only affected systems, in-place state restore, binary/delta snapshots, query growth - Track C — graphics, cross-platform, packaging, ecosystem
SuGar Engine is being developed as a final-year project (FYP) and an open-source engine demonstrating low-level graphics (Vulkan), engine architecture (ECS, resource systems), real-time rendering, and — its core differentiator — iteration speed and runtime debuggability.
Apache 2.0 License