A complete C++ program
The API keeps component data, world state, and system access close to the code that uses them.
#include <siecs.h>
struct Position { float x, y; };
struct Velocity { float x, y; };
struct Time { float dt; };
int main() {
ecs::init();
ecs::set_resource(Time{ .dt = 1.0f / 60.0f });
ecs::entity::create("player").set(
Position{ .x = 0.0f, .y = 0.0f },
Velocity{ .x = 1.0f, .y = 1.0f }
);
ecs::system("Move")
.phase(EcsOnUpdate)
.each([](
ecs::res<const Time> time,
Position &position,
const Velocity &velocity
) {
position.x += velocity.x * time->dt;
position.y += velocity.y * time->dt;
});
ecs::progress();
ecs::fini();
} Use ordinary C++ types
Components are regular structs. SIECS associates each type with the active world when it first appears in a typed operation, then stores its values in the component data model.
Multi-component set, add, and
remove calls express a final entity shape in one operation.
This keeps entity construction concise and makes composition changes easy
to read.
Let the callback describe access
A mutable reference requests writable data. A const reference requests read-only data. Resource parameters provide unique world state without becoming entity query terms.
ecs::system("Move").each([](
ecs::res<const Time> time,
Position &position,
const Velocity &velocity
) {
position.x += velocity.x * time->dt;
}); Query matching and batch iteration remain part of the SIECS runtime, while the C++ layer keeps the access contract visible in the function signature.
Compose the world with typed APIs
Systems, resources, observers, and modules share the same world as entity data. Modules can register related components, systems, and observers behind one typed import and can be enabled or disabled as a unit.
Reflection metadata can describe component fields for JSON serialization and live editor tooling through the optional REST explorer.
Model relationships directly
Relations give entities named targets. Use them for scene hierarchy, ownership, attachments, or reusable prototypes with shared component data.
auto parent = ecs::entity::create("ship");
auto child = ecs::entity::create("turret").child_of(parent);
auto prototype = ecs::entity::create("Enemy");
prototype.set(Health{ 100 }).abstract();
auto instance = ecs::entity::create("drone").is_a(prototype); Relation state remains part of the world data and can be matched by queries, observed, reflected, and inspected by tools.
Link the C runtime with your C++ application
Include siecs.h, compile the SIECS source as C, and link the
object with the C++ application.
cc -std=c23 -I. -c siecs.c -o siecs.o
c++ -std=c++23 -I. main.cpp siecs.o -pthread -o ecs_example Continue with the C++ quick start and API reference for the complete set of typed operations.