Architecture
The pieces
The engine is a static library. The editor and the runtime are two programs that link it.
Why the editor is a separate program
An exported game must contain no editor code and no debug tools. With two programs that is true by construction: the runtime never links the editor, Dear ImGui, the gizmos or the command server.
Play mode still runs inside the editor process, using the same engine library the runtime uses, so a game behaves the same in both.
Inside the engine
Shaders are GLSL in Cairn/Shaders, compiled to SPIR-V at build time and embedded in the library.
A frame
- Input is settled, so "was pressed" is true for exactly one frame.
- Scripts'
OnUpdaterun. - Fixed steps run, 60 per second of game time: scripts'
OnFixedUpdate, then physics, then contact callbacks. - Animation, audio and particles update.
- The scene is drawn: shadow maps, a depth prepass, ambient occlusion, the lit pass, the sky, particles, then post-processing and the UI.
The scene is drawn into a texture, never straight to the window. The window, the editor's viewport, screenshots and tests all read that texture.
One way to change a scene
In the editor, every change to a scene goes through an EditorCommand. That is the only way a change becomes undoable, and it is the same layer the agent commands call. A panel and an agent cannot do different things.
Assets
Every asset has an ID stored in a .meta file beside it. Components and files refer to assets by ID, never by path. The asset manager loads meshes, materials and textures on first use and keeps them.
Files are read through one file system layer, which also reads from a mounted pack. That is why the same code runs a project folder in the editor and a packed game.
Dependencies
All are fetched by CMake at pinned versions. All have permissive licences.
The built-in font is Roboto (Apache 2.0). MoltenVK (Apache 2.0) is the Vulkan driver on macOS, and is bundled into an exported .app.