A complete C program
The public API makes the world, component registration, system query, and frame progression visible in one source file.
#include <siecs.h>
ECS_COMPONENT(Position, {
float x;
float y;
});
ECS_COMPONENT(Velocity, {
float x;
float y;
});
static void Move(ecs_iter_t *it) {
Position *positions = ecs_field(it, 0);
const Velocity *velocities = ecs_field(it, 1);
for (uint32_t i = 0; i < it->count; i++) {
positions[i].x += velocities[i].x;
positions[i].y += velocities[i].y;
}
}
int main(void) {
ecs_init();
ECS_COMPONENT_REGISTER(Position);
ECS_COMPONENT_REGISTER(Velocity);
ecs_system({
.query.terms = { ecs_inout(Position), ecs_in(Velocity) },
.callback = Move,
.phase = EcsOnUpdate,
});
ecs_entity_t player = ecs_new();
ecs_set(player, Position, { 0, 0 });
ecs_set(player, Velocity, { 1, 1 });
ecs_progress();
ecs_fini();
return 0;
} Register the data your systems use
ECS_COMPONENT describes a C type and its lifecycle metadata.
Registering it with the world gives the type a runtime component id that
can be used by entities, queries, observers, and tools.
Tags use the same component model when an entity needs a state marker such
as Visible, Player, or Selected.
Describe access with query terms
Query terms express both matching and intent. The example writes
Position, reads Velocity, requires
Visible, and excludes Disabled.
ecs_query_id_t visible = ecs_query({
.terms = {
ecs_inout(Position),
ecs_in(Velocity),
ecs_filter(Visible),
ecs_not(Disabled),
},
}); Persistent queries keep their compatible tables available. Iterators then expose the requested component columns as batches for the callback.
Schedule the work in the frame
A system combines the query with a callback and a phase. Calling
ecs_progress() runs enabled systems in phase order, while
individual phases and systems can also be run directly by tools or tests.
Resources provide unique world state, observers respond to events, and modules package related registrations behind one import.
Integrate one header and one source file
Copy siecs.h and siecs.c from the standalone
distribution, include the public header, and compile them with the
application.
cc -std=c23 -I. main.c siecs.c -pthread -o ecs_example Continue with the C quick start for Bake integration and the API reference for every public symbol.