Skip to content

Latest commit

 

History

49 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Concord Flash

English | 简体中文

MPL 2.0 C++23 Windows and Vulkan CMake and Ninja

Concord Flash

Concord Flash is the second generation of the Concord engine: a native Forward+ Vulkan 3D engine for Windows. It keeps the first generation's user-facing syntax, but rewrites the render backend, deepens the ECS model, and deliberately cuts complexity that never earned its keep.

Status: the engine foundation is verified. Windowing, the Vulkan frame lifecycle, the ECS core, and the two-DLL architecture are operational. When staged SPIR-V artifacts are built, the procedural Box depth/forward path uses a per-frame UBO for camera, ambient, and bounded directional/point/spot lights, plus a fixed-grid tile light-list compute pass. Directional shadow mapping and an internal KHR ray-generation pipeline are also available: each frame slot owns isolated device-address geometry, BLAS/TLAS, SBT, and output resources. Devices or swapchains without the required capabilities fall back to the Forward+ raster path automatically. Imported model data, GPU skinning, and skinned shadow draws are available; CPU pose blending, state-machine transitions, joint masks, and layered override/additive animation live in engine/animation (see docs/动画混合与状态机.md). APIs, file formats, and runtime behavior may change without any compatibility guarantee.

Custom Vulkan passes

<Concord/CRender.h> exposes a small, Vulkan-header-free pass ABI for code generated by ConcordScript or hand-written C++. Register a callback with Concord::RegisterVulkanPass; Render.dll invokes it during command recording at BeforeScene or AfterScene, in ascending order. The callback receives VulkanPassContext, including opaque device, command-buffer, swapchain image, descriptor-set, and optional acceleration-structure handles. Convert handles with Concord::VulkanHandle<VkType>(value) in a translation unit that includes the Vulkan SDK. Callbacks may record commands but must not submit or end the engine-owned command buffer. Initialize and Shutdown are lifecycle-only: they report VulkanPassInvalidImageIndex and zero per-frame attachment, descriptor, and acceleration-structure handles.

ConcordScript shader options

The generated ConcordScriptShaders.cmake helper can compile inline and external shader sidecars with per-shader DEFINES, INCLUDE_DIRS, and OPTIONS. Each item is passed as a separate compiler argument, so paths with spaces remain valid and the output name changes when options change. The same configuration is retained in the generated JSON manifest for reflection and pipeline tooling.

Why a second generation

The first generation of Concord was built on bgfx, trading a cross-platform rendering abstraction for portability across Windows, macOS, and Linux. That abstraction itself created three problems the second generation set out to solve:

  1. The cost of indirection. bgfx's cross-backend design meant any Vulkan-specific capability (dynamic rendering, explicit frame synchronization, precise memory layout) had to first ask "does bgfx support this?" instead of just being written. The second generation programs against Vulkan directly, trading cross-platform reach the first generation never used for full control over the render pipeline.
  2. Modules split too finely. The first generation split the engine into 30+ C*.h facade headers and several independent DLLs (CEngine.dll/CAudio.dll/CGUI.dll/CSystem.dll/CTime.dll), many of which had a facade with no real content this early in the project. The second generation only builds a facade header once a module actually has code, and splits DLLs along real coupling boundaries (runtime vs. render backend) rather than one per module.
  3. Scene and ECS were two parallel states. The first generation's Scene::Spawn produced node objects that owned their own data, while Ecs::World was a completely separate component database — neither knew the other existed. Using ECS meant giving up the node API, and vice versa.

What the second generation fixes, and what's better

A Scene is an ECS World

This is the central improvement. Scene::Spawn<T> and Scene::Query<...> now share the same component storage — the object-oriented spawn syntax is just a thin shell over the data-oriented query:

// Object-oriented view: spawn an archetype, then chain a custom component onto it.
scene.Spawn<Object::Box>({.material = {.albedo = COLOR_RGB(224, 64, 64)}})
     .Add<Spin>(Spin{.degreesPerSecond = 60.0f});

// Data-oriented view: compose an entity component by component, no archetype at all.
scene.CreateEntity()
     .Add<Transform>(Transform{.position = {4.0f, 1.5f, 1.0f}})
     .Add<MeshRenderer>(MeshRenderer{});

// One query sees both — because they were always the same data.
scene.Query<Transform, MeshRenderer>([](Entity, Transform& t, MeshRenderer& m) { ... });

See docs/场景与ECS.md for the full model (Chinese; English translation pending).

Simpler syntax — every cut is pure boilerplate

First generation Concord Flash
scene.Spawn<Object::Box>(Object::BoxDesc{...}) repeats the type name scene.Spawn<Object::Box>({...}), T::Desc is deduced
.material = {.surface = {.albedo = ...}} nests two levels .material = {.albedo = ...}, flattened to one
30+ facade headers, some for empty modules Facade headers only for modules that actually exist, added as needed
Concord::Sleep(20000) to keep the window alive game.Run(), a real main loop
Every primitive has its own stateful Desc + Node pair Node becomes a stateless "recipe"; all state lives in the ECS

Native Vulkan backend, two DLLs instead of many

The engine splits into two DLLs: ConcordFlashGameEngineRuntime.dll (lifecycle, ECS, scene, window) and ConcordFlashGameEngineRender.dll (the Vulkan backend). Runtime obtains a render backend instance through a self-registering factory and never references Vulkan symbols directly — keeping the dependency between the two DLLs one-directional, and letting the render backend be replaced or upgraded independently without recompiling the whole runtime. See docs/渲染架构.md for details.

Syntax example

#include <Concord/CApplication.h>
#include <Concord/CCamera.h>
#include <Concord/CLight.h>
#include <Concord/CObject.h>
#include <Concord/CScene.h>

int main()
{
    Concord::Game game;
    Concord::Window window({.title = "My Game", .resolution = {1280, 720}});
    game.AttachWindow(window);

    Concord::Scene scene;
    scene.Spawn<Concord::Object::Camera>({.position = {0.0f, 2.0f, -5.0f}});
    scene.Spawn<Concord::Object::SunLight>({.elevationDegrees = 45.0f});
    scene.Spawn<Concord::Object::Box>({.transform = {.position = {0.0f, 1.0f, 0.0f}}});

    game.LoadScene(scene);
    game.Run();
}

Documentation

Full syntax and architecture documentation lives under docs/ (currently written in Chinese; English translations are planned):

Engineering standards (naming, file layout, the per-file line limit, etc.) live in AGENTS.md at the repository root.

License

Concord Flash is licensed under the Mozilla Public License 2.0: modifying an engine source file requires publishing that file's changes, but a game built with the engine is entirely unaffected and can be distributed closed-source. Third-party dependencies keep their own original licenses; see the subdirectories under src/3rd/.

About

Concord Flash is developed by Datatype Team (datatype.me), a full-stack development team founded by Simalth Wang, the original creator of Concord. The previous maintainer, Lattice Games, no longer updates the first generation of the engine; all active development now happens here, under Datatype Team.


Datatype Team
Developed by Datatype Team (datatype.me)

About

Concord Flash — a native Forward+ Vulkan 3D game engine for Windows, with a deepened ECS core and deliberately unfussy syntax.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages